1

我在存储过程中有一个动态 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;

这是比较- SELECT CIdentifier FROM #tempTable temp WITH(NOLOCK) WHERE temp.CIdentifier < '+@Id+'....

这比较为 CIdentifier =1122233 而不是 CIdentifier ='1122233' 因为动态 SQL 不允许我将它作为 int 传递。我不断收到“无法将 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 

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

4

1 回答 1

1

只需在第一个查询中更改WHERE ParentCId = '+ @Id + '为。问题是当值是类型时, WHERE ParentCId = '+ cast(@Id as varchar(16)) + 'SQL Server 将其视为加法,或者,如果不是,则连接。这是您从中得到错误的地方。但是,当您这样做时,它不会让 SQL Server 将其作为字符串文字进行比较,因此您不必担心这一点。如果您在最后使用而不是+numericdatePRINT (@Query)EXEC (@Query)

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

此外,您的代码没有显示@Id值的来源,因此请注意此处的 SQL 注入。

于 2018-07-25T17:59:58.510 回答