Как построить динамический TSQL-запрос с начальными и конечными утверждениями - PullRequest
0 голосов
/ 01 февраля 2011

ОК. Я не гуру SQL или администратор баз данных, так что, если есть лучший способ сделать это, пожалуйста, не стесняйтесь говорить.

Однако, что мне нужно сделать, это усовершенствовать существующую хранимую процедуру, которая использует dyanmic SQL, чтобы не вставлять повторяющиеся значения. SQL сам по себе, когда он указан для одной таблицы, - это просто. Однако сейчас у меня возникли проблемы с общим хранимым процессом, который у меня работает, который в целом работает для нескольких таблиц и использует TSQL. Проблема в выражениях BEGIN и END.

    SET @Query =  'IF NOT EXISTS (SELECT ' + @DescriptionFieldName + ' 
       FROM '+ @TableName +'
       WHERE (' + @DescriptionFieldName + ' = ''' + @DescriptionValue + ''') 

    BEGIN
        INSERT INTO '+ @TableName +' (' + @DescriptionFieldName + ', LastUser, LastUpdate) VALUES ('''+ ISNULL(@DescriptionValue, '') +''', '''+ ISNULL(@LastUser, '') +''',Convert(Varchar, GetDate())) '  + 'SELECT CAST(scope_identity() AS int);
    END'

EXEC (@Query)

Когда я изменяю EXEC на ПЕЧАТЬ, все кажется приемлемым с точки зрения синтаксиса, но при использовании EXEC выдает следующую ошибку:

"Неверный синтаксис рядом с ключевым словом BEGIN".

Кто-нибудь знает, как исправить эту проблему, чтобы запрос работал?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 01 февраля 2011

Похоже, у вас пропущена скобка после предложения where.

 SET @Query =  'IF NOT EXISTS (SELECT ' + @DescriptionFieldName + ' 
       FROM '+ @TableName +'
       WHERE (' + @DescriptionFieldName + ' = ' + @DescriptionValue + ') )

    BEGIN
        INSERT INTO '+ @TableName +' (' + @DescriptionFieldName + ', LastUser, LastUpdate) VALUES ('''+ ISNULL(@DescriptionValue, '') +''', '''+ ISNULL(@LastUser, '') +''',Convert(Varchar, GetDate())) '  + 'SELECT CAST(scope_identity() AS int);
    END'
1 голос
/ 01 февраля 2011

FWIW, при работе с динамическим SQL на лету для производства или генерации кода мне нравится использовать шаблоны, которые немного облегчают обслуживание (обратите внимание, что вы можете вставлять разрывы строк, что тоже хорошо - не забывайте вставить CHAR (13) / CHAR (10) или пробел перед кавычкой):

DECLARE @template AS varchar(max) = '
    IF NOT EXISTS (
        SELECT {@DescriptionFieldName} -- Note this is unnecessary
        FROM {@TableName}
        WHERE ({@DescriptionFieldName} = ''{@DescriptionValue}''
    ) 
    BEGIN
        INSERT INTO {@TableName} ({@DescriptionFieldName}, LastUser, LastUpdate)
        VALUES (''{@DescriptionValue}'', ''{@LastUser}'', ''{@LastUpdate}'');
    END
'

DECLARE @Query AS varchar(max) = @template
SET @Query = REPLACE(@Query, '{@DescriptionFieldName}', @DescriptionFieldName)
SET @Query = REPLACE(@Query, '{@TableName}', @TableName)
SET @Query = REPLACE(@Query, '{@DescriptionValue}', ISNULL(@DescriptionValue, ''))
SET @Query = REPLACE(@Query, '{@LastUser}', ISNULL(@LastUser, ''))
SET @Query = REPLACE(@Query, '{@LastUpdate}', @LastUpdate)

PRINT @Query
EXEC (@Query)

У вас все еще есть двойные кавычки, но вам не нужно добавлять строки, это очевидно, когда вы забыли заменить параметр, и вы не повторяете вставки в код, когда все должно измениться.

Также обратите внимание, что это может иметь проблему с NULL в @DescriptionValue (ваш оригинал имел ту же проблему в части WHERE в EXISTS)

Обратите внимание, что вы также можете вкладывать свои замены и с соответствующим форматированием, он может даже быть читаемым:

DECLARE @Query AS varchar(max) = @template
SET @Query = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@Query
                 ,'{@DescriptionFieldName}', @DescriptionFieldName)
                 ,'{@TableName}', @TableName)
                 ,'{@DescriptionValue}', ISNULL(@DescriptionValue, ''))
                 ,'{@LastUser}', ISNULL(@LastUser, ''))
                 ,'{@LastUpdate}', @LastUpdate)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...