我正在从我构建的系统中的一个错误中恢复过来,我没有考虑IE生成Windows风格的换行符(\ r \ n)和其他浏览器在发布HTML表单时生成Unix风格的换行符(\ n)带有文字区域。现在我需要在SQL-Server数据库的varchar和nvarchar字段中将所有Windows样式的换行符(\ r \ n)转换为Unix样式的换行符(\ n)。
有没有办法迭代T-SQL中的所有表/行,并将'\ r \ n'的实例替换为'\ n',用于varchar和nvarchar字段?
编辑:我认为替换部分类似于REPLACE(@fieldContents, CHAR(13)+CHAR(10), CHAR(10))
困难的部分是在所有varchar和nvarchar字段中执行此操作。
答案 0 :(得分:9)
这样的东西?然后,您可以动态执行这些字符串,或者只是剪切/粘贴结果并在查询窗口中执行它们。
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
答案 1 :(得分:1)
您可以遍历INFORMATION_SCHEMA中的系统视图并运行动态SQL来执行此操作。相关视图应为INFORMATION_SCHEMA.COLUMNS。
更好的方法可能是让UI在必须显示值时处理它。您是否有一种方法可以防止这样的值在未来进入数据库?
以下是一些可以帮助您入门的示例代码:
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字符串时。