我将一些查询存储在表列中,以便稍后传递一些参数来执行它们。 但由于特殊字符,将查询格式化为更新句子真的很烦人。
例如:
SELECT * FROM MOUNTAINS WHERE MON_NAME='PALMA' AND MON_DESC LIKE '%TRANVULCANIA%'
然后我只需要udpate查询字符串:
UPDATE QUERIES
SET QUE_SEL='SELECT * FROM MOUNTAINS WHERE MON_NAME='''+'PALMA'+''' AND MON_DESC LIKE '''+'%TRANVULCANIA%'+''' '
WHERE QUE_ID=1
您可以看到第一个'必须替换'''+',但隔壁'必须替换为 '+' ''
这是我正在处理的查询:
DECLARE @QUERY VARCHAR(MAX)
SELECT @QUERY='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'+''' '
SELECT
t.r.value('.', 'varchar(255)') AS token
, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS id
FROM (
SELECT myxml = CAST('<t>' + REPLACE(@QUERY, '''', '</t><t>''</t><t>') + '</t>' AS XML)
) p
CROSS APPLY myxml.nodes('/t') t(r)
这是结果:
token id
-------------------------------------------------- --------------------
SELECT * FROM QUERIES WHERE QUE_NOMBRE= 1
' 2
PRUEBA 1 3
' 4
5
现在我想要一个列,告诉我何时打开以及何时关闭,然后我可以设置最终替换。
答案 0 :(得分:2)
调整@rivarolle提供的解决方案
DECLARE @QUERY VARCHAR(MAX)
DECLARE @FORMATTED varchar(max)
SELECT @QUERY='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'+''''
;WITH TOKENS AS(
SELECT
t.r.value('.', 'varchar(MAX)') AS token
, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Id
FROM (
SELECT myxml = CAST('<t>' + REPLACE(@QUERY, '''', '</t><t>''</t><t>') + '</t>' AS XML)
) p
CROSS APPLY myxml.nodes('/t') t(r)
)
,
Tokens2 as (
SELECT
TOKENS.token as token
,quotes.row%2 as tipoapostrofe
from Tokens
left join (select row_number() over( order by Id asc) as row, a.* FROM (SELECT * from Tokens) a where Token = '''') quotes
on quotes.Id = Tokens.Id
)
SELECT @FORMATTED = STUFF((
SELECT ' ' + REPLACE(token,'''',CASE tipoapostrofe WHEN 1 THEN '''''''+''' WHEN 0 THEN '''+''''''' ELSE '' END) AS [text()]
FROM Tokens2
FOR XML PATH('')
), 1, 1, '')
print @FORMATTED
这个Works,只需要一个用于清理XML特殊字符的函数和另一个用于放回的函数,并且可以打印动态查询以备更新。
答案 1 :(得分:1)
我认为没有必要用'&#39;&#39; +&#39;替换撇号。打开&#39; +&#39;&#39;&#39;关闭,我做了一些探测,你可以执行一个查询,你用相同的替换开始和结束撇号...例如&#39;&#39;&#39; +&#39;对于开放和&#39;&#39; +&#39;关闭。
所以查询将是:
DECLARE @QUERY VARCHAR(MAX)
DECLARE @FORMATTED varchar(max)
SELECT @QUERY='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'+''''
SELECT @FORMATTED= STUFF((
SELECT ' ' +
(SELECT
CASE
WHEN t.r.value('.', 'varchar(250)')='''' THEN REPLACE(t.r.value('.', 'varchar(250)'), '''','''''''+''')
ELSE t.r.value('.', 'varchar(250)')
END
) AS [text()]
-- , ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS id
FROM (
SELECT myxml = CAST('<t>' + REPLACE(@QUERY, '''', '</t><t>''</t><t>') + '</t>' AS XML)
) p
CROSS APPLY myxml.nodes('/t') t(r)
FOR XML PATH('')
), 1, 1, '')
SET @FORMATTED=REPLACE(@FORMATTED,' ','')
PRINT @FORMATTED
然后我得到:
SELECT * FROM QUERIES WHERE QUE_NOMBRE= '''+' PRUEBA 1 '''+'
然后我复制到变量并执行
DECLARE @VAR VARCHAR(500)
SET @VAR='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'''+' '
EXEC(@VAR)
它适用于非常简单的查询,但查询较长且复杂,但它不起作用..
答案 2 :(得分:1)
假设您的令牌表是令牌(令牌,标识,位置):
update Tokens
set position = quotes.row%2
from Tokens
left join (select row_number() over( order by Id asc) as row, a.* FROM (SELECT * from Tokens) a where Token = '''') quotes
on quotes.Id = Tokens.Id
对于开始报价,位置列的值为1,关闭报价的值为0。其余为NULL。