2010-06-24 72 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