Ciao a tutti
volevo sottoporre il problema della scrittura di una Query legando i costrutti TOP e ORDER BY in un processo di DataIntegration in cui gli attori sono DBMS eterogenei, il problema consiste nell'interpretazione semantica dell'ottimizzatore che su alcuni DBMS decide se fare prima la TOP o prima l'ORDER BY; in particolare le QUERY
SELECT TOP 10 A, B, C
FROM TABLEA
ORDER BY A
SELECT A, B, C
FROM TABLEA
WHERE ROWNUM < 10
ORDER BY A
SELECT A, B, C
FROM TABLEA
ORDER BY A
FETCH FIRST 10 ROWS ONLY
Rispettivamente su SQLServer e Oracle e DB2/AS400 hanno comportamenti diversi, come tutti saprete SQL prima ordina l'intera TABLEA poi restituisce i primi 10 mentre Oracle calcola i primi 10 e poi li ordina, questo sistema produce due ResultSet completamente diversi.
So che Oracle dispone di un particolare costrutto PL/SQL per ovviare al problema:
SELECT A, B, C
FROM
(SELECT A, B, C
FROM TABLEA
ORDER BY A)
WHERE ROWNUM < 10
oppure
SELECT A, B, C
FROM (
SELECT row_number() OVER (ORDER BY A DESC) R, A, B, C
FROM TABLEA) X
WHERE X.R < 10;
Ma quello che voglio io e' un MiddleTier che calcoli dinamicamente la Query su entrambi i sistemi in base ad un file di configurazione, quindi quello che a mio avviso e' il sistema migliore per risolvere il problema e' con l'ausilio del mio amatissimo DataAdapter di cui postero' in fututo.
Secondo me la TOP e' troppo poco standard per affidarmi a questo costrutto, quindi, per questo motivo credo la cosa migliore sia utilizzare il DataAdapter in cui la SelectCommand non specifica la clausola di TOP (questo rende il nostro SQL molto piu' standard) e utilizzando
System.Data.OleDb.OleDbDataAdapter xxx = new System.Data.OleDb.OleDbDataAdapter();
xxx.Fill(dsTest, 0, iTop, "TableName");
Otteniamo che per qualsiasi DBMS l'ORDER BY avviene sull'intero ResultSet che risponde alla clausola WHERE, naturalmente questo ci porta i vantaggi sopra elencati e anche alcuni svantaggi (appesantiamo il DBMS), la coperta e' sempre corta, ma credo che questo sia un prezzo che possiamo pagare; ricordo inoltre che il DataAdapter e' disconnesso e anche che i dati che passano tra DB e MiddleTier sono solo quelli compresi tra startRecord e maxRecord di DataAdapter.Fill
Nel prossimo futuro postero' perche' non sono amico dei DataReader (se non in casi di performance speciali).
In futuro postero' anche perche' aborro alle EnterpriseLibrary (file configurazione mostruoso) e di come un mio collega mi parla delle Factory del VS 2005 che mi appresto ad installare.
Ciao a tutti
Allino