Cinque differenze tra PL-SQL e T-SQL

Riprendo il tema della lezione precedente sulle differenze tra la programmazione SQL su ambiente Sql Server e su ambiente Oracle. Andiamo a scoprire altre cinque fondamentali differenze tra il PL-SQL e il T-SQL.

Confronti tra un campo varchar e una stringa contenente spazi in PL-SQL e T-SQL

Riprendiamo lo stesso script utilizzato nello scorso articolo per creare delle tabelle di test. Facciamo attenzione all’utilizzo di varchar su SQL Server e varchar2 su Oracle.

Su Sql server avremo:

CREATE TABLE TabellaTest (
 campo1 VARCHAR(50) NULL,
 campo2 DECIMAL(18,2) NULL);
INSERT INTO TabellaTest 
VALUES('test', 35.23);

Mentre su Oracle scriveremo:

CREATE TABLE TabellaTest (
 campo1 VARCHAR2(50) NULL,
 campo2 DECIMAL(18,2) NULL);
INSERT INTO TabellaTest(
  campo1, campo2)  
VALUES('test', 35.23);

Come sono valutati gli spazi a destra e a sinistra quando usiamo colonne varchar all’interno di un filtro? Su Sql Server gli eventuali spazi a destra non saranno considerati. Ad esempio la query seguente avrà comunque come output l’unico record presente nella tabella, nonostante la presenza degli spazi dopo il carattere t.

SELECT *
FROM   TabellaTest
WHERE  campo1 = 'test    ';

Al contrario, su Oracle tali spazi vengono presi in considerazione. Di conseguenza il filtro precedente risulterà falso e quindi la query restituirà zero righe.

L’esempio può sembrare artificioso, in realtà non è raro trovarsi in una situazione del genere quando confrontiamo le colonne con variabili valorizzate precedentemente.

Ricordiamo infine che gli spazi a sinistra sono valutati su entrambi gli ambienti, inoltre gli spazi a destra saranno sempre “salvati” durante le operazioni di inserimento.

Gestione righe non committate

Nello scorso articolo avevamo visto che by default le operazioni DML su Oracle devono essere seguite da un commit per risultare persistenti su un database (ricordo di fare attenzione ai commit impliciti derivanti ad esempio da operazioni DDL). Su Sql Server, invece, il commit è necessario solo se viene dichiarata esplicitamente l’apertura di una transazione.

Ma cosa succede se proviamo a interrogare, prima del commit, una tabella modificata in un’altra sessione?
Su Oracle vedremmo la tabella con i valori originali, come se l’operazione non fosse stato ancora eseguita.
Al contrario, su Sql Server la tabella risulta lockata: tutte le query su di essa resteranno “in running” finché la transazione non verrà chiusa tramite un commit o un rollback.

Per forzare l’esecuzione di una query su tabelle lockate occorre inserire l’hint WITH (NOLOCK) nella clausola FROM, subito dopo il nome della tabella. In questo caso, a differenza di Oracle, vediamo i dati come se il commit fosse già stato eseguito. L’uso di NOLOCK non è comunque consigliato in ambiente di produzione.

Divisione tra interi con T-SQL e PL-SQL

Creiamo in entrambi gli ambienti una nuova tabella con un campo di tipo int e inseriamo due record con i valori 1 e 2.

CREATE TABLE TestInteri(campo1 INT);
INSERT INTO TestInteri(campo1)
VALUES (1);
INSERT INTO TestInteri(campo1)
VALUES (2);

La query seguente restituirà due risultati differenti:

SELECT AVG(campo1)
FROM   TestInteri;

Su Oracle l’output è dato dal numero decimale 1.5, corrispondente alla media dei valori 1 e 2 trattati anch’essi come decimali.
Al contrario, su Sql Server verrà restituito l’intero 1, a meno di convertire esplicitamente (o implicitamente tramite una moltiplicazione per 1.0) i valori della colonna.

Più in generale, tali considerazioni valgono anche per la divisione tra numeri interi: a meno di cast, su Sql Server il risultato sarà sempre un intero (non arrotondato), mentre su Oracle otterremo comunque il decimale “esatto”.

Concatenazione tra stringhe e interi

In ambiente Oracle se concateniamo una stringa e un intero tramite l’operatore ||, l’intero verrà convertito implicitamente in stringa. Ad esempio l’output di questa query sarà la stringa a1

SELECT 'a' || 1
FROM   DUAL;

Al contrario, in ambiente Sql Server, l’operatore di concatenazione tra stringhe “+” tenterà  sempre di convertire il campo varchar in intero, nel caso almeno una delle due colone sia di tipo Int. Al netto di rimuovere la tabella Dual, la query precedente restituirà dunque un errore di conversione.

Concatenazione con null

Analizziamo ora un’altra importante differenza tra PL-SQL e T-SQL.

By default, su Sql Server la concatenazione con l’operatore “+” tra varie stringhe di cui anche una sola è null, ha come risultato null. Viene seguita la logica per cui il risultante della concatenazione tra una stringa determinata e una stringa sconosciuta risulta essere una stringa sconosciuta. Perciò risulta fondamentale trattare questi casi utilizzando la funzione coalesce, oppure sostituendo l’operatore “+”con la funzione Concat.

Su Oracle la situazione cambia: il null lavora come elemento neutro della concatenazione, di conseguenza non impatta il valore degli altri campi sia se utilizzato con la funzione Concat, sia se utilizzato con l’operatore “||”.

Continua a imparare

Torna in alto
Torna su