使用动态SQL获取各种错误

时间:2014-11-13 20:35:46

标签: sql sql-server-2012 dynamic-sql

SET @SQLSTATEMENT = 'INSERT INTO #MAX_STORAGE
                        SELECT MAX(A.[ROW]) 
                        FROM
                            (SELECT * 
                             FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED] 
                             WHERE 
                                 [FIPST_ENT] = ' + @FIPST_ENT + ' 
                                 AND [FIPCNTY_ENT] = ' + @FIPCNTY_ENT + '
                                 AND [SIC_ENT] = ' + @SIC2_ENT + '
                                 AND [FMSZ_ENT] = ' + @FMSZENT_ENT + '
                                 AND [ESTABLISHMENTS_AVAILABLE_FMSZEST <= ' + @MAXIMUM_FMSZEST+'] > 0) A'

EXEC(@SQLSTATEMENT)

我正在运行上面的动态SQL查询作为我编写的存储过程的一部分,并收到以下错误:

  

Msg 207,Level 16,State 1,Line 7
  列名称“A”无效。

然后我更改了我的查询,使其看起来像这样(删除了别名A):

SET @SQLSTATEMENT =
    'INSERT INTO #MAX_STORAGE
        SELECT 
           MAX([ROW]) 
        FROM
           (SELECT * 
            FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED] 
            WHERE [FIPST_ENT] = ' + @FIPST_ENT + ' 
              AND [FIPCNTY_ENT] = ' + @FIPCNTY_ENT + '
              AND [SIC_ENT] = ' + @SIC2_ENT + '
              AND [FMSZ_ENT] = ' + @FMSZENT_ENT + '
              AND [ESTABLISHMENTS_AVAILABLE_FMSZEST <= ' + @MAXIMUM_FMSZEST + '] > 0)'

EXEC(@SQLSTATEMENT)

但我仍遇到错误(这次不同):

  

消息102,级别15,状态1,行9   ')'

附近的语法不正确

我在程序的前面声明了以下变量,并在它们旁边看到了各自的数据类型/长度:

  • @FIPST_ENT CHAR(2)
  • @FIPCNTY_ENT CHAR(3)
  • @ SIC2_ENT CHAR(2)
  • @FMSZENT_ENT CHAR(1)
  • @MAXIMUM_FMSZENT CHAR(1)
  • @SQLSTATEMENT VARCHAR(MAX)

在存储过程中到达此动态SQL语句之前,临时表#MAX_STORAGE已创建,并且只包含一列数据类型int

我错过了一些我做错的事吗?任何帮助将不胜感激。

感谢。

1 个答案:

答案 0 :(得分:2)

至少,您需要在动态SQL中将字符串字段括在转义单引号中。我在下面展示的改编是基于对该问题的评论:

  

FIPST_ENT本质上是数字(即01-50),但是作为角色进行投射。与其他FIPCNTY_ENTSIC2_ENT相同。 FMSZENT被转换为字符,但有时是数字(即1-9),有时则是非数字(即A-C)。

所以似乎只有FMSZENT需要转义单引号。

此外,使用派生查询需要别名。因此无论最初的问题是什么,您都会通过删除别名来引入新的解析错误; - )。

SET @SQLSTATEMENT =

'INSERT INTO #MAX_STORAGE
SELECT MAX(tmp.[ROW]) FROM

(SELECT * FROM [DATABASE].[dbo].[Refined_Est_Probability_09_MODIFIED] 
WHERE [FIPST_ENT] = '+@FIPST_ENT+' 
AND [FIPCNTY_ENT] = '+@FIPCNTY_ENT+'
AND [SIC_ENT] = '+@SIC2_ENT+'
AND [FMSZ_ENT] = '''+@FMSZENT_ENT+'''
AND [ESTABLISHMENTS_AVAILABLE_FMSZEST<='+@MAXIMUM_FMSZEST+'] > 0) tmp;'

现在,在调试动态SQL时,第一步应该是查看实际构建的SQL,因为它可能不是您认为的应该是:

PRINT @SQLSTATEMENT;