Sql server 通过模式替换查询中的列
如何替换字符串中的所有列Sql server 通过模式替换查询中的列,sql-server,tsql,sql-server-2012,patindex,Sql Server,Tsql,Sql Server 2012,Patindex,如何替换字符串中的所有列 DECLARE @invalidColumns varchar(200) = 'abc, xyz' DECLARE @sqltext varchar(max) = '((abc = ''sometext'') OR (xyz = '' some more text'')) OR (pqr = ''vb'') AND ( abc != '' text '')
DECLARE @invalidColumns varchar(200) = 'abc, xyz'
DECLARE @sqltext varchar(max) = '((abc = ''sometext'') OR (xyz = '' some more text'')) OR
(pqr = ''vb'') AND ( abc != '' text '')
OR ((hht = ''asd asd'') AND ( xyz = '' More text '' ))
'
在上面的示例中,我必须在@sqlText中搜索列abc和xyz,并将它们全部替换为1=1
所以最终的输出应该是
((1 = 1) OR (1 = 1)) OR
(pqr = ''vb'') AND ( 1 != 1)
OR ((hht = ''asd asd'') AND ( 1 = 1 ))
我试着这样做,但似乎替换函数不适用于模式,也只适用于第一次发现。一条语句中可能会多次出现abc和xyz列
SELECT CASE WHEN PATINDEX('%abc% ''%',@sqltext) > 0
THEN REPLACE (@sqlText,'%abc% ''%', '1=1')
END
有什么帮助吗
编辑
我试过这个,但没有给我正确的结果
DECLARE @len INT
DECLARE @initializor INT = 1
DECLARE @First INT
DECLARE @Result VARCHAR(max) SET @Result = ''
DECLARE @EndPattern INT
SET @len = LEN(@sqltext)
WHILE( @initializor <= @len)
BEGIN
SET @First = PATINDEX('%abc% ''%', SUBSTRING(@sqltext, @initializor, @Len))
SET @EndPattern = 1
WHILE PATINDEX('%abc% ''%', SUBSTRING(@sqltext, @initializor, @EndPattern)) = 0
SET @EndPattern = @EndPattern + 1
IF COALESCE(@First, 0) <> 0
BEGIN
SET @Result = @Result + SUBSTRING(@sqltext, @initializor, @First - 1)
SET @initializor = @initializor + @First - 1
SET @EndPattern = 1
WHILE PATINDEX('%abc% ''%', SUBSTRING(@sqltext, @initializor, @EndPattern)) = 0
SET @EndPattern = @EndPattern + 1
-- Find end of pattern range
WHILE PATINDEX('%abc% ''%', SUBSTRING(@sqltext, @initializor, @EndPattern)) > 0
AND @Len >= (@initializor + @EndPattern - 1)
SET @EndPattern = @EndPattern + 1
--Either at the end of the pattern or @Next + @EndPattern = @Len
SET @Result = @Result + '''1=1'''
SET @initializor = @initializor + @EndPattern - 1
END
SET @initializor = @initializor + 1;
END
SELECT @Result
介绍有关替换文本的更多信息。下面是一个很好的例子:
DECLARE @invalidColumns varchar(max) = replace('abc, xyz', ' ', '')
DECLARE @sqltext varchar(max) = ''
;WITH t1 as
(
SELECT '(*' pat, '(abc = ''sometext'')' txt, 'abc' col
UNION ALL SELECT 'OR *)' pat, 'OR (xyz = '' some more text'')' txt, 'xyz' col
UNION ALL SELECT 'OR *' pat, '(pqr = ''vb'')' txt, 'pqr' col
UNION ALL SELECT 'AND *' pat, 'abc != '' text ''' txt, 'abc' col
UNION ALL SELECT 'OR (*' pat, '(hht = ''asd asd'')' txt, 'hht' col
UNION ALL SELECT 'AND(*)' pat, 'xyz = ''''''' txt, 'xyz' col
), t2 as
(
SELECT t.c.value('.', 'VARCHAR(20)') col
FROM (
SELECT x = CAST('<t>' +
REPLACE(@invalidColumns, ',', '</t><t>') + '</t>' AS XML)
) a
CROSS APPLY x.nodes('/t') t(c)
)
SELECT @sqltext = @sqltext
+ replace(t1.pat, '*', case when t2.col is null then t1.txt else ' 1 = 1 ' end)
FROM t1
LEFT JOIN t2 on t1.col = t2.col
SELECT @sqltext
+1的努力,但这似乎是一个手动方式来取代列。我有大约100多个查询,它们的条件可能每天都在变化。我无法硬编码它们:@Zerotoinfinite您仍然可以使用我的方法,只需创建一个函数来拆分sqltext并返回一个具有相同3列的表。稍后我会带你去看的。我以后会调查的你有机会调查吗。。我试着这么做,却把代码弄乱了:@Zerotoinfinite你好,我一直病到现在。我已经看过你的代码了。我可以解决它。但解决方法是在文本中搜索。我永远不会为任何使用此流程的生产系统提供解决方案。因此,与其向您提供通心粉代码,我建议您找到另一种解决方案,我使用REPLACE、PATINDEX、STUFF和CHARINDEX实现了这一点。因为这是在我的客户端服务器上,所以我不能将查询粘贴到这里。但如果你愿意,我可以写逻辑。我衷心感谢你的帮助