Where condition as varchar 使用变量

Where condition as varchar using variable

我在 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 不是 '' 然后执行第一个条件。我该如何实施这个解决方案?

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

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

你应该真正在这里做的是而不是将值注入你的声明;该路径导致 SQL 注入。正确地参数化你的陈述。

如果您必须传递分隔列表,请使用字符串拆分器。我 假设 您正在使用最新版本的 SQL 服务器(如果不是,您将需要使用用户定义的字符串拆分器,例如 XML 拆分器delimitedsplit8k_LEAD).

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;