【问题标题】:How to escape a ' character in the SQL update with replace function?如何使用替换功能在 SQL 更新中转义 ' 字符?
【发布时间】:2018-09-13 21:06:41
【问题描述】:

我的表中有这些数据

  PartNumber  | IsValid
 BC.QT.000002'     0
'CP.AC.'000010'    0
'CP.AL.000013      0
'CP.A'L.000016'    0
'CP.AL.000024'     0

我想要做的是从 PartNumber 值中删除 ',但如果该引号 ' 在值的中间,例如 'CP.AC.'000010' 我只想删除后缀和前缀 '

想要的结果应该是这样的

 PartNumber | IsValid
BC.QT.000002     0
CP.AC.'000010    0
CP.AL.000013     0
CP.A'L.000016    0
CP.AL.000024     0

这是我尝试过的 SQL

CREATE TABLE #Temp(
   PartNumber          VARCHAR(20)
  ,Test                VARCHAR(30)
);
INSERT INTO #Temp(PartNumber,Test) VALUES ('''test''',NULL);
INSERT INTO #Temp(PartNumber,Test) VALUES ('''te''st2''',NULL);
INSERT INTO #Temp(PartNumber,Test) VALUES ('''test3''',NULL);
INSERT INTO #Temp(PartNumber,Test) VALUES ('''tes''t5''',NULL);

Update #Temp
set partNumber = REPLACE(PartNumber,'''','')
Where len(partNumber ) - len(replace(partNumber , '''', '')) = 2 

这不起作用,因为它完全忽略了值中有 3 ' 的值,或者如果有 2 ' 但其中一个在中间。

如果存在前缀/后缀 ',我需要一种方法来删除它们。

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008


    【解决方案1】:

    即使内容可能包含空格也是安全的另一种选择是用例:

    UPDATE #Temp
    SET partNumber = CASE WHEN partNumber LIKE '''%''' THEN -- starts and ends with an apostrophe
                        SUBSTRING(partNumber, 2, LEN(partNumber)-2) 
                     WHEN partNumber LIKE '''%' THEN -- starts with an apostrophe
                         RIGHT(partNumber, LEN(partNumber)-1) 
                     WHEN partNumber LIKE '%''' THEN -- ends with an apostrophe
                         LEFT(partNumber, LEN(partNumber)-1) 
                     ELSE  
                         partNumber 
                     END
    

    除了比 Gordon 的答案更麻烦之外,缺点是它只会删除第一个和最后一个撇号 - 如果您有像 ''asdf' 这样的值,它将被更新为 'asdf

    【讨论】:

      【解决方案2】:

      假设您在PartNumber 中没有空格,您可以使用:

      replace(ltrim(rtrim(replace(partnumber, '''', ' '))), ' ', '''')
      

      这处理使用修剪函数从字符串的开头和结尾删除字符。唉,这些只适用于空间;所以需要replace才能把引号变成空格。

      【讨论】:

        【解决方案3】:

        这将删除左右两边的所有 '。 例如:''sample'' 将是示例

        已编辑:修复 PartNumber 仅包含 '

        UPDATE [T]
        SET  [PartNumber] =
            CASE
                WHEN [X].[Left] IS NULL OR [X].[Right] IS NULL
                    THEN ''
                ELSE
                    SUBSTRING
                    (
                         LEFT([T].[PartNumber], LEN([T].[PartNumber]) - ISNULL([X].[Right] - 1, 0)) -- Remove all the ' from the right
                        ,ISNULL([X].[Left], 1) -- remove all the ' from the left
                        ,LEN([T].[PartNumber])
                    )
            END
        FROM #temp AS [T]
        CROSS APPLY
        (
            SELECT
                 [Left] = NULLIF(PATINDEX('%[^'']%', [T].[PartNumber]), 0) -- get the first position of a character distinct of ' (from the left)
                ,[Right] = NULLIF(PATINDEX('%[^'']%', REVERSE([T].[PartNumber])), 0) -- get the last position of a character distinct of ' (from the right)
        ) AS [X];
        

        【讨论】:

        • 如果 PartNumber 只包含撇号,这将失败。
        【解决方案4】:

        另一种方法是使用Left()Right() 来嗅探第一个和最后一个字符,然后提取适当的子字符串

        注意:如果 PartNumber 由单个撇号组成,则此操作失败,即第一个和最后一个字符一个撇号。

        -- Sample data:
        declare @Samples as Table ( PartNumber VarChar(16) );
        insert into @Samples ( PartNumber ) values
          ( 'BC.QT.000002' ), ( '''CP.AC.''000010''' ),
          ( '''CP.AL.000013' ), ( '''CP.A''L.000016''' ),
          ( '''CP.AL.000024''' );
        
        -- Play with it:
        select PartNumber,
          Substring( PartNumber,
            case when Left( PartNumber, 1 ) = '''' then 2 else 1 end,
            Len( PartNumber ) - case
              when Left( PartNumber, 1 ) = '''' and Right( PartNumber, 1 ) = '''' then 2
              when Left( PartNumber, 1 ) = '''' or Right( PartNumber, 1 ) = '''' then 1
              else 0 end ) as TrimmedPartNumber
          from @Samples;
        

        提示: 来自Len():“返回指定字符串表达式的字符数,不包括尾随空格。” DataLength 不排除尾随空格。对于 Unicode 字符串,您可以使用 DataLength( UnicodeStringExpression ) / DataLength( N'#' ) 来获取字符长度。一般DataLength( Left( Coalesce( StringExpression, '#' ), 1 ) ) 会返回每个字符的字节数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-23
          • 1970-01-01
          • 2019-05-20
          • 2017-01-02
          • 1970-01-01
          • 1970-01-01
          • 2016-05-27
          • 2011-09-18
          相关资源
          最近更新 更多