试试这个方法:
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的错误位置。但这会变得非常棘手......您必须逐个字符地遍历它,并计算左括号以找到相关的右括号。