【问题标题】:Parse value from column and insert into new table in T-Sql从列中解析值并插入到 T-Sql 中的新表中
【发布时间】:2017-06-02 20:36:40
【问题描述】:

我有一列需要解析并插入到新表中。我已经非常接近获得所需的数据,但我似乎无法获得正确的语法。这是我需要解析的数据格式:

装箱单 #195,UID = Pkg-15094-195

装箱单 #112,UID = Pkg-41251-241

我只需要装箱单号。当然,它并不总是 2 个字符。

看起来比较简单,只是获取字符[#]和[,]的索引之差 然后从 [#] + 1 的索引开始,长度为 [,] - [#] - 1。正是这个额外的减法搞砸了我的语法:

SELECT substring(IMG_FILE_DESCRIPTION, 
    CHARINDEX('#', IMG_FILE_DESCRIPTION) + 1,
    CHARINDEX(',', IMG_FILE_DESCRIPTION) - CHARINDEX('#', IMG_FILE_DESCRIPTION)
)
AS PKL
FROM MASTER_SCAN_IMAGE
where IMG_SCT_PKEY = '21'

这行得通,但给了我太多。如果我尝试像这样添加另一个减法,则会出现语法错误:

SELECT substring(IMG_FILE_DESCRIPTION, 
    CHARINDEX('#', IMG_FILE_DESCRIPTION) + 1,
    (CHARINDEX(',', IMG_FILE_DESCRIPTION) - CHARINDEX('#', IMG_FILE_DESCRIPTION)) -1
)
AS PKL
FROM MASTER_SCAN_IMAGE
where IMG_SCT_PKEY = '21'

Msg 537, Level 16, State 2, Line 1 Invalid length parameter passed to the LEFT or SUBSTRING function.

所以我认为我应该将长度值包装到一个变量中,但它也会产生语法错误:

SELECT *
FROM MASTER_SCAN_IMAGE
DECLARE @length int = CHARINDEX(',', IMG_FILE_DESCRIPTION) - CHARINDEX('#', IMG_FILE_DESCRIPTION);

Msg 207, Level 16, State 1, Line 3
Invalid column name 'IMG_FILE_DESCRIPTION'.
Msg 207, Level 16, State 1, Line 3
Invalid column name 'IMG_FILE_DESCRIPTION'.

事实上,我似乎根本无法使用 CHARINDEX 来分配变量,我总是以同样的“无效列名”错误告终。

DECLARE @length bigint = CHARINDEX(',', IMG_FILE_DESCRIPTION);

Msg 207, Level 16, State 1, Line 3
Invalid column name 'IMG_FILE_DESCRIPTION'.

charindex 可以发送的两种返回类型 int 和 bigint 都是一样的。

【问题讨论】:

    标签: sql sql-server tsql parsing charindex


    【解决方案1】:

    使用这个:

    declare @column varchar(200) = 'Packing Slip #195, UID = Pkg-15094-195'
    
    
    select RIGHT(LEFT(@column, CHARINDEX(',', @column)-1), CHARINDEX('#', REVERSE(LEFT(@column, CHARINDEX(',', @column)-1)))-1) 
    

    运行代码here

    【讨论】:

    • 感谢您的快速回复。我的查询措辞很糟糕,并且没有显示我正在使用的完整列数据。我刚刚编辑了我的问题以反映我拥有的数据。不幸的是,我不能使用替换,因为数据的末尾总是有不同的数字。
    • @BrianGe 好的,我根据您添加的新信息更新了我的解决方案。使用链接查看并尝试。
    【解决方案2】:

    如果您对 TVF 持开放态度...请考虑以下事项。

    厌倦了提取字符串,我修改了一个解析函数来接受两个 non-like 分隔符。

    示例

    Declare @YourTable table (ID int,IMG_FILE_DESCRIPTION varchar(max))
    Insert Into @YourTable values 
     (1,'Packing Slip #195, UID = Pkg-15094-195')
    ,(2,'Packing Slip #112, UID = Pkg-41251-241')
    ,(3,'Packing Slip #222, UID = Pkg-41251-241 and Slip #999')  -- Notice two Packing Slips
    
    Select A.ID
          ,SlipNr = B.RetVal
     From  @YourTable A
     Cross Apply [dbo].[udf-Str-Extract](A.IMG_FILE_DESCRIPTION+',','Slip #',',') B
    

    退货

    ID  SlipNr
    1   195
    2   112
    3   222    <-- Notice multiple slips
    3   999    <-- Notice multiple slips
    

    有兴趣的 UDF

    CREATE FUNCTION [dbo].[udf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
    Returns Table 
    As
    Return (  
    
    with   cte1(N)   As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
           cte2(N)   As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
           cte3(N)   As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
           cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)
    
    Select RetSeq = Row_Number() over (Order By N)
          ,RetPos = N
          ,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1) 
     From  (
            Select *,RetVal = Substring(@String, N, L) 
             From  cte4
           ) A
     Where charindex(@Delimiter2,RetVal)>1
    
    )
    /*
    Max Length of String 1MM characters
    
    Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
    Select * From [dbo].[udf-Str-Extract] (@String,'[[',']]')
    */
    

    【讨论】:

      【解决方案3】:

      提取单据 ID,

         declare @column varchar(200) = 'Packing Slip #234234295, UID = Pkg-15094-195'
      
      
         select substring(@column,charindex('#',@column)+1,charindex(',',@column)-charindex('#',@column)-1)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多