SQL批量複製命令的六個陷阱

2021-10-01 00:03:39 字數 2376 閱讀 7787

批量複製工具(bcp)是

sqlserver主要的命令列工具之一,使用非常方便,它也是sql server匯入匯出海量資料的方式。但是dba應注意bcp存在幾項限制,本文作者通過自身經歷總結了一些主要的問題表現。

1、沒有對utf-8的支援

sql server有對unicode的本地支援,使用過nvarchar和ntext欄位型別的任何人都知道。它通過對映每個字元為雙位元組實體來內部處理 unicode。如果你只是處理sql server例項之間的資料,那麼不會有任何問題,因為它們都以相同的方式儲存。

不過,如果你 試圖使用bcp從把unicode匯出為utf-8的資料**匯入資料,那事情就有點複雜了。utf-8是unicode的一種子變體,專門設計支援與八 位ascii文字的向後相容,所以預設使用八位ascii編碼的網頁、電子郵件和其它格式可以用於儲存unicode資料。

如果你從utf-8源匯出資料,不要指望對這些資料使用bcp;它一直不支援utf-8。你必須考慮資料問題,以完整雙位元組unicode匯出使資料形成可接受格式。具有諷刺意味的是,另乙個普通的編碼可以通過「-c」開關(iso 1252,ansi/微軟公司windows)被bcp接受。不過,就整體而言,你最好把資料匯出為雙位元組unicode,以保持對bcp的最大相容性,尤其是如果你處理的資料可能包含與ascii不相容的字元。

2、注意匯出的行順序

使用bcp通過查詢匯出的資料對於匯出順序遵守相同的規則,會應用於任何其它情況的查詢。換句話說,如果你的查詢沒有明確的「order by」從句,你獲得的資料看起來就是完全任意的順序。它通常是基於隱含索引中的順序形成的,但是我已經學會甚至連經驗法則也不相信了——尤其是如果該查詢 在多個表之間執行「join」或者一些其它聚合函式。

資料是按什麼順序匯出的通常並不重要,但是資料以什麼順序匯入是非常關鍵的。如果你使用的資料庫是後來匯入行的正確性決定於早先存在的行,而且你是批量匯入資料的話,那麼匯出的順序就很重要,你需要相應地建立你的bcp語句。這一點似乎顯而易見,但是我經常驚訝有那麼多人,甚至包括一些資深的sql server專家都沒有意識到這一點。

3、從bcp啟用的儲存過程不能接收引數

如果你使用帶有引數的儲存過程,作為bcp動作transact-sql(t-sql)語句的一部分,幾乎可以肯定它不能用,而且會在命令列丟擲函式順序錯誤。

當t-sql語句傳遞給bcp時,它將被使用「set fmtonly on」機制進行分析,來判斷結果集的柱狀格式。這意味著動態構造語句(比如帶引數的儲存過程)將不能正確分析,而且也不能在bcp下編譯。

如果你想解決這個問題,有幾種方法可以選擇:

建立不帶任何引數的儲存過程,用問號啟用儲存過程並傳入需要的引數(可能通過資料來源而不是命令列接收引數)。

用sqlcmd替代bcp。

msdn部落格中提到了乙個處理技巧,需要使用稱為「openrowset」的技巧。如果你通過「openrowset 」函式執行「select」,你可以以臨時方式傳遞乙個t-sql語句,從而解決呼叫帶引數儲存過程的限制。然而,這種處理技巧也有侷限:例如,與語句連 接時不應該使用,因為執行會對資料庫造成消極變化,而且該語句可能需要執行不止一次。

4、匯入時要注意表定義

當你使用bcp從乙個sql server源匯出資料,並匯入到另乙個sql server時,你匯出時的列定義和匯入時的列定義必須相匹配。這也包括諸如null或者not null這類定義,在目標表缺少它們會引起靜默資料損壞。

5、在目標資料庫上的觸發器不能被bcp觸發

不管什麼時候執行匯入操作,bcp的本地行為在目標資料庫上都會禁用觸發器。因為bcp匯入操作通常很大,如果按預設啟用觸發器的話,匯入操作會很混亂。因此,你需要在bcp上使用命令選項「-h fire_triggers」,這樣觸發器才會被觸發。

要注意,當選項啟用時,觸發器會為每個批量操作執行一次,——也就是說,每次你執行bcp時執行一次。另外還要注意,在sql server 2005和以後的版本中,觸發器使用了「行版本」,在匯入操作時用tempdb來儲存行版本資訊。如果你的tempdb不能容納觸發器生成的大量資料湧 入,該操作將異常終止。

6、bcp不能給本地附加檔案輸出

如果你使用bcp匯出資料到檔案,該檔案必須是新建立的。你不能選擇現存盤案,並把匯出結果追加到檔案。幸運的是,解決辦法並不困難,您可以簡單地匯出到任何多個檔案,然後使用copy命令來整合這些結果。命令如下:

copy export1.dat + export2.dat export.dat

***********************************=分割線******************************==

六個防止SQL注入式攻擊的建議

sql注入攻擊的危害性很大。在講解其防止辦法之前,資料庫管理員有必要先了解一下其攻擊的原理。這有利於管理員採取有針對性的防治措施。一 sql注入攻擊的簡單示例。statement select from users where value a variable 上面這條語句是很普通的一條sql語句,...

六個哲理的故事

1 單純的喜悅 有乙個小女孩每天都從家裡走路去上學。一天早上天氣不太好,雲層漸漸變厚,到了下午時風吹得更急,不久開始有閃電 打雷 下大雨。小女孩的媽媽很擔心,她擔心小女孩會被打雷嚇著,甚至被雷打到。雷雨下得愈來愈大,閃電像一把銳利的劍刺破天空,小女孩的媽媽趕緊開著車,沿著上學的路線去找小女孩,看到自...

人生的六個階段

人生的六個階段 潛龍勿用 見龍在田 終日乾乾 或躍在淵 飛龍在天 亢龍有悔 上述幾詞均出自易經六十四卦中的第一卦乾卦,乾為天 卦名 乾為天 的卦象是幹上幹下,由六條線段疊合而成。它象徵著天是至高至大,覆蓋萬物又不偏不倚,天行健,君子當以自強不息。原文 幹 元 享 利 貞。其意為 天是創造萬物的根元,...