Как преобразовать новые строки (замените \r\n \n) через весь varchar и nvarchar поля в базе данных

Я восстанавливаюсь с ошибки в системе, которую я создал, где я не принял во внимание, что IE генерирует новые строки стиля Windows (\r\n), и другие браузеры генерируют новые строки стиля Unix (\n) при регистрации HTML-форм с текстовыми областями. Теперь я должен преобразовать все новые строки стиля Windows (\r\n) в новые строки стиля Unix (\n) всюду по varchar и nvarchar полям в моей базе данных SQL-Server.

Существует ли способ выполнить итерации через все таблицы/строки в T-SQL и экземплярах замены '\r\n' с '\n' для varchar и nvarchar полей?

Править: Я думаю, что часть замены была бы чем-то как

REPLACE(@fieldContents, CHAR(13)+CHAR(10), CHAR(10))

Твердая часть делает это через весь varchar и nvarchar поля.

6
задан Roy Tinker 24 June 2010 в 18:32
поделиться

2 ответа

Что-то вроде этого? Затем вы можете динамически выполнить эти строки или просто вырезать / вставить результаты и выполнить их в окне запроса.

select 'update ' + sc.name + '.' + t.name + ' set ' + c.name + ' = replace(' + c.name + ', CHAR(13)+CHAR(10), CHAR(10))'
from sys.columns c
    inner join sys.systypes st
        on c.system_type_id = st.xtype
            and CHARINDEX('varchar', st.name) <> 0
    inner join sys.tables t
        on c.object_id = t.object_id
    inner join sys.schemas sc
        on t.schema_id = sc.schema_id
9
ответ дан 10 December 2019 в 00:32
поделиться

Можно выполнить итерацию по системным представлениям в INFORMATION_SCHEMA и запустить для этого динамический SQL. Соответствующим представлением должно быть INFORMATION_SCHEMA.COLUMNS.

Лучший подход, вероятно, заключается в том, чтобы ваш пользовательский интерфейс справился с этим, когда ему нужно отобразить значения. Есть ли у вас метод предотвращения попадания подобных значений в БД в будущем?

Вот пример кода, который должен помочь вам начать:

DECLARE
    @table_schema SYSNAME,
    @table_name   SYSNAME,
    @column_name  SYSNAME,
    @cmd          VARCHAR(MAX)

DECLARE cur_string_columns AS
    SELECT
        TABLE_SCHEMA,
        TABLE_NAME,
        COLUMN_NAME
    FROM
        INFORMATION_SCHEMA.COLUMNS
    WHERE
        DATA_TYPE IN ('VARCHAR', 'CHAR') AND  -- NVARCHAR and NCHAR?
        CHARACTER_MAXIMUM_LENGTH > 1

OPEN cur_string_columns

FETCH NEXT FROM cur_string_columns INTO @table_schema, @table_name, @column_name

WHILE (@@FETCH_STATUS = 0)
BEGIN
    SELECT @cmd = 'UPDATE
    ' + QUOTENAME(@table_schema) + '.' + QUOTENAME(@table_name) + '
SET ' + QUOTENAME(@column_name) + ' = REPLACE(' + QUOTENAME(@column_name) + ', CHAR(13) + CHAR(10), CHAR(10))'

    EXEC(@cmd)

    FETCH NEXT FROM cur_string_columns INTO @table_schema, @table_name, @column_name
END

CLOSE cur_string_columns

DEALLOCATE cur_string_columns

Если у вас большие таблицы, это может занять много времени. Кроме того, оптимально было бы обновлять каждую таблицу только один раз, в то время как в этом случае она будет обновляться один раз для каждого столбца строк в таблице. Если бы я делал это на большой базе данных, то я бы изменил сценарий с учетом этого - упорядочил бы курсор по схеме таблицы и имени таблицы, добавил бы к SET часть строки для каждого столбца в таблице, только EXEC(@cmd), когда таблица меняется, а затем сбросил бы строку SET.

1
ответ дан 10 December 2019 в 00:32
поделиться