2010-06-24 115 views
6

我正在从系统中的错误中恢复,但我没有考虑到IE生成的Windows样式在使用文本区域发布HTML表单时,换行符(\ r \ n)和其他浏览器会生成Unix样式换行符(\ n)。现在我需要在SQL-Server数据库的整个varchar和nvarchar字段中将所有Windows风格的换行符(\ r \ n)转换为Unix风格的换行符(\ n)。如何在数据库中的所有varchar和nvarchar字段之间转换换行符(用 n替换 r n)

是否有方法遍历T-SQL中的所有表/行,并使用'\ n'替换varchar和nvarchar字段的'\ r \ n'实例?

编辑:我想更换部分会像

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

难的是在所有的varchar和nvarchar领域这样做。

回答

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 
+0

真棒的想法,我喜欢创造力和简洁。谢谢。 注意:我在('my_schema-1','my_schema_2',...)“中的where sc.name表单的底部添加了一个条件,以将其限制为我自己的模式。我还在第一行的字符串末尾添加了分号,以允许在查询窗口中粘贴和运行结果。 – 2010-06-24 18:55:21

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字符串。

+0

是的,我修改了客户端代码,用\ n在表单提交中替换\ r \ n ...但我仍留下数据库中的所有文本,直到现在才生成。 – 2010-06-24 18:34:45

+0

+1 - 感谢发布示例T-SQL代码。 – 2010-06-24 19:02:13