gpt4 book ai didi

sql - 你会努力让你的 SQL 查询安全吗?

转载 作者:行者123 更新时间:2023-12-05 00:42:03 27 4
gpt4 key购买 nike

我的情况是,我得到了一个逗号分隔的 VarChar 作为存储过程的输入。我想做这样的事情:

SELECT * FROM tblMyTable 
INNER JOIN /*Bunch of inner joins here*/
WHERE ItemID IN ($MyList);

但是,您不能将 VarChar 与 IN 一起使用。陈述。有两种方法可以解决这个问题:
  • (错误的方式)在字符串中创建 SQL 查询,如下所示:
    SET $SQL = '
    SELECT * FROM tblMyTable
    INNER JOIN /*Bunch of inner joins here*/
    WHERE ItemID IN (' + $MyList + ');
    EXEC($SQL);
  • (正确的方法)创建一个包含 $MyList 值的临时表,然后在初始查询中加入该表。

  • 我的问题是:

    选项 2 在创建临时表时对性能造成了相对较大的影响,这不太理想。

    虽然选项 1 对 SQL 注入(inject)攻击开放,但由于我的 SPROC 是从经过身份验证的源调用的,它是否 真的事情?只有受信任的来源才会执行这个 SPROC,所以如果他们选择破坏数据库,那是他们的特权。

    那么,你会在多大程度上保证你的代码安全呢?

    最佳答案

    你用的是什么数据库?在 SQL Server 中,您可以创建一个拆分函数,该函数可以拆分一个长字符串并在亚秒内返回一个表。您在查询中像普通表一样使用表函数调用(不需要临时表)

    您需要创建一个拆分功能,或者如果您有一个,只需使用它。这是如何使用拆分功能的:

    SELECT
    *
    FROM YourTable y
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value

    I prefer the number table approach to split a string in TSQL但是在 SQL Server 中拆分字符串的方法有很多,请参阅上一个链接,其中解释了每种方法的优点和缺点。

    要使 Numbers Table 方法起作用,您需要设置一个时间表,这将创建一个表 Numbers包含从 1 到 10,000 的行:
    SELECT TOP 10000 IDENTITY(int,1,1) AS Number
    INTO Numbers
    FROM sys.objects s1
    CROSS JOIN sys.objects s2
    ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)

    设置 Numbers 表后,创建此拆分函数:
    CREATE FUNCTION [dbo].[FN_ListToTable]
    (
    @SplitOn char(1) --REQUIRED, the character to split the @List string on
    ,@List varchar(8000)--REQUIRED, the list to split apart
    )
    RETURNS TABLE
    AS
    RETURN
    (

    ----------------
    --SINGLE QUERY-- --this will not return empty rows
    ----------------
    SELECT
    ListValue
    FROM (SELECT
    LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
    FROM (
    SELECT @SplitOn + @List + @SplitOn AS List2
    ) AS dt
    INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
    WHERE SUBSTRING(List2, number, 1) = @SplitOn
    ) dt2
    WHERE ListValue IS NOT NULL AND ListValue!=''

    );
    GO

    您现在可以轻松地将 CSV 字符串拆分为表格并加入表格:
    select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,')

    输出:
    ListValue
    -----------------------
    1
    2
    3
    4
    5
    6777

    (6 row(s) affected)

    您可以像这样使用 CSV 字符串,而不需要临时表:
    SELECT * FROM tblMyTable 
    INNER JOIN /*Bunch of inner joins here*/
    WHERE ItemID IN (select ListValue from dbo.FN_ListToTable(',',$MyList));

    关于sql - 你会努力让你的 SQL 查询安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2425150/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com