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

Sql 如何生成动态查询的更新查询(自动)?,sql,sql-server,sql-server-2008,tsql,formatting,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

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

例如:

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)

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

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

因此,问题是:

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
然后我复制到一个变量中并执行

DECLARE @VAR VARCHAR(500)
SET @VAR='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'''+' '
EXEC(@VAR)

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

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

因此,问题是:

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
然后我复制到一个变量中并执行

DECLARE @VAR VARCHAR(500)
SET @VAR='SELECT * FROM QUERIES WHERE QUE_NOMBRE='''+'PRUEBA 1'''+' '
EXEC(@VAR)

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

假设您的令牌表是TokensToken,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表示结束报价。其余为空。

假设您的令牌表是TokensToken,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表示结束报价。其余为空。

调整@rivarle给出的解决方案

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特殊字符的函数和另一个放回的函数,动态查询就可以打印出来以备更新。

采用@rivarle给出的解决方案

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特殊字符的函数和另一个用于放回的函数,动态查询就可以打印出来进行更新。

您是否考虑过命名参数,因为SELECT*FROM Table WHERE Column=@Value?只是一个例子。。当然,我使用的是@values,但我在查询中使用了一些xml,所以我需要使用“您是否考虑过命名参数,因为SELECT*FROM Table WHERE Column=@Value?”只是一个例子。。当然,我使用了@values,但我在查询中使用了一些xml,所以我需要使用@devart。这个答案不起作用,有时在运行Msg 9436,16级,状态1,第9行xml解析时失败:第41行,字符57,结束标记与开始标记不匹配,或者当我想执行结果时,因为打开的撇号必须通过关闭撇号关闭;我知道,只要在开头加上撇号就行了,但不是这样。请提供任何有关此问题的查询或示例。@devart此答案不起作用,有时仅在运行Msg 9436,级别16,状态1,第9行XML解析时失败:第41行,字符57,结束标记与开始标记不匹配,或者当我想要执行结果时,因为打开的撇号必须通过关闭撇号关闭;我很难只在开头加上撇号就行了,但不是这样。请提供任何关于这个问题的疑问或例子。