【问题标题】:Cannot pass column name as parameter to sp_executesql无法将列名作为参数传递给 sp_executesql
【发布时间】:2018-01-19 06:28:29
【问题描述】:

我在执行以下代码时遇到问题,它给了我如下错误:

消息 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-server tsql dynamic-sql


    【解决方案1】:

    您不能将列作为参数,对于任何对象名称(表、存储过程...)都相同。

    您必须使语句动态化,即格式化 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 注入。

    【讨论】:

      【解决方案2】:

      如果将数据写入相同的用户定义表类型,则可以传递表。参数必须是 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-07
        • 2015-11-03
        • 1970-01-01
        • 1970-01-01
        • 2018-05-15
        • 2015-02-02
        相关资源
        最近更新 更多