【问题标题】:How to use integer variable in Dynamic Query如何在动态查询中使用整数变量
【发布时间】:2021-09-05 12:42:45
【问题描述】:

我创建了以下动态查询来检查特定属性的长度是否超过 50。我试图使长度大小也动态但低于错误。

Msg 207, Level 16, State 1, Line 7
Invalid column name '50'.

我想出的查询如下。我对 SQL 很陌生,并试图解决这个错误。谢谢!

--Rule A.5.Summary :- Length
/* The 'DECLARE' statements below are used to
define standard test parameters and their datatypes. The values for these
parameters will be updated for each of the DQ dimensions/KDEs being tested */
DECLARE @DQ_DIMENSION_RULE VARCHAR(100)
DECLARE @RULE_NO VARCHAR(100)
DECLARE @TABLE_NAME VARCHAR(100)
DECLARE @DATA_ATTRIBUTE VARCHAR(100)
DECLARE @LENGTH_SIZE INT

/*The 'SET' statements below are used to
assign values to each of the test parameters declared above. 
The values will depend on the DQ dimension/KDE being tested.*/
SET @DQ_DIMENSION_RULE = 'Accuracy - Negative Values'
SET @RULE_NO = 'A.4'
SET @TABLE_NAME = 'TRANSACTIONS'
SET @DATA_ATTRIBUTE = 'TRANSACTIONID'
SET @LENGTH_SIZE = 50

DECLARE @sql nvarchar(max) = N'
SELECT 
    ' + QUOTENAME(@DQ_DIMENSION_RULE, '''') + N' AS [DQ_Dimension_Rule],
    ' + QUOTENAME(@RULE_NO, '''') + N' AS [Rule_No],
    ' + QUOTENAME(@TABLE_NAME, '''') + N' AS [Table Name],
    ' + QUOTENAME(@DATA_ATTRIBUTE, '''') + N' AS [Column Name],
    case when SUM(CASE WHEN LEN(' + QUOTENAME(@DATA_ATTRIBUTE) + N') >' + QUOTENAME(@LENGTH_SIZE) + N' THEN 1 ELSE 0 END) > 0 then ''Y'' else ''N'' end as [Potential Issue(Y/N)]
    
FROM ' + QUOTENAME(@TABLE_NAME)

-- The data from 'SELECT' statement is being inserted into the summary table
--INSERT INTO summary
EXEC sp_executesql @sql;

【问题讨论】:

  • 要调试动态 SQL,请使用 print 语句而不是 exec 语句,并打印 SQL,然后它是静态的且易于调试。如果您仍然卡住,请发布生成的静态 SQL,因为我们需要看到它来提供帮助。
  • 我还注意到,迄今为止,您尚未接受任何问题的单一答案。您熟悉如何接受答案吗?这是本网站的预期礼仪。

标签: sql sql-server tsql dynamic-sql


【解决方案1】:

你不应该在整数值周围加上QUOTENAME(),整数不是你需要引用的表名,等等。

您应该只将整数转换为字符串,不带引号...

DECLARE @sql nvarchar(max) = N'
SELECT 
    ' + QUOTENAME(@DQ_DIMENSION_RULE, '''') + N' AS [DQ_Dimension_Rule],
    ' + QUOTENAME(@RULE_NO, '''') + N' AS [Rule_No],
    ' + QUOTENAME(@TABLE_NAME, '''') + N' AS [Table Name],
    ' + QUOTENAME(@DATA_ATTRIBUTE, '''') + N' AS [Column Name],
    case when SUM(CASE WHEN LEN(' + QUOTENAME(@DATA_ATTRIBUTE) + N') >' + CAST(@LENGTHSIZE AS NVARCHAR(MAX)) + N' THEN 1 ELSE 0 END) > 0 then ''Y'' else ''N'' end as [Potential Issue(Y/N)]
    
FROM ' + QUOTENAME(@TABLE_NAME)
  • QUOTENAME(@LENGTHSIZE) => CAST(@LENGTHSIZE AS NVARCHAR(MAX))

【讨论】:

    【解决方案2】:

    比注入更好,参数化它:

    DECLARE @DQ_DIMENSION_RULE VARCHAR(100);
    DECLARE @RULE_NO VARCHAR(100);
    DECLARE @TABLE_NAME sysname; --Correct data type for object names
    DECLARE @DATA_ATTRIBUTE VARCHAR(100);
    DECLARE @LENGTH_SIZE INT;
    
    SET @DQ_DIMENSION_RULE = 'Accuracy - Negative Values';
    SET @RULE_NO = 'A.4';
    SET @TABLE_NAME = 'TRANSACTIONS';
    SET @DATA_ATTRIBUTE = 'TRANSACTIONID';
    SET @LENGTH_SIZE = 50;
    
    DECLARE @sql nvarchar(max) = N'
    SELECT 
        ' + QUOTENAME(@DQ_DIMENSION_RULE, '''') + N' AS [DQ_Dimension_Rule],
        ' + QUOTENAME(@RULE_NO, '''') + N' AS [Rule_No],
        N' + QUOTENAME(@TABLE_NAME, '''') + N' AS [Table Name],
        ' + QUOTENAME(@DATA_ATTRIBUTE, '''') + N' AS [Column Name],
        case when SUM(CASE WHEN LEN(' + QUOTENAME(@DATA_ATTRIBUTE) + N') > @LENGTH_SIZE THEN 1 ELSE 0 END) > 0 then ''Y'' else ''N'' end as [Potential Issue(Y/N)]
    FROM ' + QUOTENAME(@TABLE_NAME) + N';';
    
    EXEC sys.sp_executesql @sql, N'@LENGTH_SIZE int', @LENGTH_SIZE;
    

    我还更改了动态对象的数据类型,并确保它的文字字符串也注入了 nvarchar 符号字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      • 2020-07-13
      • 2015-09-02
      • 1970-01-01
      • 2018-04-06
      相关资源
      最近更新 更多