2009-12-04 20 views
6

Vorrei poter analizzare un'istruzione SQL SELECT arbitraria e recuperare le varie parti componenti (colonne, relazioni, condizioni JOIN, condizioni WHERE, colonne ORDER BY), idealmente utilizzando Delphi. Una rapida ricerca su google mostra diversi prodotti freeware, ma non è chiaro se sono completi e/o in fase di sviluppo attivo.Libreria per analizzare le istruzioni SQL

Il mio bisogno immediato di estrarre solo l'elenco delle relazioni utilizzate in una serie di definizioni VIEW per garantire che le viste o le tabelle richieste esistano prima di provare a CREARE la vista. Così, per esempio, per l'istruzione:

SELECT PersonID, LastName, OrderID 
FROM People P INNER JOIN Orders O ON P.PersonID = O.PersonID 

ho bisogno di tornare ai valori "Persone" e "Ordini". (Ovviamente, questo è un semplice esempio: voglio essere in grado di gestire casi più complessi in cui, ad esempio, la parola "FROM" potrebbe apparire nell'elenco delle colonne come parte di un'espressione).

Sto cercando di fornire questo servizio in un database che permette l'uso di funzioni stdcall esportate da DLL, così idealmente qualsiasi libreria candidato sarebbe richiamabile da Delphi o C.

+0

fai a dirmi quale motore di SQL vostro usando? A meno che non mi sia mancato. – Reallyethical

+0

Sii felice, ma non ti aiuterà. Sto usando R: Base. –

risposta

6

Date un'occhiata a Gold Parser. Ha una versione di Delphi a disposizione, e grammatica SQL nella pagina di download.

+0

Grazie. Questo non si è verificato nella mia ricerca su google, presumibilmente perché la parte SQL si trova su una pagina separata dal parser e Delphi menziona. –

+0

Sì, è un po 'oscuro. Buon sistema, però. –

0

parser SQL sono complicate.

ne pensi di questo approccio:

  1. iniziare la transazione.
  2. Inviare il comando CREATE VIEW al server.
  3. rilevare l'errore (qualsiasi driver di database decente dovrebbe essere in grado di farlo).
  4. in caso di errore, analizzare il messaggio di errore e mostrare le tabelle mancanti al client.
  5. rollback

vedere questo esempio (PostgreSQL):

=> begin; 
BEGIN 
=> create view testview as select foo,bar from a join b on a.x=b.y; 
ERROR: relation "a" does not exist 
LINE 1: create view testview as select foo,bar from a join b on a.x=... 
                ^
=> rollback; 
ROLLBACK 

o questa (Oracle):

SQL> create view testview as select foo,bar from a join b on a.x=b.y; 
create view testview as select foo,bar from a join b on a.x=b.y 
                * 
ERROR at line 1: 
ORA-00942: table or view does not exist 

SQL> rollback; 

Rollback complete. 
+0

Sì, è quello che sto facendo attualmente. Se riesco a rilevare problemi nel momento in cui creo il mio file di definizione della struttura dal database originale, tuttavia, posso risolverne alcuni immediatamente (in sostanza, sto cercando di eseguire una chiusura transitiva su tutte le definizioni di vista nel database, che il DBMS purtroppo non funziona quando si fornisce un elenco di viste). –

+0

Ha. Questo è sicuramente un trucco, ma divertente. Sfortunatamente il poster non ha detto che aveva anche un server di database funzionante con cui lavorare.Prima di provare qualcosa di simile, assicurati di indagare su potenziali vettori di minacce! – Dolph

+0

Sono stato corretto non avendo un DB. Hai postato mentre stavo scrivendo la mia risposta, Larry. :) – Dolph

0

È possibile utilizzare Delphi con ADODB.

Utilizzare un TADOQuery per verificare se la query è buona o meno senza aprire realmente il recordset. Puoi anche recuperare i nomi dei campi della query.

Eliminare un TADOConnection su un modulo. Eliminare una TMemo e un TButton e provare questo codice:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    lADOQuery : TADOQuery; 
    lFieldNames : TStrings; 
begin 
    lADOQuery := TADOQuery.Create(nil); 
    try 
    lADOQuery.Connection := ADOConnection1; 
    lADOQuery.SQL.Text := Memo1.Text; 
    lFieldNames := TStringList.create; 
    try 
     lADOQuery.GetFieldNames(lFieldNames); 

     showmessage(lFieldNames.Text); // Show fieldNames of the query 

     // To show that the dataset is not actually opened try this : 
     // Throws an exception (Dataset closed) 
     //showmessage(inttostr( lADOQuery.RecordCount)); 
    except 
     On e: Exception do 
     ShowMessage('Invalid query'); 
    end; 
    lFieldNames.free; 
    finally 
    lADOQuery.free; 
    End; 
end; 
+0

Il mio DBMS non è accessibile tramite ADO. –

Problemi correlati