Sql 其中条件为varchar,使用变量

Sql 其中条件为varchar,使用变量,sql,sql-server,tsql,where-clause,dynamic-sql,Sql,Sql Server,Tsql,Where Clause,Dynamic Sql,我在varchar中有一个SQL查询,如下所示: declare @dataSourceId varchar(500) = '' declare @SQL varchar(500) = 'select * from DataSources where Data is not null and DataSourceId not in ('+@dataSourceId+')

我在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 not null和dataSourceId 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 Server,如果不是,则需要使用用户定义的字符串拆分器,例如用于分隔DSplit8k_LEAD的XML拆分器

挑选* 来自dbo.DataSources 其中数据不为空 和数据源ID不在“从字符串中选择值”中_SPLIT@dataSourceId,',' 或NULLIF@dataSourceId,则为空 并且数据不是空的 并且数据源ID不为空 选项重新编译; 当然,由于OR组合的原因,这可能执行得不太好,因此您可以使用正确参数化的动态语句:

声明@SQL nvarcharMAX, @CRLF nchar2=NCHAR13+NCHAR10; 设置@SQL=N'SELECT*'+@CRLF+ N'来自dbo.DataSources'+@CRLF+ N'其中数据不为空'+@CRLF+ 当NULLIF@dataSourceId,则为空,然后为N'并且数据源ID不为空' ELSE N'和DataSourceId未从字符串中插入选择值_SPLIT@dataSourceId,,' 结束+N';' EXEC sys.sp_executesql@SQL,N'@dataSourceId varchar500',@dataSourceId; 然而,这很可能会受到注入攻击,这远远不是推荐的。@dataSourceId可能包含哪些内容,例如“7,13,42”之类的值列表?像select FooId from Bar这样的可执行代码怎么样?处理它们的方式有很大的不同。