Sql-Server

動態執行查詢在從過程呼叫時會產生錯誤,但在手動執行時會起作用

  • November 3, 2020
create procedure createTable(@tableName varchar(25), @columnName varchar(25), @columnType varchar(25))
as
   begin

   declare @sqlQuery as varchar(MAX)
   set @sqlQuery = 'create table ' + @tableName + '(' + @columnName + ' ' + @columnType + ' primary key)'

   print (@sqlQuery)
   exec @sqlQuery

   end
go

上面的程式碼產生以下輸出和錯誤:

create table proba2(ceva int primary key)
Msg 2812, Level 16, State 62, Procedure createTable, Line 9 [Batch Start Line 13]
Could not find stored procedure 'create table proba2(ceva int primary key)'.

奇怪的是,如果我複制輸出中的第一行(即列印的查詢本身)並執行它,它就可以工作;該表將被創建。儘管如此,儲存過程中的 exec 卻沒有。據我所知,該過程的 exec 呼叫應該可以工作。它甚至應該在字元串末尾不指定“主鍵”的情況下工作。

替換exec @sqlQueryexec (@sqlQuery)必須工作。但是,sp_executesql建議在您的情況下使用,因為它具有更大的靈活性。

下面是一個典型的例子sp_executesql

Declare   @DatabaseName nvarchar(128) = 'MyDB'
       , @schema_name nvarchar(128) = 'dbo'
       , @table_name nvarchar(128) = 'MyTbl'
       , @column_name nvarchar(128) = 'MyTblColumn'
       , @ReadColumnInfo nvarchar(max)
       , @datatypename varchar(128);

select @ReadColumnInfo = 'Use ' + QUOTENAME(@DatabaseName) + '; ';
set @ReadColumnInfo =  @ReadColumnInfo + '
SELECT @datatype = TYPE_NAME(c.user_type_id)
FROM sys.objects AS o   
JOIN sys.columns AS c  ON o.object_id = c.object_id  
WHERE o.name = @TblName and o.schema_id = SCHEMA_ID (@scmName) and c.name = @columnName';


exec sp_executesql 
         @ReadColumnInfo -- Statement
       , N'@TblName varchar(128), @columnName varchar(128), @scmName varchar(128), @datatype varchar(128) OUTPUT' --- Params within Statement
       , @TblName = @table_name, @columnName = @column_name, @scmName = @schema_name, @datatype = @datatypename OUTPUT;  --- Param Values within Statement 
select @datatypename;

引用自:https://dba.stackexchange.com/questions/279101