sql - 使用动态 SQL 获取各种错误

标签 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
Invalid column name '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)

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

Msg 102, level 15, state 1, line 9
Incorrect syntax near ')'

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

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

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

我是否错过了我做错的事情?任何帮助将不胜感激。

谢谢。

最佳答案

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

FIPST_ENT is numeric in nature (i.e. 01-50) but cast as a character. Likewise with the other FIPCNTY_ENT and SIC2_ENT. FMSZENT is cast as a character but is sometimes numeric (i.e. 1-9) and other times non-numeric (i.e. 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;

关于sql - 使用动态 SQL 获取各种错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26917904/

相关文章:

java - 使用 save() Play Framework JPA 问题

sql-server - 使用 case 时如何更改列名? SQL 服务器查询

c# - Entity Framework 代码优先和 SQL Server 2012 序列

sql - 是否有公认的理想标记模式

sql - 比较 SQL 子查询之间的变化的更快方法?

tsql - T-SQL-连接多个表导致重复的行

sql - 从 PostgreSQL 表中提取特定列并对其值进行更新

postgresql - 在 pl/pgsql 中将附加文本连接到字符串变量

postgresql - 列出 Postgres 中包含具有 NULL 值的 bool 类型列的所有表?

mysql - 连接表的 SQL 查询