我在in子句中使用,但给出类型转换错误

时间:2019-06-11 12:20:37

标签: sql sql-server tsql

我使用了动态SQL查询并防止SQL注入 我想使用( @clientIds )而不是('+ @ clientIds +'

GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--exec test '1,2'
Alter PROCEDURE [dbo].[test]
    @clientIds varchar(Max)
AS
BEGIN
    DECLARE @sSQL  nvarchar(max);
    DECLARE @params NVARCHAR(MAX);
    Select @sSQL=N'select * from tblClient WITH (NOLOCK) Where clientID in ( @clientIds )'
    SET @params = N'@clientIds NVARCHAR(50)';
    EXECUTE sp_executesql @sSQL, @params, @clientIds;
END

1 个答案:

答案 0 :(得分:0)

您的SP可以像

Alter PROCEDURE [dbo].[test]
    @clientIds varchar(Max)
AS
    SET NOCOUNT ON;

    DECLARE @SQL  NVARCH(max) = N'SELECT * FROM [tblClient] WHERE [clientID] IN(' + @clientIds + N');';

    EXECUTE sp_executesql @SQL;

但是,这不会阻止SQL注入,因为它可能在参数'1,2;DELETE * FROM tblClient;中。

我将使用 Table-Valued Parameter 作为

CREATE TYPE MyType AS TABLE (Id INT);

Alter PROCEDURE [dbo].[test]
  @IDs MyType READONLY
AS
    SET NOCOUNT ON;

    SELECT *
    FROM [tblClient] 
    WHERE [clientID] IN(SELECT Id FROM @IDs);

OR

Alter PROCEDURE [dbo].[test]
  @IDs MyType READONLY
AS
    SET NOCOUNT ON;

    SELECT C.*
    FROM [tblClient] C INNER JOIN @IDs Ids
    ON C.clientID = Ids.Id;

另外,请检查my answer here是否适合您的情况。