将多个数据类型传递到动态sql值中而不传递参数化查询

时间:2018-07-25 17:29:25

标签: sql-server stored-procedures dynamic-sql parameterized-query

我在存储过程中有一个动态SQL查询,该查询可以工作并给出正确的结果。但这花了太长时间,因为我必须将其比较为varchar而不是int。我相信SQL Server中的@query变量要求该语句为unicode。 这是动态sql部分

ALTER PROCEDURE [dbo].[sp_GetRows]( @Id varchar(64))
AS
BEGIN
 DECLARE @Query nvarchar(4000),
 @Comp varchar(256)

SELECT @Comp
=  STUFF(( 
        SELECT DISTINCT ',' + char(39)+
        tci.Component +char(39)
        FROM  TCI tci WITH(NOLOCK) 
            JOIN CDetail cd WITH(NOLOCK) 
           ON  tci.ParentCId = cd.CIdentifier 
            WHERE tci.ParentCId  = @Id
            AND cd.ParentBranch IS NULL
            FOR XML PATH('')),1,1,'')
    SET @Query
    = 'WITH CTE AS 
        (       
            SELECT '+@Id+' as ParentCId, CIdentifier as ChildCId,
            a.Comp as Comp 
            from dbo.CD cd WITH(NOLOCK)             

               INNER JOIN  

            (SELECT DISTINCT ChildCId,Comp 
            FROM TCI tc WITH(NOLOCK) 
            WHERE ParentCId = '+ @Id + '

                                ) a 
            ON cd.CIdentifier= a.ChildCId
        );
       EXEC (@Query)
        END;

这是比较-         从#tempTable中选择SELECT标识符TEMP WITH(NOLOCK)             WHERE temp.CIdentifier <'+ @ Id +'....

这与CIdentifier = 1122233而不是CIdentifier ='1122233'相比,因为动态SQL不允许我将其作为整数传递。我不断收到“无法将varchar转换为int错误”

因此,我使用了参数化查询-希望能够使我传递int值。这是查询部分

        SET @Query
    = N';WITH CTE AS 
        (       
            ......
             (SELECT DISTINCT ChildCId,Comp 
                    FROM TCI tc WITH(NOLOCK) 
                    WHERE ParentCId = @Id
                    AND ChildCId + tc.Comp
                        NOT IN
            (SELECT ChildId + Comp FROM dbo.TCI WITH(NOLOCK) 
        WHERE ParentId IN   (SELECT CIdentifier FROM  #tempTable WITH(NOLOCK) 
                            WHERE  temp.CIdentifier < @Idn
                            AND Comp IN ( @Comp))                   
                            )
                            ) 
            )a 
         ON cd.CIdentifier= a.ChildId
        )
        SELECT * FROM CTE;'


EXEC sp_executeSQL @Query,'@Id VARCHAR(64),@Idn INT,@comp VARCHAR(256)',@Id=@Id,@Idn=@Idn,@comp =@comp 

这给了我错误的结果,并且当我看到使用跟踪的执行时-看到没有将值传递到查询中。如何获取查询以获取变量?

1 个答案:

答案 0 :(得分:1)

只需在第一个查询中将WHERE ParentCId = '+ @Id + '更改为WHERE ParentCId = '+ cast(@Id as varchar(16)) + '。问题在于,当值是+类型或numeric类型时,SQL Server将date视为加法,否则将其串联。这是您得到错误的地方。但是,执行此操作时,它不会使SQL Server将其与字符串文字进行比较,因此您不必为此担心。如果您在末尾使用PRINT (@Query)而不是EXEC (@Query)

,则可以看到此信息

请注意,需要在您拥有任何NUMERIC数据类型的其他位置进行更改,例如在SELECT部分SELECT '+ cast(@Id as varchar(16)) +'

此外,您的代码不会显示@Id值的来源,因此请谨慎使用SQL注入。