我在执行下面的代码时遇到问题,它给出了如下错误:
消息102,级别15,状态1,行3'@ST'附近的语法不正确。
我可以尝试使用动态SQL实现登录,但想尝试使用sp_executesql
方法。如果我有一些语法错误或者我不应该将表名作为参数传递,请告诉我?
DECLARE @SQL NVARCHAR(4000)= '';
SET @SQL = N'--INSERT INTO #missingkeys ( SOURCE_KEY,[ROWCOUNT] )
SELECT S.[SOURCE_KEY], COUNT(1) AS [ROWCOUNT] FROM (SELECT DISTINCT @SK AS [SOURCE_KEY]
FROM [PDA].@ST ) AS S
LEFT JOIN [PDA].@MT AS T
ON T.[SOURCE_KEY] = S.[SOURCE_KEY]
GROUP BY S.[SOURCE_KEY]';
DECLARE @SOURCETABLE NVARCHAR(255)= 'FACT';
DECLARE @SOURCE_KEY NVARCHAR(255)= 'KEY', @MAP_TABLE NVARCHAR(255)= 'DimMap';
EXEC sp_executesql
@SQL,
N'@SK nvarchar(255), @ST nVARCHAR(255), @MT nVARCHAR(255)',
@SK = @SOURCE_KEY,
@ST = @SOURCETABLE,
@MT = @MAP_TABLE;
您不能将列作为参数,对于任何对象名称(表,存储过程,...)都是相同的。
您必须使语句动态化,即在SQL字符串中格式化列名:
SET @SQL =
N'SELECT '+
'S.[SOURCE_KEY],'+
'COUNT(1) AS [ROWCOUNT] '+
'FROM ('+
'SELECT DISTINCT '+
QUOTENAME(@SK)+' AS [SOURCE_KEY] '+
'...'; -- the rest of your statement
PS:使用QUOTENAME转义对象名称以避免SQL注入。
如果将数据写入相同的用户定义表类型,则可以传递表。参数必须是READONLY:
CREATE TYPE [dbo].[t] AS TABLE([a] [int] NOT NULL PRIMARY KEY CLUSTERED)
create table #t (a int)
insert into #t values (1), (2), (3)
exec sp_executesql N'select * from #t'
declare @t t
insert into @t select a from #t
exec sp_executesql N'Select * from @p1', N'@p1 t readonly', @t