使用正则表达式从字符串中提取值并存储为新的列值

时间:2018-12-26 21:50:16

标签: sql sql-server sql-like

我有一个SQL Server存储过程,在其中输入了值'Mat',该值可能包含在值的末尾:(DAY),(MONTH),(HR)

如果此值存在,我希望能够使用正则表达式或更简单的其他方式将其拉出并存储为另一列。

我目前已经尝试在SQL Server中使用LIKE操作作为新列,但是我不认为SQL Server允许这样做。

这是我当前的存储过程:

ALTER PROCEDURE [dbo].[UpdateMaterial_Get_MaterialValues_ByMaterialName]
--UpdateMaterial_Get_MaterialValues_ByMaterialName '2 Inch Discharge Hose (DAY)'
--UpdateMaterial_Get_MaterialValues_ByMaterialName '2 Step Hydroseeding'
    @MAT NVARCHAR(255)
AS
BEGIN
    SELECT 
        DEFAULTS.Mat, DEFAULTS.Region, DEFAULTS.MatUnit, DEFAULTS.MatWidth,
        TYPEDESC.TypeDesc AS MatType,
        @MAT LIKE '(\S+)' AS EquipmentType
    FROM 
        tbl_MaterialDefaults DEFAULTS 
    RIGHT JOIN
        tbl_Client_List_Type_Desc TYPEDESC ON TYPEDESC.Num = DEFAULTS.MatID
    WHERE 
        Mat = @MAT
END

当前在尝试执行ALTER时出现错误:

  

关键字“ like”附近的语法不正确。

您可以在代码中看到两个示例,它们分别是@MAT值。这是我对这两个的期望:

对于@MAT值“ 2英寸排放软管(天)”

Mat                            Region                       MatUnit   MatWidth  MatType   EquipmentType      
2 Inch Discharge Hose (DAY)    Standard Sacramento          ACRE      1.00      MATERIAL  (DAY) 

对于@MAT值“ 2步水力种植”

Mat                            Region                       MatUnit   MatWidth  MatType   EquipmentType
2 Step Hydroseeding            Standard Sacramento          ACRE      1.00      MATERIAL

1 个答案:

答案 0 :(得分:3)

您可以尝试以下方法:

在您的存储过程中:

DECLARE @ExprStart int = -1,
        @ExprEnd int = -1,
        @EquipmentType varchar(100) = NULL

IF @Mat LIKE '%(%)%' BEGIN
  SET @ExprStart = PATINDEX('%)%', REVERSE(@Mat)),
      @ExprEnd = PATINDEX('%(%', REVERSE(@Mat))
  SET @EquipmentType = REVERSE(SUBSTRING( @Mat, @ExprStart, @ExprEnd - @ExprStart + 1 ))
END

SELECT 
    DEFAULTS.Mat, 
    DEFAULTS.Region, 
    DEFAULTS.MatUnit, 
    DEFAULTS.MatWidth,
    TYPEDESC.TypeDesc AS MatType,
    @EquipmentType AS EquipmentType
 FROM 
    tbl_MaterialDefaults DEFAULTS 
 RIGHT JOIN
    tbl_Client_List_Type_Desc TYPEDESC ON TYPEDESC.Num = DEFAULTS.MatID
 WHERE 
    Mat = @MAT

只有在-且在末尾的“设备类型”前没有任何括号时,此方法才有效。但是我相信你是这样。

编辑后添加:我看到您已经说过早先的括号可能会发生。我已经调整了代码以适应这一点。我的新版本假定我们从@Mat中提取了最后的括号。

编辑以添加一个甚至更简单的版本:如果您只需要担心(HR)(DAY)(MONTH),我们可以这样做:

 -- We don't need any of those declarations or PATINDEXes.
 SELECT 
     DEFAULTS.Mat, 
     DEFAULTS.Region, 
     DEFAULTS.MatUnit, 
     DEFAULTS.MatWidth,
     TYPEDESC.TypeDesc AS MatType,
     CASE WHEN RTRIM(@Mat) LIKE '%(HR)'
          THEN '(HR)'
          WHEN RTRIM(@Mat) LIKE '%(DAY)'
          THNE '(DAY)'
          WHEN RTRIM(@Mat) LIKE '%(MONTH)'
          THEN '(MONTH)'
     END AS EquipmentType
 FROM etc.

但是,这仅在您只有那些字符串的情况下才有效。我还假设它们总是会在结尾,并且只有空格(可以用RTRIM()删除)可以在它们之后。