TMSScript и обобщённые табличные выражения

Обсуждение возникших проблем, предложений и ошибок SDAC компонентов
Ответить
saupg
Сообщения: 18
Зарегистрирован: Вт 06 май 2014 07:01

TMSScript и обобщённые табличные выражения

Сообщение saupg » Ср 08 окт 2014 13:55

Здравствуйте!

Часто в проекте использую рекурсивные запросы (обобщённые табличные выражения), в частности для выборки данных из иерархических справочников (записи с полями ID, ID_PARENT, NAME - каждая запись ссылается на родительскую запись, аналог - стуктура файловой системы с каталогами и файлами). Начиная с SQL Server 2005 такие запросы можно строить с помощью конструкции WITH (Common table expression или обобщённые табличные выражения). Но обязательно требуется наличие символа ";" перед этим ключевым словом (как правило, везде пишут так ";WITH ...", но можно оставлять ";" и в конце предыдущей строки).

Для выполнения скриптов в программе используется компонент TMSScript, который считает символ ";" разделителем, из-за чего пакет SQL-команд разбивается на "ДО WITH" и "ПОСЛЕ WITH". Если в пакете перед WITH декларируются локальные переменные, то в самом WITH и после него эти переменные уже не видимы. Очистка свойства Delimiter у TMSScript не помогает.

Пример простейшего скрипта с применением WITH, полностью валидного с точки зрения SQL сервера:

Код: Выделить всё

procedure TForm1.Button6Click(Sender: TObject);
begin
  MSScript2.SQL.Text := 'DECLARE @I SMALLINT ' +
    'SELECT @I = 1 ' +
    ';WITH TAB (M) AS ( ' +
    'SELECT @I ' +
    'UNION ALL ' +
    'SELECT CAST(T.M + 1 AS SMALLINT) ' +
    'FROM TAB T ' +
    'WHERE T.M < 10 ' +
    ') ' +
    'SELECT * FROM TAB ' +
    'GO';
  MSScript2.Execute;
end;
При выполнении получаем ошибку:
Неправильный синтаксис около конструкции ")".
Необходимо объявить скалярную переменную "@I".
При этом имеется такое наблюдение: если скрипт содержит ";WITH" в теле хранимой процедуры, то ";" игнорируется, и всё выполняется хорошо. Т.е. вы всё-таки производите какой-то анализ запроса, а не тупо разбиваете скрипт на выполняемые пакеты по символу ";".

Исправьте, пожалуйста.

AndreyZ
Devart Team
Сообщения: 328
Зарегистрирован: Чт 08 сен 2011 13:18

Re: TMSScript и обобщённые табличные выражения

Сообщение AndreyZ » Чт 09 окт 2014 14:13

В случае, когда вы очищаете свойство TMSScript.Delimiter, его значение устанавливается в значение по-умолчанию, т.е. в тот же символ ';' .

Для решения этой проблемы, перед выполнением скрипта, попробуйте установить свойству TMSScript.Delimiter значение 'GO' . Например:

Код: Выделить всё

MSScript2.Delimiter := 'GO';

Ответить