2012年12月5日 星期三

[SQL Server] 刪除table中符合條件的大量資料,不使用delete、truncate的作法

作法是:
1. 使用bcp公用程式將符合條件的資料匯出
2. create temp table
3. 將兩個table名稱互換
4. 觀察一段時間,運行正常後再考慮刪除原始table(已改名過的那個)

雖然truncate很快但無法設定條件,不適用於此案例。而delete勢必造成運行速度下滑或table lock

用bcp來處理的話不必快速而且可以保留住原始table

bcp queryout語法如下:

DECLARE @cmd varchar( 2000 )
SELECT @cmd = 'bcp "Select * from testDB.dbo.testTable Where LastTxDate > dateadd(day,-365,getdate()) " queryout "c:\testTable_queryout.txt" -c -T -r "\n"'
EXEC master..xp_cmdshell @cmd


bcp in語法如下:

DECLARE @cmd varchar( 2000 )
SELECT @cmd = 'bcp testDB.dbo.testTable_backup in "c:\testTable_queryout.txt" -c -T  -r "\n"'
EXEC master..xp_cmdshell @cmd

因軟硬體環境不同,以下測試資料僅供參考:
測試DBtestTable 29517筆,bcp out的檔案大小: 21.1 MB

以bcp out匯出全部共29517的時間為4.59秒,每秒處理6425.12 rows
以bcp queryout匯出符合條件之4327筆的時間為0.38秒,每秒處理11538.67 rows


以bcp out匯入全部共29517的時間為5.25秒,每秒處理5622.29 rows
以bcp queryout匯入符合條件之4327筆的時間為0.24秒,每秒處理18412.77 rows


參考資料:
使用 bcp 公用程式匯入及匯出大量資料 (SQL Server)
bcp 公用程式 詳細參數說明
SQLServer數據導入導出工具BCP詳解


bcp 匯出與匯入

2012年12月4日 星期二

[SQL Server] 以T-SQL新增欄位至table 只能排在最後一欄


一般要在SQL Server的table下新增一個欄位有2種作法:
1. 在物件總管的table名稱上按右鍵->設計(G),然後新增。想要將新欄位插在哪個位置都可以
但缺點是,當table中資料量很大時此作法可能會導致失敗
引申資訊: 解決 Management Studio 管理工具無法變更表格結構的問題

2. 使用T-SQL來新增
缺點是新增的欄位一定會排在table的最後一欄,目前還沒有解決方法。
目前最新的SQL Server 2012好像也沒有?


土法煉鋼的解法:
如果真的非要將新欄位插入至指定欄位
新建一個排好順序的table,將資料load進去再把db名稱換過來

有錯請指正,謝謝!

2012年12月3日 星期一

[SQL Server] 修改trigger時遇到的錯誤

使用 UNION、INTERSECT 或 EXCEPT 運算子結合的所有查詢,其目標清單中的運算式數量必須相等。

不過此錯誤並不限於trigger,只要是用到UNION、INTERSECT 或 EXCEPT的話,所連接的2個table欄位數目必須一樣