DIFFERENZE SQL

Adesso ho deciso di andare da un bravo psichiatra per farmi diagnosticare qualche problema a livello psichico di quelli complicati.

Allora, ho passato la mattinata per far digerire alla mia procedura ( o classe ) per l’utilizzo di più database anche sqlite;
E ora provo a passare in rassegna tutte le differenze tra MYSQL, POSTGRE, SQLITE che fino ad ora ho trovato.

Sicuro che non saranno tutte ma per lo meno ci provo.

Creazione di tabella da SELECT
Mysql : CREATE TABLE nometabella SELECT * FROM altratabella WHERE campo = ‘CONDIZIONE’
Postgre e Sqlite occorre aggiungere ‘AS’ quindi CREATE TABLE nometabella AS SELECT * FROM altratabella WHERE campo = ‘CONDIZIONE’
La nuova tabella avrà la struttura della vecchia.

Creazione di tabella temporanea da SELECT
Mysql : CREATE TEMPORARY TABLE nometabella SELECT * FROM altratabella WHERE campo = ‘CONDIZIONE’
Sqlite : CREATE TEMPORARY TABLE nometabella AS SELECT * FROM altratabella WHERE campo = ‘CONDIZIONE’ ( vedi clausola ‘AS’ )
Postgre CREATE OR REPLACE TEMP VIEW nometabella AS SELECT * FROM altratabella WHERE campo = ‘CONDIZIONE’ ( vedi clausola ‘AS’ )
La nuova tabella avrà la struttura della vecchia. Quando l’utente si disconnette da database, quindi passato il tempo di IDLE la tabella viene automaticamente eliminata. In Sqlite quando il file del db viene chiuso

Concatenare testo
Mysql e Postgre : SELECT campo1, campo2, concat(campo3,’ ‘,campo4,’ ', campo5) AS campocalcolato FROM … etc etc
Sqlite : si utilizza il doppio pipe ‘||’ quindi : SELECT campo1, campo2, (campo3 || ’ ’ || campo4 || ’ ’ || campo5) as campocalcolato FROM … etc etc

Condizioni nella query
Mysql e Postgre :

SELECT CASE WHEN righe.causale = '001' THEN 1 ELSE CASE WHEN righe.causale = '005' THEN 3 ELSE 2 END END as ordina, righe.causale FROM righe ORDER by ordina
Con Sqlite dovrebbe essere la stessa cosa;

Ordinare campi di testo contenente numeri :
Mysql - Sqlite utilizzare Cast() ad esempio : SELECT * FROM tabella ORDER by CAST(campo as decimal(10,3))
Postgre : Sembra non ci sia la possibilità di farlo se non creando un paio di funzioni :

CREATE FUNCTION f_ordnattxt(valore text) RETURNS text
    LANGUAGE plpgsql IMMUTABLE
    AS $$
DECLARE
   testov TEXT;
BEGIN
   testov := SUBSTRING(valore FROM '[^0-9]+');
   RETURN testov;
END;
$$;

CREATE FUNCTION f_ordnatnum(valore text) RETURNS integer
    LANGUAGE plpgsql IMMUTABLE
    AS $$
DECLARE
   testov TEXT;
   numero INT;
BEGIN
   testov := SUBSTRING(valore FROM '[0-9]+');
   numero := coalesce(testov,'0')::int4;
   RETURN numero;
END;
$$;

Utilizzo : SELECT campo1, campo2, campo3 FROM tabella ORDER BY f_ordnattxt(campo1),f_ordnatnum(campo1)
Dove campo1 è una campo testo che contiene anche numeri

E vogliamo parlare dell’uso delle date nei vari dialetti SQL?

Ti accontento subito Nedi;
Mysql, Sqlite, Postgre la data sempre nel formato UNIX ‘aaaa-mm-gg’
quindi posso usare SELECT * from test WHERE data = ‘2018-01-10’

Con Mssql invece, si vede alla microsoft si fanno le pippe mentali ! le date sono salvate sempre con ore, minuti e secondi …
Ovviamente per deliziare i palati più sopraffini …
quindi per un semplice SELECT * from test WHERE data = ‘2018-01-10’ occorre utilizzare un trucco
SELECT * from test WHERE data BETWEEN ‘2018-01-10’ AND ‘2018-01-10 23:59:59’

Confronto di date con Sqlite !!! IMPORTANTE
A differenza di Postgre e Mysql, con Sqlite importante utilizzare la funzione date() per il confronto appunto delle date;
Alcuni esempi :

SELECT campo1, campo2, campo3, campodata FROM tabella WHERE campodata = '2018-01-01';
deve essere scritto cos :

SELECT campo1, campo2, campo3, campodata FROM tabella WHERE date(campodata) = date('2018-01-01')
altrimenti la query non produce alcun risultato.

SELECT campo1, campo2, campo3, campodata FROM tabella WHERE date(campodata) >= date('2018-01-01') SELECT campo1, campo2, campo3, campodata FROM tabella WHERE date(campodata) <= date('2018-01-01') SELECT campo1, campo2, campo3, campodata FROM tabella WHERE date(campodata) > date('2018-01-01') SELECT campo1, campo2, campo3, campodata FROM tabella WHERE date(campodata) < date('2018-01-01') SELECT campo1, campo2, campo3, campodata FROM tabella WHERE date(campodata) BETWEEN date('2018-01-01') AND date('2018-12-31')

Ci ho sbattuto la testa per parecchi giorni !

Questo se hai registrato le date come SQLDateTime

se hai registrato come sqlDate non c’ problema

I campi sono tutti date e non datetime o timestamp
per scrivere i campi di tipo data o aggiornarli utilizzo rispettivamente

row.datecolumn(“data”) = new date()
oppure rsitem.field(“data”).datevalue = new date()

In Una query di questo tipo :
SELECT campo1, campo2, campo3, campodata FROM tabella WHERE campodata) <= ‘2018-01-01’
vengono mostrati tutti i record meno quelli con campodata = ‘2018-01-01’
Ho fatto diverse prove. Infatti non riuscivo a capire perch la procedura di fatturazione non reperiva tutti i documenti.

L’unica soluzione che ho trovato appunto era l’utilizzo della funzione date() che lavora come deve.

In SQLite non esiste il tipo data. Viene trasformato in stringa.
.dateValue=new date() va a scrivere un valore sqldatetime

Giusto per orientarsi, non che usare date() sia sbagliato, anzi copri tutti i casi sia sqldate che sqldatetime