2013-06-05 86 views
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 

现在我想一列,告诉我什么时候开,什么时候关,然后我可以设置最终替换。

+0

你有没有考虑命名参数,因为'SELECT * FROM Table WHERE Column = @ Value'? –

+0

只是一个例子..当然我使用@values,但我在我的查询中使用了一些xml,所以我需要使用' – Artemination

回答

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特殊字符,另一个用于放回功能,以及动态查询打印准备更新。

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) 

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

+0

@devart这个答案不起作用,有时会在运行时失败(Msg 9436,Level 16,State 1,Line 9 XML解析:第41行,第57个字符,结束标记与开始标记不匹配)或当我想执行结果时,因为打开的撇号必须用近撇号关闭;我强硬它可以只是把开放撇号,但它不起作用。 – Artemination

+0

请提供此问题的任何查询或示例。 – Devart

1

假设你的令牌表是令牌(令牌,ID,位置):

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 

位置列将具有启动报价和0用于封闭报价一个值1。其余的为NULL。

+0

呃...这可以工作,让我测试它.. – Artemination

+0

Thx你非常@rivarolle,赏金将在5小时内你的。 – Artemination