Библиотека для разбора операторов SQL - PullRequest
6 голосов
/ 04 декабря 2009

Я бы хотел иметь возможность анализировать произвольный оператор SQL SELECT и извлекать различные составляющие части (столбцы, отношения, условия JOIN, условия WHERE, столбцы ORDER BY), в идеале с использованием Delphi. Быстрый поиск в Google показывает несколько различных бесплатных продуктов, но неясно, завершены ли они и / или находятся в стадии активной разработки.

Моя немедленная необходимость - просто извлечь список отношений, используемых в серии определений VIEW, чтобы убедиться, что требуемые представления или таблицы существуют, прежде чем я попытаюсь СОЗДАТЬ представление. Так, например, для утверждения:

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

Мне нужно вернуть значения "Люди" и "Заказы". (Очевидно, это простой пример. Я хочу иметь возможность обрабатывать более сложные случаи, когда, например, слово «FROM» может появляться в списке столбцов как часть выражения).

Я пытаюсь предоставить эту услугу в базе данных, которая позволяет использовать функции STDCALL, экспортированные из DLL, поэтому в идеале любая библиотека-кандидат может вызываться из Delphi или C.

Ответы [ 3 ]

6 голосов
/ 04 декабря 2009

Взгляните на Gold Parser. Доступна версия Delphi и грамматика SQL на странице загрузки.

0 голосов
/ 04 декабря 2009

Вы можете использовать Delphi с ADODB.

Используйте TADOQuery, чтобы проверить, хорош ли ваш запрос или нет, не открывая набор записей. Вы также можете получить имена полей запроса.

Оставьте TADOConnection на форме. Удалите TMemo и TButton и попробуйте этот код:

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 голосов
/ 04 декабря 2009

парсеры SQL сложны.

Думал ли ты о таком подходе:

  1. Начать транзакцию.
  2. Отправьте команду CREATE VIEW на сервер.
  3. поймать ошибку (любой достойный драйвер базы данных должен это сделать).
  4. если произошла ошибка, проанализируйте сообщение об ошибке и покажите отсутствующие таблицы клиенту.
  5. Откат

см. Этот пример (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

или этот (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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...