我在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
不是''
,则执行第一个条件。如何实施此解决方案?
在这里真正应该做的是而不是向语句中注入值;该路径导致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;
您可以通过编程方式构建这样的条件:
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