【问题标题】:Where condition as varchar using variablewhere 条件为 varchar 使用变量
【发布时间】:2021-04-01 00:34:17
【问题描述】:

我在 varchar 中有一个 SQL 查询,如下所示:

declare @dataSourceId varchar(500) = ''
declare @SQL varchar(500) = 'select * from DataSources
                             where Data is not null 
                               and DataSourceId not in ('+@dataSourceId+')
                                or Data is not null 
                               and DataSourceId is not null'

如果@dataSourceId 是空字符串'' 那么我想执行条件Data is not null and DataSourceId is not null 但如果@dataSourceId 不是'' 然后执行第一个条件。如何实施此解决方案?

【问题讨论】:

  • @dataSourceId 可以包含什么,例如像'7,13,42' 这样的值列表?像select FooId from Bar 这样的可执行代码呢?如何处理它们有很大的不同。

标签: sql sql-server tsql where-clause dynamic-sql


【解决方案1】:

你应该真正在这里做的是在你的陈述中注入价值;该路径导致 SQL 注入。正确参数化您的语句。

如果您必须传递一个分隔列表,请使用字符串拆分器。我假设您使用的是最新版本的 SQL Server(如果没有,您需要使用用户定义的字符串拆分器,例如用于delimitedsplit8k_LEAD 的 XML 拆分器)。

SELECT *
FROM dbo.DataSources
WHERE (Data IS NOT NULL 
  AND DataSourceId not in (SELECT value FROM STRING_SPLIT(@dataSourceId,',')))
   OR (NULLIF(@dataSourceId,'') IS NULL
  AND  Data IS NOT NULL
  AND  DataSourceId IS NOT NULL)
OPTION (RECOMPILE);

当然,由于OR 的组成,这可能表现不佳,因此您可以使用正确参数化动态语句:

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

SET @SQL = N'SELECT *' + @CRLF +    
           N'FROM dbo.DataSources' + @CRLF + 
           N'WHERE Data IS NOT NULL' + @CRLF +
           CASE WHEN NULLIF(@dataSourceId,'') IS NULL THEN N'  AND DataSourceId IS NOT NULL'
                                                      ELSE N'  AND DataSourceId NOT IN(SELECT value FROM STRING_SPLIT(@dataSourceId,'','')'
           END + N';'
EXEC sys.sp_executesql @SQL, N'@dataSourceId varchar(500)', @dataSourceId;

【讨论】:

    【解决方案2】:

    您可以像这样以编程方式构建条件:

    declare @dataSourceId varchar(500) = ''
    declare @SQL varchar(500) = 
        'select * from datasources where data is not null and '
        + case 
            when @dataSourceId <> '' then 'datasourceid in (' + @dataSourceId + ')'
            else 'datasource is not null'
        end
    

    【讨论】:

    • 然而,这可能危险容易受到注入攻击,并且不推荐。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-25
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多