2011-06-09 14 views
10

Estoy buscando un buen analizador de SQL en Delphi (2010) para SQL Server. Necesito tal cosa para analizar una consulta y extraer: seleccionar lista, donde y ordenar por cláusulas. No importa si se trata de una solución comercial o de código abierto. También puede ser un archivo DLL (escrito en cualquier idioma, por supuesto) pero prefiero un componente VCL sobre un archivo DLL.Analizador de SQL en Delphi para SQL Server

+0

No es exactamente la misma pregunta, pero podría valer la pena un vistazo : ttp: //stackoverflow.com/questions/615608/need-in-sql-parser-on-delphi –

+0

Sí, pero es para Firebird, no para el servidor sql. Y hay diferencias entre ellos. –

+1

Con cte's, consultas anidadas, insertar/soltar/actualizar/alterar/etc declaraciones, este es un código no trivial. Realmente, la única forma segura de analizar una consulta de servidor SQL es con el servidor sql. –

Respuesta

10

Rafael Delphi viene con un intérprete de SQL se encuentra en la unidad de DBCommon

comprobar estas funciones

function NextSQLToken(var p: PAnsiChar; out Token: AnsiString; CurSection: TSQLToken): TSQLToken; overload; 
function NextSQLToken(var p: PWideChar; out Token: WideString; CurSection: TSQLToken): TSQLToken; overload; 
function NextSQLToken(var p: PChar; out Token: String; CurSection: TSQLToken): TSQLToken; overload; 

function GetIndexForOrderBy(const SQL: WideString; DataSet: TDataSet): TIndexDef; 
function GetTableNameFromSQL(const SQL: WideString): WideString; 
function GetTableNameFromQuery(const SQL: Widestring): Widestring; 
function AddParamSQLForDetail(Params: TParams; SQL: WideString; Native: Boolean; QuoteChar: WideString = ''): WideString; 
function IsMultiTableQuery(const SQL: WideString): Boolean; 
function SQLRequiresParams(const SQL: WideString): Boolean; 

function NextSQLTokenEx(var p: PWideChar; out Token: UnicodeString; CurSection: TSQLToken; IdOption: IDENTIFIEROption): TSQLToken; overload; 
function NextSQLTokenEx(var p: PWideChar; out Token: WideString; CurSection: TSQLToken; IdOption: IDENTIFIEROption): TSQLToken; overload; 
function NextSQLTokenEx(var p: PAnsiChar; out Token: AnsiString; CurSection: TSQLToken; IdOption: IDENTIFIEROption): TSQLToken; overload; 
function GetTableNameFromSQLEx(const SQL: WideString; IdOption: IDENTIFIEROption): WideString; 

Ésta es una muestra muy simple para mostrar cómo analizar una sentencia SQL y obtener todos los elementos.

uses 
    TypInfo, 
    DbCommon, 
    SysUtils; 


const 
    StrSql ='Select Field1, Field2, 54 field3, Field4 from Mytable1 Order by Field1,Field5'; 

procedure ParseSql(Const Sql : string); 
var 
    SQLToken  : TSQLToken; 
    CurSection : TSQLToken; 
    Start  : PWideChar; 
    Token  : WideString; 
    IdOption  : IDENTIFIEROption; 
begin 
    IdOption :=idMixCase; 
    Start  :=PWideChar(StrSql); 
    CurSection := stUnknown; 
    repeat 
    SQLToken := NextSQLTokenEx(Start, Token, CurSection, IdOption); 
    if SQLToken<>stEnd then 
    Writeln(Format('Type %s Token %s', [GetEnumName(TypeInfo(TSQLToken), integer(SQLToken)),Token])); 
    CurSection := SQLToken; 
    until SQLToken in [stEnd]; 
end; 



begin 
    try 
    ParseSql(StrSql); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 

Esto devolverá

Type stSelect Token Select 
Type stFieldName Token Field1 
Type stFieldName Token Field2 
Type stNumber Token 54 
Type stFieldName Token field3 
Type stFieldName Token Field4 
Type stFrom Token from 
Type stTableName Token Mytable1 
Type stOrderBy Token Order by 
Type stFieldName Token Field1 
Type stFieldName Token Field5 
+0

Es realmente bueno, pero cree que 'TOP' es un campo, pero no es por supuesto. –

+0

No funciona bien como dije. Falla en muchos casos, como cuando tienes 'Table.Field' devuelve' Table' como un campo y 'Field' como Field también. Falla al detectar 'Count()', 'Sum()', 'Average' y' top' también. No es lo suficientemente bueno para lo que estoy buscando, pero gracias por tu ayuda. –

+1

@Rafael lo siento por eso, voy a mantener mi respuesta, porque puedo ayudarlo a alguien más en el futuro a analizar oraciones SQL simples. Otra opción es crear tu propio analizador basado en esta implementación (DbCommon) y leer un artículo como este http://www.felix-colibri.com/papers/db/sql_parser/sql_parser.html – RRUZ

Cuestiones relacionadas