首页 > 解决方案 > SQL - 文本函数不起作用(Reverse/Left/Substring/LTrim) - 很简单

问题描述

我在一个表上有一个文本字段,我试图在 select 语句中将其分解为两个单独的列。我发誓这在我上次使用它时对我有用,但现在它抛出一个错误“无效的长度参数”。我究竟做错了什么?

从单个列中拆分数据,如下所示:
“CORP - DIVISION - REGION - TEAM - SUPERVISOR”


分为两列,如:
SUPERVISOR | 团队


这是我发誓曾经工作过的东西,但现在已经不行了,我想不通!

Reverse(Left(Reverse(table.column),CHARINDEX(' ', Reverse(table.column))-1)) AS 'SUPERVISOR'
,LTRIM(LEFT(Substring(table.column,18,150),CHARINDEX(' - ', Substring(table.column,18,150))-1)) AS 'TEAM'
    

标签: sqlsql-servertext

解决方案


如果您有已知或最大数量的项目,请考虑使用一点 XML。也许更容易阅读和维护。

此外,如果您只对团队和主管感兴趣,则可以消除 Pos1、Pos2、Pos3。

例子

Declare @YourTable Table ([ID] varchar(50),[SomeCol] varchar(50))
Insert Into @YourTable Values 
 (1,'CORP - DIVISION - REGION - TEAM - SUPERVISOR')

Select A.ID
      ,B.*
 From  @YourTable A
 Cross Apply (
                Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(100)')))  
                      ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(100)')))
                      ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(100)')))
                      ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(100)')))
                      ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(100)')))
                      ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(100)')))
                      ,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(100)')))
                      ,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(100)')))
                      ,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(100)')))
                From  (Select Cast('<x>' + replace(SomeCol,'-','</x><x>')+'</x>' as xml) as xDim) as A 
             ) B

退货

ID  Pos1    Pos2        Pos3    Pos4    Pos5        Pos6    Pos7    Pos8    Pos9
1   CORP    DIVISION    REGION  TEAM    SUPERVISOR  NULL    NULL    NULL    NULL

编辑

如果您有非 XML 安全字符(<、>、、...),请使用

...
From  ( values (cast('<x>' + replace((Select replace(SomeCol,'-','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml)))  A(xDim)
...

推荐阅读