从 T-SQL 分隔字符串解析整数值的更好方法

发布于 11-26 12:29 字数 1312 浏览 3 评论 0原文

我有一个 SQLServer2008 R2 存储过程,其中包含用于从分隔字符串中解析出整数的算法。

下面是我为循环分隔字符串并提取分隔字符串中可能存在的任何数字而编写的 SQL 代码示例:

-- Create a delimited list for testing
DECLARE @NumericList nvarchar(MAX) = N'1, 33,44 ,55, foo ,666,77 77,8,bar,9,10'

-- Declare the delimiter
DECLARE @ListDelimiter VARCHAR(1) = ','

-- Remove white space from the list
SET @NumericList = REPLACE(@NumericList, ' ','');

-- Var that will hold the value of the delimited item during the while-loop
DECLARE @NumberInScope VARCHAR(MAX)

WHILE(LEN(@NumericList) > 0)
BEGIN
    -- Get the value to the left of the first delimiter.
    IF(CHARINDEX(@ListDelimiter, @NumericList) > 0)
        SET @NumberInScope = LEFT(@NumericList, CHARINDEX(@ListDelimiter, @NumericList))
    ELSE
        SET @NumberInScope = @NumericList   

    -- Remove the @NumberInScope value from the @NumericList
    SET @NumericList = RIGHT(@NumericList, LEN(@NumericList) - LEN(@NumberInScope))

    -- Remove the delimiter from the @NumberInScope
    SET @NumberInScope = REPLACE(@NumberInScope,@ListDelimiter,'')

    -- Print only the integer values
    IF(ISNUMERIC(@NumberInScope) = 1)
    BEGIN
        PRINT @NumberInScope
    END 
END

上面的代码工作正常,但在查看代码后,在我看来,必须有更多做同一件事的简洁方法。换句话说,是否有任何我忽略的字符串函数(或者可能是任何新的 R2 函数)可以实现,从而缩小代码并希望更易于阅读?

I have a SQLServer2008 R2 Stored Procedure that contains an algorithm for parsing out integers from a delimited string.

Here's an example of the SQL code that I made for looping through the delimited string and extracting any numbers that may exist in the delimited string:

-- Create a delimited list for testing
DECLARE @NumericList nvarchar(MAX) = N'1, 33,44 ,55, foo ,666,77 77,8,bar,9,10'

-- Declare the delimiter
DECLARE @ListDelimiter VARCHAR(1) = ','

-- Remove white space from the list
SET @NumericList = REPLACE(@NumericList, ' ','');

-- Var that will hold the value of the delimited item during the while-loop
DECLARE @NumberInScope VARCHAR(MAX)

WHILE(LEN(@NumericList) > 0)
BEGIN
    -- Get the value to the left of the first delimiter.
    IF(CHARINDEX(@ListDelimiter, @NumericList) > 0)
        SET @NumberInScope = LEFT(@NumericList, CHARINDEX(@ListDelimiter, @NumericList))
    ELSE
        SET @NumberInScope = @NumericList   

    -- Remove the @NumberInScope value from the @NumericList
    SET @NumericList = RIGHT(@NumericList, LEN(@NumericList) - LEN(@NumberInScope))

    -- Remove the delimiter from the @NumberInScope
    SET @NumberInScope = REPLACE(@NumberInScope,@ListDelimiter,'')

    -- Print only the integer values
    IF(ISNUMERIC(@NumberInScope) = 1)
    BEGIN
        PRINT @NumberInScope
    END 
END

The code above works fine, but after reviewing the code it seems to me that there's got to be a more concise way of doing the same thing. In other words, is there any string functions (or any new R2 function, maybe) that I'm overlooking that I can implement that would shrink the code and, hopefully, be easier to read?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ペ泪落弦音2024-12-03 12:29:19

权威文章是“SQL Server 2005 中的数组和列表”以及其他”

这里显示了几种分割 CSV 的方法:CLR、数字表、WHILE 循环

The definitive article is "Arrays and Lists in SQL Server 2005 and Beyond"

Here several methods are shown for splitting CSVs: CLR, Numbers table, WHILE loops

究竟谁懂我的在乎2024-12-03 12:29:19

这是代码,您还可以创建一个“split”函数并使用它

DECLARE @NumericList nvarchar(max) = N'1, 33,44 ,55, foo ,666,77 77,8,bar,9,10'

;WITH cte as (
SELECT CAST(1 as bigint) p1,  CHARINDEX(',', @NumericList+',') p2, 
CAST(null as Nvarchar(max)) NumberInScope 
UNION ALL
SELECT p2 + 1, CHARINDEX(',',@NumericList+',', p2 + 1), 
SUBSTRING(@NumericList, p1, p2-p1) 
FROM cte WHERE p2>0
)
SELECT NumberInScope from cte WHERE isnumeric(NumberInScope) > 0
OPTION (MAXRECURSION 0)

Here is the code, you can also create a 'split' function and use that

DECLARE @NumericList nvarchar(max) = N'1, 33,44 ,55, foo ,666,77 77,8,bar,9,10'

;WITH cte as (
SELECT CAST(1 as bigint) p1,  CHARINDEX(',', @NumericList+',') p2, 
CAST(null as Nvarchar(max)) NumberInScope 
UNION ALL
SELECT p2 + 1, CHARINDEX(',',@NumericList+',', p2 + 1), 
SUBSTRING(@NumericList, p1, p2-p1) 
FROM cte WHERE p2>0
)
SELECT NumberInScope from cte WHERE isnumeric(NumberInScope) > 0
OPTION (MAXRECURSION 0)
烟若柳尘2024-12-03 12:29:19

从 MSSql Server 2016 开始,引入了一个新关键字 STRING_SPLIT 来执行所需的操作。

SELECT STRING_SPLIT ( string , separator )

请参阅 https://msdn.microsoft.com/en-us/library/mt684588。 ASPX

From MSSql Server 2016, there is a new keyword introduced STRING_SPLIT to do the desired operation.

SELECT STRING_SPLIT ( string , separator )

Refer https://msdn.microsoft.com/en-us/library/mt684588.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文