【问题标题】:Get substring between "\" where multiple "\"获取“\”之间的子字符串,其中多个“\”
【发布时间】:2013-11-18 01:46:06
【问题描述】:

找到这个解决方案在斜杠()字符后获取子字符串

DECLARE @st1 varchar(10)
SET @st1 = 'MYTEST\aftercompare'
SELECT @st1
,SUBSTRING(@st1, CHARINDEX('\', @st1) + 1, LEN(@st1))

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/5c3a5e2c-54fc-43dd-b12c-1a1f6784d7d8/tsql-get-substring-after-slash-character

但是有没有办法在第二个斜杠甚至更多之后获取子字符串?

DECLARE @st1 varchar(50)
--Added more slashes
SET @st1 = 'MYTEST\aftercompare\slash2\slash3\slash4'
SELECT @st1
--This part would need some work
--,SUBSTRING(@st1, CHARINDEX('\', @st1) + 1, LEN(@st1))

并且只获取斜线之间的子字符串。

值:[1] "aftercompare" - [2] "slash2" - [3] "slash3" - [4] "slash4"

【问题讨论】:

  • 为什么要在 T-SQL 中这样做?在这方面,您的客户端语言会更加高效。
  • @AaronBertrand 完全同意 +1
  • 使用列信息如下格式的表格:“8:00-10:00\男\4分部\Room1”“10:00-12:00\女\8分部\Room2" 并且无法访问原始插入。并希望为每个场景创建维度。

标签: sql tsql sql-server-2008-r2 substring trim


【解决方案1】:

如果您真的想在 TSQL 中执行此操作,请参见下文。

I've gamed SQL Fiddle into showing it working,忽略小提琴中的 CROSS JOIN,他们只是绕过 SQLFiddle 对 DECLARE 的限制。

DECLARE @s varchar(8000);
DECLARE @sep char;

SET @s = 'MYTEST\aftercompare\slash2\slash3\slash4';
SET @sep = '\';

WITH [splits] AS (
    SELECT
        0 [index],
        CHARINDEX(@sep, @s) [pos],
        0 [lastPos]
    UNION ALL
    SELECT
        [index] + 1,
        CHARINDEX(@sep, @s, [pos] + 1),
        [pos]
    FROM [splits]
    WHERE
        [pos] > 0)
SELECT
    [index],
    SUBSTRING(
        @s,
        [lastPos] + 1,
        CASE WHEN [pos] = 0
            THEN 8000
            ELSE [pos] - [lastPos] - 1
        END) [value]
FROM [splits];

给出结果

INDEX   VALUE 
0       MYTEST 
1       aftercompare 
2       slash2 
3       slash3 
4       slash4 

在我无法使用表值参数的 SQL 2005 数据库中,我创建了 .Net CLR Split 来组成正常的 .Net Split 函数。使用正确的工具,字符串操作更简单、更快捷。


如果需要,here is a NVarChar(MAX) version.

DECLARE @s nvarchar(max);
DECLARE @sep nchar;

SET @s = N'MYTEST\aftercompare\slash2\slash3\slash4';
SET @sep = N'\';

WITH [splits] AS (
    SELECT
        CAST(0 AS bigint) [index],
        CHARINDEX(@sep, @s) [pos],
        CAST(0 AS bigint) [lastPos]
    UNION ALL
    SELECT
        [index] + 1,
        CHARINDEX(@sep, @s, [pos] + 1),
        [pos]
    FROM [splits]
    WHERE
        [pos] > 0)
SELECT
    [index],
    SUBSTRING(
        @s,
        [lastPos] + 1,
        CASE WHEN [pos] = 0
            THEN 2147483647
            ELSE [pos] - [lastPos] - 1
        END) value
FROM [splits];

【讨论】:

  • 不错的解决方案,现在我只需要将它更新到我的表格中。谢谢!
【解决方案2】:

您可以使用此表值函数返回一个表,其中包含每个拆分结果的单独行:

    ALTER FUNCTION [dbo].[Split]
    (
        @sString nvarchar(2000),
        @cDelimiter nchar(1)
    )
    RETURNS 
    @TblSplits TABLE 
    (
        SplitText nvarchar(2000)
    )
    AS
    BEGIN
        if @sString is null return
        declare @iStart int,
                @iPos int
        if substring( @sString, 1, 1 ) = @cDelimiter 
        begin
            set @iStart = 2
            insert into @TblSplits
            values( null )
        end
        else 
            set @iStart = 1
        while 1=1
        begin
            set @iPos = charindex( @cDelimiter, @sString, @iStart )
            if @iPos = 0
                set @iPos = len( @sString )+1
            if @iPos - @iStart > 0          
                insert into @TblSplits
                values  ( substring( @sString, @iStart, @iPos-@iStart ))
            else
                insert into @TblSplits
                values( null )
            set @iStart = @iPos+1
            if @iStart > len( @sString ) 
                break
        end

        DELETE @TblSplits WHERE SplitText IS NULL;

        RETURN
    END

你可以这样调用函数:

        DECLARE @st1 nvarchar(50)
        --Added more slashes
        SET @st1 = 'MYTEST\aftercompare\slash2\slash3\slash4'
        SELECT @st1

        SELECT * from dbo.Split(@st1,N'\');

【讨论】:

    猜你喜欢
    • 2021-03-16
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 2022-10-07
    • 2014-04-02
    相关资源
    最近更新 更多