Как экранировать символ 'в обновлении SQL с помощью функции замены? - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть эти данные в моей таблице

  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', но один из них посередине.

Мне нужен способ удалить префикс / суффикс ', если они существуют.

Ответы [ 4 ]

0 голосов
/ 14 сентября 2018

Другой подход использует 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;

Совет: From Len(): "Возвращает количество символов указанного строкового выражения, , исключая завершающие пробелы ." DataLength не исключает конечные пробелы. Для строк Unicode вы можете использовать DataLength( UnicodeStringExpression ) / DataLength( N'#' ), чтобы получить длину в символах. Обычно DataLength( Left( Coalesce( StringExpression, '#' ), 1 ) ) возвращает количество байтов на символ.

0 голосов
/ 14 сентября 2018

Другой вариант, который был бы безопасен, даже если контент может содержать пробелы, заключался бы в использовании case:

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

Недостатком, помимо того, что он более громоздок, чем ответ Гордона, является то, что он будет толькоудалить первый и последний апострофы - если у вас есть значение типа ''asdf', оно будет обновлено как 'asdf.

0 голосов
/ 14 сентября 2018

Это удалит все 'слева и справа.Например: '' sample '' будет 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];
0 голосов
/ 14 сентября 2018

Если у вас нет пробелов в PartNumber, вы можете использовать:

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

Это обрабатывает удаление символов из начала и конца строки, используя функции обрезки. Увы, они работают только на пространствах; поэтому замена необходима, чтобы превратить кавычки в пробелы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...