Как разделить все небуквенные символы от строки в SQL Server?

Поскольку вы используете 10g, вы можете использовать псевдостолбец ORA_ROWSCN. Это дает вам верхнюю границу последнего SCN (номер изменения системы), который вызвал изменение в строке. Поскольку это возрастающая последовательность, вы можете сохранить максимум ORA_ROWSCN, который вы видели, а затем искать только данные с SCN больше этого

.

По умолчанию ORA_ROWSCN фактически поддерживается на уровне блока, поэтому изменение любой строки в блоке изменит ORA_ROWSCN для всех строк в блоке. Этого, вероятно, вполне достаточно, если целью является минимизация количества обрабатываемых строк несколько раз без изменений, если мы говорим о «нормальных» шаблонах доступа к данным. Вы можете перестроить таблицу с помощью ROWDEPENDENCIES, что приведет к отслеживанию ORA_ROWSCN на уровне строк, что дает вам более детальную информацию, но требует одноразовых усилий для перестройки таблицы.

Другой вариант - настроить что-то вроде Change Data Capture (CDC) и сделать ваше приложение OCI подписчиком изменений в таблице, но это также требует единовременных усилий по настройке CDC.

160
задан Even Mien 17 June 2009 в 15:16
поделиться

4 ответа

Try this function:

Create Function [dbo].[RemoveNonAlphaCharacters](@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin

    Declare @KeepValues as varchar(50)
    Set @KeepValues = '%[^a-z]%'
    While PatIndex(@KeepValues, @Temp) > 0
        Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')

    Return @Temp
End

Call it like this:

Select dbo.RemoveNonAlphaCharacters('abc1234def5678ghi90jkl')

Once you understand the code, you should see that it is relatively simple to change it to remove other characters, too. You could even make this dynamic enough to pass in your search pattern.

Hope it helps.

348
ответ дан 23 November 2019 в 21:27
поделиться

Я знал, что SQL плохо справляется со строками, но не думал, что это будет так сложно. Вот простая функция для вырезания всех чисел из строки. Могли бы быть более эффективные способы сделать это, но это только начало.

CREATE FUNCTION dbo.AlphaOnly (
    @String varchar(100)
)
RETURNS varchar(100)
AS BEGIN
  RETURN (
    REPLACE(
      REPLACE(
        REPLACE(
          REPLACE(
            REPLACE(
              REPLACE(
                REPLACE(
                  REPLACE(
                    REPLACE(
                      REPLACE(
                        @String,
                      '9', ''),
                    '8', ''),
                  '7', ''),
                '6', ''),
              '5', ''),
            '4', ''),
          '3', ''),
        '2', ''),
      '1', ''),
    '0', '')
  )
END
GO

-- ==================
DECLARE @t TABLE (
    ColID       int,
    ColString   varchar(50)
)

INSERT INTO @t VALUES (1, 'abc1234567890')

SELECT ColID, ColString, dbo.AlphaOnly(ColString)
FROM @t

Результат

ColID ColString
----- ------------- ---
    1 abc1234567890 abc

Раунд 2 - Черный список на основе данных

-- ============================================
-- Create a table of blacklist characters
-- ============================================
IF EXISTS (SELECT * FROM sys.tables WHERE [object_id] = OBJECT_ID('dbo.CharacterBlacklist'))
  DROP TABLE dbo.CharacterBlacklist
GO
CREATE TABLE dbo.CharacterBlacklist (
    CharID              int         IDENTITY,
    DisallowedCharacter nchar(1)    NOT NULL
)
GO
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'0')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'1')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'2')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'3')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'4')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'5')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'6')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'7')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'8')
INSERT INTO dbo.CharacterBlacklist (DisallowedCharacter) VALUES (N'9')
GO

-- ====================================
IF EXISTS (SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID('dbo.StripBlacklistCharacters'))
  DROP FUNCTION dbo.StripBlacklistCharacters
GO
CREATE FUNCTION dbo.StripBlacklistCharacters (
    @String nvarchar(100)
)
RETURNS varchar(100)
AS BEGIN
  DECLARE @blacklistCt  int
  DECLARE @ct           int
  DECLARE @c            nchar(1)

  SELECT @blacklistCt = COUNT(*) FROM dbo.CharacterBlacklist

  SET @ct = 0
  WHILE @ct < @blacklistCt BEGIN
    SET @ct = @ct + 1

    SELECT @String = REPLACE(@String, DisallowedCharacter, N'')
    FROM dbo.CharacterBlacklist
    WHERE CharID = @ct
  END

  RETURN (@String)
END
GO

-- ====================================
DECLARE @s  nvarchar(24)
SET @s = N'abc1234def5678ghi90jkl'

SELECT
    @s                  AS OriginalString,
    dbo.StripBlacklistCharacters(@s)   AS ResultString

Результат

OriginalString           ResultString
------------------------ ------------
abc1234def5678ghi90jkl   abcdefghijkl

Моя задача читателям: можете ли вы сделать это более эффективным? А как насчет использования рекурсии?

4
ответ дан 23 November 2019 в 21:27
поделиться

Параметризованная версия G Mastros ' отличный ответ :

CREATE FUNCTION [dbo].[fn_StripCharacters]
(
    @String NVARCHAR(MAX), 
    @MatchExpression VARCHAR(255)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
    SET @MatchExpression =  '%['+@MatchExpression+']%'

    WHILE PatIndex(@MatchExpression, @String) > 0
        SET @String = Stuff(@String, PatIndex(@MatchExpression, @String), 1, '')

    RETURN @String

END

Только алфавитный:

SELECT dbo.fn_StripCharacters('a1!s2@d3#f4$', '^a-z')

Только числовой:

SELECT dbo.fn_StripCharacters('a1!s2@d3#f4$', '^0-9')

Только буквенно-цифровой:

SELECT dbo.fn_StripCharacters('a1!s2@d3#f4$', '^a-z0-9')

Не буквенно-цифровые:

SELECT dbo.fn_StripCharacters('a1!s2@d3#f4$', 'a-z0-9')
159
ответ дан 23 November 2019 в 21:27
поделиться

Я поместил это в оба места, где вызывается PatIndex.

PatIndex('%[^A-Za-z0-9]%', @Temp)

для пользовательской функции над RemoveNonAlphaCharacters и переименовал ее в RemoveNonAlphaNumericCharacters

1
ответ дан 23 November 2019 в 21:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: