Поскольку вы используете 10g, вы можете использовать псевдостолбец ORA_ROWSCN
. Это дает вам верхнюю границу последнего SCN (номер изменения системы), который вызвал изменение в строке. Поскольку это возрастающая последовательность, вы можете сохранить максимум ORA_ROWSCN
, который вы видели, а затем искать только данные с SCN больше этого
По умолчанию ORA_ROWSCN
фактически поддерживается на уровне блока, поэтому изменение любой строки в блоке изменит ORA_ROWSCN
для всех строк в блоке. Этого, вероятно, вполне достаточно, если целью является минимизация количества обрабатываемых строк несколько раз без изменений, если мы говорим о «нормальных» шаблонах доступа к данным. Вы можете перестроить таблицу с помощью ROWDEPENDENCIES
, что приведет к отслеживанию ORA_ROWSCN
на уровне строк, что дает вам более детальную информацию, но требует одноразовых усилий для перестройки таблицы.
Другой вариант - настроить что-то вроде Change Data Capture (CDC) и сделать ваше приложение OCI подписчиком изменений в таблице, но это также требует единовременных усилий по настройке CDC.
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.
Я знал, что 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
Моя задача читателям: можете ли вы сделать это более эффективным? А как насчет использования рекурсии?
Параметризованная версия 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')
Я поместил это в оба места, где вызывается PatIndex.
PatIndex('%[^A-Za-z0-9]%', @Temp)
для пользовательской функции над RemoveNonAlphaCharacters и переименовал ее в RemoveNonAlphaNumericCharacters