2

我将一些查询存储在表列中,以便稍后通过一些参数执行它们。但是由于特殊字符,将查询格式化为更新语句真的很烦人。

例如:

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

现在我想要一列告诉我何时打开和何时关闭,然后我可以设置最终替换。

4

3 回答 3

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

这个工作,只需要一个用于清理 XML 特殊字符的功能和另一个用于放回的功能,并且打印动态查询以准备更新。

于 2013-06-13T15:05:40.977 回答
1

我认为没有必要用'''+'来替换撇号来打开和'+'''来关闭,我做了一些探测,你可以执行一个查询,用相同的..例如'''+' 表示打开,'''+' 表示关闭。

所以查询将是:

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,'&#x20;','')
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)

它适用于非常简单的查询,但对于更长和复杂的查询它不起作用..

于 2013-06-05T22:05:07.263 回答
1

假设您的令牌表是 Tokens(Token, Id, Position):

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。

于 2013-06-12T21:20:36.110 回答