【问题标题】:Update UDF names stored in table to add parameter value更新存储在表中的 UDF 名称以添加参数值
【发布时间】:2018-01-25 08:17:18
【问题描述】:

我有数千个 UDF 名称存储在表中,并在需要的地方动态执行。问题是我在函数dbo.GetStockPrice(6544,1) 中添加了一个新参数unit,所以我现在需要再发送一个参数值1,但它可以是任何值,并且所有数据都应更改为dbo.GetStockPrice(6544,1,1)存在dbo.GetStockPrice 的行。所以我正在寻找一次更新这些的查询。

样本数据

DECLARE @table AS TABLE(id INT, UDF VARCHAR(1000))
INSERT INTO @table VALUES
(7774,'dbo.GetStockPrice(1211,1)*dbo.GetStockPrice(1211,1)'),
(7775,'dbo.GetStockPrice(232,1)'),
(7778,'dbo.GetStockPrice(6456,1)'),
(7780,'dbo.GetStockPrice(34,1)'),
(7784,'dbo.FNACondition(dbo.FNAMargin(1,NULL,0), 0, dbo.GetStockPrice(654,1)+1)'),
(7786,'dbo.GetStockPrice(9876,1)'),
(7906,'dbo.GetStockPrice(5565,1)'),
(7911,'dbo.GetStockPrice(7886,1)'),
(7912,'dbo.GetStockPrice(87,1)'),
(8403,'dbo.PriceValue(479,NULL,NULL)*dbo.GetStockPrice(6544,1)+dbo.FNAMargin(1,NULL,0)')

预期输出:

7774    dbo.GetStockPrice(1211,1,1)*dbo.GetStockPrice(1211,1,1)
7775    dbo.GetStockPrice(232,1,1)
so on......

我仍在尝试REPLACESUBSTRING,但无法提出任何解决方案。在行中的长度和位置不同时遇到困难。

寻求帮助!提前谢谢你:)

【问题讨论】:

    标签: sql sql-server sql-server-2012 sql-update


    【解决方案1】:

    试试这个方法:

    DECLARE @table AS TABLE(id INT, UDF VARCHAR(1000))
    INSERT INTO @table VALUES
    (7774,'dbo.GetStockPrice(1211,1)*dbo.GetStockPrice(1211,1)'),
    (7775,'dbo.GetStockPrice(232,1)'),
    (7778,'dbo.GetStockPrice(6456,1)'),
    (7780,'dbo.GetStockPrice(34,1)'),
    (7784,'dbo.FNACondition(dbo.FNAMargin(1,NULL,0), 0, dbo.GetStockPrice(654,1)+1)'),
    (7786,'dbo.GetStockPrice(9876,1)'),
    (7906,'dbo.GetStockPrice(5565,1)'),
    (7911,'dbo.GetStockPrice(7886,1)'),
    (7912,'dbo.GetStockPrice(87,1)'),
    (7913,'dbo.Blah(87,1)'),
    (8403,'dbo.PriceValue(479,NULL,NULL)*dbo.GetStockPrice(6544,1)+dbo.FNAMargin(1,NULL,0)');
    

    --查询

    WITH SplitToParts AS
    (
        SELECT t.*
              ,A.parted
              ,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS PartNr
              ,B.part.value('text()[1]','nvarchar(max)') AS Part
        FROM @table AS t
        CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT t.UDF AS [*] FOR XML PATH('')),'dbo.GetStockPrice(','</x><x>$$$FoundIt$$$</x><x>') + '</x>' AS XML)) AS A(parted)
        CROSS APPLY parted.nodes(N'/x') AS B(part)
        WHERE UDF LIKE '%dbo.GetStockPrice(%'
    )
    ,modified AS
    (
        SELECT *
              ,CASE WHEN LAG(stp.Part) OVER(PARTITION BY id ORDER BY PartNr)='$$$FoundIt$$$' THEN STUFF(stp.Part,CHARINDEX(')',stp.Part),0,',1') ELSE stp.Part END AS Added
        FROM SplitToParts AS stp
    )
    SELECT t2.*
          ,(
            SELECT REPLACE(m.added,'$$$FoundIt$$$','dbo.GetStockPrice(')
            FROM modified AS m 
            WHERE m.id=t2.id 
            ORDER BY m.PartNr
            FOR XML PATH(''),TYPE
           ).value('.','nvarchar(max)')
    FROM @table AS t2
    WHERE UDF LIKE '%dbo.GetStockPrice(%';
    

    结果

    7774    dbo.GetStockPrice(1211,1,1)*dbo.GetStockPrice(1211,1,1)
    7775    dbo.GetStockPrice(232,1,1)
    7778    dbo.GetStockPrice(6456,1,1)
    7780    dbo.GetStockPrice(34,1,1)
    7784    dbo.FNACondition(dbo.FNAMargin(1,NULL,0), 0, dbo.GetStockPrice(654,1,1)+1)
    7786    dbo.GetStockPrice(9876,1,1)
    7906    dbo.GetStockPrice(5565,1,1)
    7911    dbo.GetStockPrice(7886,1,1)
    7912    dbo.GetStockPrice(87,1,1)
    8403    dbo.PriceValue(479,NULL,NULL)*dbo.GetStockPrice(6544,1,1)+dbo.FNAMargin(1,NULL,0)
    

    一些解释:字符串将使用您的函数名称作为拆分器进行分割。很高兴你用[sql-server-2012] 标记了这个,所以你可以使用LAG()。这将测试前一个元素,如果它是$$$FoundIt$$$。在这种情况下,第一个右括号将获得一个额外的,1。剩下的就是重新连接。

    注意:如果您的调用可能包含计算值,例如

    dbo.GetStockPrice(1211,(1+2))
    or
    dbo.GetStockPrice(dbo.SomeOtherFunc(1),1)
    

    ...第一个右括号是插入,1的错误位置。但这会变得非常棘手......您必须逐个字符地遍历它,并计算左括号以找到相关的右括号。

    【讨论】:

    • 不幸的是,在尝试使用我的真实表时收到此错误"XML parsing: line 1, character 40, illegal qualified name character"。仅供参考,还有许多其他行也不包括要替换的此功能。这是问题吗?
    • @Susang,等一下。我没想到这里有非法的 XML 字符。尽快更新...
    • @Susang,你可以再试一次。
    • @Susang 一个提示:您应该通过添加 WHERE UDF LIKE '%dbo.GetStockPrice(%' 将其过滤到包含此 UDF 的行。这必须在第一个 cte 在最后一个 SELECT 中完成
    猜你喜欢
    • 2012-04-24
    • 2011-09-17
    • 2018-07-09
    • 2012-02-05
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-26
    相关资源
    最近更新 更多