如何生成动态查询的更新查询(自动)?

时间:2013-06-05 19:57:45

标签: sql sql-server sql-server-2008 tsql formatting

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

例如:

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

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

3 个答案:

答案 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,'&#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)

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

答案 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。