我正在尝试将here中的顶级解决方案的最高代码变成SQL用户定义的函数。但是,当我尝试使用数字4的变量(在value函数的第一个参数中)时,它会倒钩。
这可行:
SELECT CAST('<x>' + REPLACE(@Input,',','</x><x>') + '</x>' AS XML).value('/x[4]','int')
...但是每当我尝试替换'/ x [4]'以使用变量代替4时,都会收到类似
的消息XML数据类型方法“值”的参数1必须为字符串文字。
到目前为止,这是我完整的用户定义功能...只需学习如何:
USE [DBName]
GO
CREATE FUNCTION fx_SegmentN
(@Input AS VARCHAR(100),
@Number AS VARCHAR(1))
RETURNS varchar(100)
AS
BEGIN
DECLARE @ValueStringLiteral varchar(14)
SET @ValueStringLiteral = '/x[' + @Number + ']'
RETURN '' +
CASE
WHEN @Number <1
THEN ('ERROR')
WHEN @Number = 1
THEN (LEFT(@Input, CHARINDEX('-', @Input, 1)-1))
WHEN @Number > 1
--THEN (SELECT CAST('<x>' + REPLACE(@Input,',','</x><x>') + '</x>' AS XML).value('/x[4]','int')) --THIS LINE WORKS
THEN (SELECT CAST('<x>' + REPLACE(@Input,',','</x><x>') + '</x>' AS XML).value('/x[' + @Number + ']','int')) --THIS ONE DOES NOT
ELSE
(NULL)
END + ''
END
答案 0 :(得分:1)
尝试一下:
CREATE FUNCTION fx_SegmentN
(
@Input AS VARCHAR(100)
,@Number AS VARCHAR(1)
) RETURNS varchar(100)
AS
BEGIN
DECLARE @XML XML;
DECLARE @value VARCHAR(100);
SET @XML = CAST('<x>' + REPLACE(@Input,',','</x><x>') + '</x>' AS XML);
WITH DataSource ([rowID], [rowValue]) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY T.c ASC)
,T.c.value('.', 'VARCHAR(100)')
FROM @XML.nodes('./x') T(c)
)
SELECT @value = [rowValue]
FROM DataSource
WHERE [rowID] = @Number;
RETURN @value;
END
GO
SELECT dbo.fx_SegmentN ('1a,2b,3c,4d,5e,6f,7g,8h', 3);
感兴趣
答案 1 :(得分:0)
这是一个丑陋的骇客,但有效:)
DECLARE @Query AS NVARCHAR(MAX) = N'SELECT CAST(''<x>'' + REPLACE(''' + @Input + ''' ,'','',''</x><x>'') + ''</x>'' AS XML).value(''/x['+ @Number + ']'',''int'')'
EXEC sp_executesql @Query
答案 2 :(得分:0)
实际上很简单:
declare @x xml = N'
<x>2345</x>
<x>vsaaef</x>
<x>fxcfs</x>
<x>Number 4</x>
<x>vxcv</x>
<x>111</x>
';
declare @Position int = 4;
select t.c.value('./text()[1]', 'nvarchar(100)')
from @x.nodes('/x[position() = sql:variable("@Position")]') t(c);