2016-04-16 1 views
9
--sp_executesql version 
    --SET @SQLQUERY = 'UPDATE @TableName SET Brief = @Brief, 
    --    [Full] = @Full,       
    --    CreatedBy = @CreatedBy, 
    --    Department = @Department, 
    --    Answer = @Answer WHERE [email protected]'; 
--SET @ParamDefinition=N'@TableName nvarchar(50),@Brief nvarchar(50),@Full nvarchar(MAX),@CreatedBy varchar(256),@Department varchar(256),@Answer nvarchar(MAX),@Id int' 
-- exec sp_executesql @SQLQUERY,@ParamDefinition,@TableName,@Brief,@Full,@CreatedBy,@Department,@Answer,@Id; 

-- exec version 
SET @SQLQUERY = 'UPDATE ' + @TableName + ' SET 
        Brief ='+ @Brief+', 
        [Full] ='+ @Full+',       
        CreatedBy ='+ @CreatedBy+', 
        Department ='+ @Department+', 
        Answer ='[email protected]+' WHERE Id='+CAST(@Id as nvarchar(10)) 

print @SQLQUERY; 
EXEC (@SQLQUERY) 

Я использовал оба EXEC и sp_executesql процедуры, чтобы выполнить мой динамический запрос, но оба терпят неудачу.T-SQL процедуры, скалярная переменная ошибка даже после успешного Updation

В случае EXEC динамический запрос не установлен в @SQLQUERY переменной (видно после отладки), в случае sp_executesql я получаю скалярную переменную ошибку, хотя база данных обновляется, и я уже прошел все к нему.

ответ

6

Корпус очень прост. Вы не можете параметризуете имя таблицы/столбца в UPDATE высказывания:

SET @SQLQUERY = 'UPDATE @TableName  --here is problem 
       SET Brief = @Brief, 
         [Full] = @Full,       
         CreatedBy = @CreatedBy, 
         Department = @Department, 
         Answer = @Answer 
       WHERE [email protected]'; 


SET @ParamDefinition=N'@TableName nvarchar(50),@Brief nvarchar(50), 
         @Full nvarchar(MAX), @CreatedBy varchar(256), 
         @Department varchar(256),@Answer nvarchar(MAX),@Id int' 

EXEC dbo.sp_executesql @SQLQUERY,@ParamDefinition, 
         @TableName,@Brief,@Full, 
         @CreatedBy,@Department,@Answer,@Id; 

Использование замены вместо:

SET @SQLQUERY = N'UPDATE <tab_name> 
        SET Brief  = @Brief, 
        [Full]  = @Full,       
        CreatedBy = @CreatedBy, 
        Department = @Department, 
        Answer  = @Answer 
        WHERE Id = @Id'; 

SET @SQLQUERY = REPLACE(@SQLQUERY, '<tab_name>', QUOTENAME(@TableName)); 

SET @ParamDefinition=N'@Brief nvarchar(50),@Full nvarchar(MAX), 
         @CreatedBy varchar(256),@Department varchar(256), 
         @Answer nvarchar(MAX),@Id int'; 

EXEC [dbo].[sp_executesql] @SQLQUERY, 
          @ParamDefinition, 
          @Brief,@Full,@CreatedBy, @Department,@Answer,@Id; 

Примечание:

  • Имя таблицы должны иметь SYSNAME типа данных.
  • Рекомендуется использовать идентификаторы с QUOTENAME (чтобы избежать возможных атак SQL-инъекций).
  • Я думаю, @CreatedBy is datetime Вот почему я не понимаю, почему он передан как varchar(256).
  • Это хорошая практика, чтобы закончить каждое заявление с помощью ;. В будущих версиях это будет обязательно.
+1

спасибо, что я застрял на нем в течение длительного времени в течение 12 часов: D – Aqib