如何获取SQL子串?

时间:2014-04-11 13:35:05

标签: sql sql-server tsql substring

我有一个包含以下值的列:

" AAAA \ BBBBBBBB \ CCC" (A,B,C部分长度不固定。)

我需要修剪\ CCC部分(如果存在),如果不存在则不管它。

例如:

AAA \ BBBBBB \ CCC - > AAA \ BBBBBB

AA \ BBBB - > AA \ BBBB

AA - > AA

对不起,我不够清楚,A,B,C部分不是字面上的ABC,它们可以是任何内容。

还应删除\ DDD \ EEEE(等)

4 个答案:

答案 0 :(得分:7)

虽然在纯T-SQL中确实有一种方法可以做到,但它可能不会那么清晰。

您可能需要考虑使用基于SQLCLR的用户定义函数(UDF)。有了这些,您将能够从Sql Server中(或)的强大功能和清晰度中受益。

只需将其设置为使您的函数将字符串作为参数接收,并将您想要的输出作为标量值返回。从那时起,您就可以像使用其他任何UDF一样使用该功能。通过这种方式,您的代码将更容易编写(以及之后的读取/维护)。

您的函数可以像这样(伪代码)一样容易编写:

public static string SpecialSubstring(string input)
{
    if (input == null) return null;

    var builder = new StringBuilder();
    var occurences = 0;

    for (i = 0; i < input.Length; i++;)
    {
        var current = input[i];

        if (current == '\') occurences += 1;
        if (occurences >= 2) break;

        builder.Append(current)
    }

    return builder.ToString();
}

然后,从T-SQL:

SELECT
    [owningschema].SpecialSubstring('AAA\BBBBBB\CCC'), -- returns 'AAA\BBBBBB'
    [owningschema].SpecialSubstring('AA\BBBB'),, -- returns 'AA\BBBB'
    [owningschema].SpecialSubstring('AA') -- returns 'AA'

此页面将为您提供入门所需的全部内容:

SQL Server Common Language Runtime Integration

答案 1 :(得分:3)

如果有两个或多个部分(由\分隔)

,这是一个删除最后一部分的解决方案
DECLARE @var VARCHAR(32) = 'AAAA\BBBBBBBB\CCC'

SELECT
    LEN(@var) - LEN(REPLACE(@var, '\', '')) -- Number of occurences of the character \

    , CHARINDEX('\', @var) -- Position of the first occurence
    , LEN(@var) - CHARINDEX('\', REVERSE(@var)) -- Position of the last occurence

    , CASE WHEN LEN(@var) - LEN(REPLACE(@var, '\', '')) > 1 AND CHARINDEX('\', @var) !=  LEN(@var) - CHARINDEX('\', REVERSE(@var))
        THEN SUBSTRING(@var, 1, LEN(@var) - CHARINDEX('\', REVERSE(@var)))
        ELSE @var
    END

答案 2 :(得分:3)

您可以使用PATINDEX来确定该字段是否包含3个(或更多)部分,然后使用一些字符串操作来删除最后一部分:

select case 
       when PATINDEX(field, '%\%\%') > 0 then 
           /* Chop off last part */
           LEFT(field, len(field) - charindex('\', reverse(field)))
       else
           field
       end case as choppedfield
  from my_table

答案 3 :(得分:1)

这就是我完成这项任务的方式:

declare @temp varchar(50), @temp2 varchar(15), @temp3 varchar(15)
set @temp = 'aaaa\bbbb\cccc\dddd'

IF (SELECT LEFT(@temp,CHARINDEX('\',@temp, CHARINDEX('\',@temp,0)+1))) != ''
    BEGIN
      SELECT LEFT(LEFT(@temp,CHARINDEX('\',@temp, CHARINDEX('\',@temp,0)+1)),LEN(LEFT(@temp,CHARINDEX('\',@temp, CHARINDEX('\',@temp,0)+1)))-1)
    END
ELSE
    BEGIN
      select @temp
    END

将其粘贴到查询窗口中,并为其提供具有不同@temp值的镜头。它会快速检查是否存在两个'\',并将其修剪到第二个'\'之前的字符位置。如果存在少于两个'\',它将只返回值本身。