SQL 服务器分词器

SQL server tokenizer

在 SQL 服务器中有没有办法创建一个函数来使以下字符串 'ABC,DEF,GHI' 输出值 3。

然后是否可以有一个函数允许您指定要输出的字符串的哪个标记。 所以输入将是您想要返回的字符串和令牌。 输入:('ABC,DEF,GHI', 2) 输出:DEF

第一题

declare @token varchar(20)
set @token = 'ABC,DEF,GHI'

select len(@token) - len(replace(@token ,',','')) + 1

这个函数完成了我在第 2 部分中需要的功能

CREATE FUNCTION dbo.itemAtIndexInASplitString( @stringToSplit VARCHAR(MAX), @delimiter VARCHAR(5), @indexToReturn int)
RETURNS
varchar(max)
AS
BEGIN
DECLARE @returnList TABLE ([ID] int, [Name] [nvarchar] (500))
DECLARE @name NVARCHAR(255)
DECLARE @pos INT
DECLARE @index INT
DECLARE @return_value varchar(max)
SET @index = 0
SET @return_value = null

WHILE CHARINDEX(@delimiter, @stringToSplit) > 0
BEGIN
SELECT @pos  = CHARINDEX(@delimiter, @stringToSplit)  
SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

INSERT INTO @returnList 
SELECT @index, @name

SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
SET @index = @index + 1 END

INSERT INTO @returnList
SELECT @index, @stringToSplit

SELECT @return_value = Name from @returnList where [ID] = @indexToReturn

RETURN @return_value
END
GO

这比您正在编写的代码短得多:

简短说明:通过将 , 替换为 </x><x>,我们只需在前面添加一个 <x>,在末尾添加一个 </x>,然后 - 瞧! - 我们有 XML.

XML 很容易索引。您必须使用 XQuery 函数 sql:variable() 将变量索引获取到 XPath 中。

DECLARE @string VARCHAR(MAX)='ABC,DEF,GHI'; 
DECLARE @index INT=2;

WITH AsXML AS 
(
    SELECT CAST('<x>' + REPLACE(@string,',','</x><x>') + '</x>' AS XML) AS Splitted
)
SELECT Splitted.value('/x[sql:variable("@index")][1]','varchar(max)')
FROM AsXML 

编辑:在这里您可以找到一个将此方法作为函数的完整示例。

CREATE FUNCTION dbo.Tokenizer
(
     @string VARCHAR(MAX)
    ,@index INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    DECLARE @RetVal VARCHAR(MAX);

    WITH AsXML AS 
    (
        SELECT CAST('<x>' + REPLACE(@string,',','</x><x>') + '</x>' AS XML) AS Splitted
    )
    SELECT @RetVal = Splitted.value('/x[sql:variable("@index")][1]','varchar(max)')
    FROM AsXML;

    RETURN @RetVal; 
END
GO

SELECT dbo.Tokenizer( 'ABC,DEF,GHI',2); --Returns "DEF"
GO

--Clean up
DROP FUNCTION dbo.Tokenizer;