2013-04-22 51 views
0

我有执行一个SQL查询的问题,下面是我的存储过程演员在SQL Server查询

查询

ALTER PROCEDURE ProcName 
(
    @iID VARCHAR(50), 
    @AccountID INT 
) 
AS 
SET NOCOUNT ON 

DECLARE @Sql VARCHAR(MAX) 

SET @Sql = 'DELETE FROM ReferringPhysician WHERE iID IN(' + @iID + ') AND AccountID = '+ @AccountID + '' 
EXEC (@Sql) 

我试图执行这个查询,但它给了我错误因为我正在使用exec(),在这里我在哪里条件下我正在处理string,而在另一种情况下我正在处理int,所以在第二种情况下我得到了铸造错误!我怎么能通过这个?

任何帮助,非常感谢!

感谢

+1

这看起来像这将是容易受到SQL注入式攻击。您应该使用sp_executesql – 2013-04-22 15:56:30

+0

@JoelCoehoorn yes,但不能将逗号分隔列表传递到sp_executesql,并根据需要正确解析它。 – 2013-04-22 16:04:49

回答

4

您的查询是容易受到SQL注入。为了避免您遇到的数据类型问题

一种方式是通过在那里你可以不使用EXEC()more details here)适当的数据类型:

DECLARE @sql NVARCHAR(MAX) = N'DELETE dbo.referringPhysician 
    WHERE iID IN (' + @iID + ') AND AccountID = @AccountID;'; 

EXEC sp_executesql @sql, N'@AccountID INT', @AccountID; 

您可以通过使用表完全保护这从SQL注入评估参数并使用正确类型而不是逗号分隔字符串传入DataTable或其他集合。例如: -

CREATE TYPE dbo.iIDs TABLE(iID INT PRIMARY KEY); 

现在你的存储过程可以完全避免动态SQL:

ALTER PROCEDURE dbo.ProcName -- always use schema prefix! 
    @iIDs dbo.iIDs READONLY, 
    @AccountID INT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DELETE r 
    FROM dbo.ReferringPhysician AS r 
    INNER JOIN @iIDs AS i 
    ON r.iID = i.iID 
    WHERE r.AccountID = @AccountID; 
END 
GO 
+0

AccountID是一个INT类型。它实际上是最容易受到攻击的@iID参数(varchar(50)) – 2013-04-22 15:57:45

+0

@JoelCoehoorn yes true但是你不能用sp_executesql修复:-) – 2013-04-22 15:59:58

+0

@AaronBertrand所以,你想说我不必须将逗号分隔的字符串传递给我的存储过程。对? – 2013-04-22 16:05:49

0

试试这个:

ALTER PROCEDURE ProcName 
(
    @iID VARCHAR(50), 
    @AccountID INT 
) 
AS 
SET NOCOUNT ON 

DECLARE @Sql VARCHAR(MAX) 

SET @Sql = 'DELETE FROM ReferringPhysician WHERE iID IN(' + CAST(@iID AS VARCHAR) + ') AND AccountID = '+ CAST(@AccountID AS VARCHAR) + '' 
EXEC (@Sql) 
+1

请[不要使用无长度的varchar](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/bad-habits-to-kick-declaring-varchar-without-length.aspx) 。 – 2013-04-22 15:54:55

+0

由于它已被定义为“VARCHAR”,因此无需将'@ iID'强制转换为'VARCHAR'。并且请使用'VARCHAR'长度(如'VARCHAR(50)' – Lamak 2013-04-22 15:55:15

+0

不知道为什么这是低调投票。它解决了问题,即使它不是最优解。 – 2013-04-22 16:04:11