2009-12-04 16 views
6

Me gustaría poder analizar una declaración SQL SELECT arbitraria y recuperar las diversas partes componentes (columnas, relaciones, condiciones de JOIN, condiciones WHERE, columnas ORDER BY), idealmente usando Delphi. Una búsqueda rápida en Google muestra varios productos gratuitos diferentes, pero no está claro si están completos y/o en desarrollo activo.Biblioteca para analizar sentencias SQL

Mi necesidad inmediata de simplemente extraer la lista de relaciones utilizadas en una serie de definiciones VIEW para garantizar que existan vistas o tablas requeridas antes de intentar CREAR la vista. Entonces, por ejemplo, para la instrucción:

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

Necesito recuperar los valores "Personas" y "Pedidos". (Obviamente, este es un ejemplo simple. Quiero poder manejar casos más complejos donde, por ejemplo, la palabra "FROM" podría aparecer en la lista de columnas como parte de una expresión).

Estoy tratando de proporcionar este servicio en una base de datos que permite el uso de funciones STDCALL exportadas de DLL, por lo que idealmente cualquier biblioteca candidato sería exigible a partir de Delphi o C

+0

puede ser posible dime qué motor SQL tu consumo? A menos que me lo haya perdido. – Reallyethical

+0

Sé feliz, pero no te ayudará. Estoy usando R: Base. –

Respuesta

6

Tome un vistazo a Gold Parser. Tiene una versión de Delphi disponible, y gramática SQL en la página de descarga.

+0

Gracias. Esto no apareció en mi búsqueda de Google, presumiblemente porque la parte de SQL está en una página separada del analizador y Delphi menciona. –

+0

Sí, es algo oscuro. Buen sistema, sin embargo. –

0

programas de análisis de SQL son complicadas.

Qué piensa de este enfoque:

  1. iniciar la transacción.
  2. Envía el comando CREATE VIEW al servidor.
  3. detecta el error (cualquier controlador de base de datos decente debería ser capaz de hacer esto).
  4. si hubo un error, analiza el mensaje de error y muestra las tablas faltantes al cliente.
  5. rollback

ver este ejemplo (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 este (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í, eso es lo que estoy haciendo actualmente. Sin embargo, si puedo detectar problemas en el momento en que creo mi archivo de definición de estructura desde la base de datos original, puedo resolver algunos de ellos inmediatamente (esencialmente, estoy intentando realizar un cierre transitivo en todas las definiciones de vista en la base de datos, el DBMS desafortunadamente no funciona cuando se proporciona una lista de vistas). –

+0

Ha. Esto es definitivamente un truco, pero divertido. Lamentablemente, el cartel no dice que incluso tenía un servidor de base de datos en funcionamiento para trabajar.Antes de intentar algo como esto, ¡asegúrate de investigar posibles vectores de amenaza! – Dolph

+0

Me corrigen por no tener una base de datos. Publicaste mientras escribía mi respuesta, Larry. :) – Dolph

0

Puede usar Delphi con ADODB.

Use un TADOQuery para comprobar si su consulta es buena o no sin abrir realmente el conjunto de registros. Tu también puedes recuperar los nombres de los campos de la consulta.

Coloque una TDOConnection en un formulario. Caída de un TMemo y una TButton y probar este código:

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

Mi DBMS no es accesible usando ADO. –

Cuestiones relacionadas