У меня есть база данных, содержащая около 50 таблиц, каждая таблица имеет около 10-100 столбцов с максимум 1 миллион строк в каждой таблице. (довольно большой, как для новичка: P)
База данных старая и некоторые строки содержат специальные символы (невидимые символы или какой-то странный юникод), и я хотел бы удалить эти символы.
Я искал в Google и нашел небольшой фрагмент, в котором перечислены все столбцы определенного типа:
SELECT
OBJECT_NAME(col.OBJECT_ID) AS [TableName]
,col.[name] AS [ColName]
,typ.[name] AS [TypeName]
FROM
sys.all_columns col
INNER JOIN sys.types typ
ON col.user_type_id = typ.user_type_id
WHERE
col.user_type_id IN (167,231)
AND
OBJECT_NAME(col.OBJECT_ID) = 'Orders'
В этом списке перечислены все столбцы, которые являются varchar или nvarchar.
Я нашел две функции, одна из которых возвращает таблицу всех символов из строки, а вторая проверяет, содержит ли строка какие-либо специальные символы:
CREATE FUNCTION AllCharactersInString (@str nvarchar(max))
RETURNS TABLE
AS
RETURN
(SELECT
substring(B.main_string,C.int_seq,1) AS character
,Unicode(substring(B.main_string,C.int_seq,1)) AS unicode_value
FROM
(SELECT
@str AS main_string) B,(SELECT
A.int_seq
FROM
(SELECT
row_number() OVER (ORDER BY name) AS int_seq
FROM
sys.all_objects) A
WHERE
A.int_seq <= len(@str)) C
)
И второй:
CREATE FUNCTION ContainsInvisibleCharacter (@str nvarchar(max))
RETURNS int
AS
BEGIN
DECLARE @Result Int
IF exists
(SELECT
*
FROM
AllCharactersInString(@str)
WHERE
unicode_value IN (1,9,10,11,12,13,14,28,29,31,129,141,143,144,157,160))
BEGIN SET @Result = 1
END
ELSE
BEGIN SET @Result = 0
END
RETURN @Result
END
Мой вопрос заключается в том, как объединить эти две функции в одну (если это возможно и будет быстрее) и вторую: как запустить эту функцию для всех записей во всех столбцах (которые относятся к конкретному типу) в таблице.
У меня есть этот код:
SELECT
O.Order_Id
,Rn_Descriptor
FROM
dbo.Order O
WHERE
dbo.ContainsInvisibleCharacter(O.Rn_Descriptor) = 1
AND
O.Order_Id IN (SELECT TOP 1000
Order.Order_Id
FROM
dbo.Order
WHERE
Order.Rn_Descriptor IS NOT NULL
)
но работает ооочень медленно: /
Может, есть самый быстрый способ удалить нежелательных персонажей?
Что будет хорошо, так это найти строки, содержащие эти символы, перечислить их, и тогда я смогу проверить их вручную.