非 `TRUNCATE TABLE` (清空資料),而是 `DROP TABLE` (移除結構)。適用於匯入臨時表、ETL 中繼表等自動化清理場景。
`CHECKSUM(*)` 對整列計算雜湊值。**全 NULL 列的 CHECKSUM 固定為 `2147483511`** (SQL Server 內部實作常數)。若表中**不存在**任何非全 NULL 列,則該表可安全刪除。
SET NOCOUNT ON;
DECLARE @SchemaName sysname, @TableName sysname, @Sql nvarchar(max);
DECLARE cur CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT s.name, t.name
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.name NOT LIKE '#%' -- 排除暫存表
AND t.name NOT IN ('MSdistributor_Access'); -- 排除系統表
OPEN cur;
FETCH NEXT FROM cur INTO @SchemaName, @TableName;
WHILE @@FETCH_STATUS = 0
BEGIN
-- 動態建構:若不存在任何非全 NULL 列,則 DROP
SET @Sql = N'
IF NOT EXISTS (
SELECT 1
FROM ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N'
WHERE CHECKSUM(*) <> 2147483511
)
DROP TABLE ' + QUOTENAME(@SchemaName) + N'.' + QUOTENAME(@TableName) + N';';
EXEC sp_executesql @Sql;
FETCH NEXT FROM cur INTO @SchemaName, @TableName;
END
CLOSE cur; DEALLOCATE cur;
-- 建立測試表 CREATE TABLE T1 (c1 int, c2 int, c3 datetime); -- 全 NULL CREATE TABLE T2 (c1 int, c2 varchar(10), c3 float); -- 全 NULL CREATE TABLE T3 (c1 decimal(10,2), c2 nchar(10)); -- 混合:一列全 NULL,一列有值 INSERT T1 VALUES (NULL,NULL,NULL), (NULL,NULL,NULL); INSERT T2 VALUES (NULL,NULL,NULL); INSERT T3 VALUES (NULL,NULL), (NULL,N'Test'); -- 執行上述腳本後: -- T1, T2 被 DROP -- T3 保留
| 風險 | 說明 | 緩解 |
|---|---|---|
| 資料型別不支援 | `CHECKSUM` **不支援** `text`、`ntext`、`xml`、`image`、`cursor`、`sql_variant`、`CLR UDT`、`FILESTREAM`、`hierarchyid`、`geometry`、`geography`。 | 排除含此類欄位的表,或改用 `COLUMNS_UPDATED()` / 逐欄 `IS NULL` 判斷。 |
| 外鍵約束阻擋 | 若表被其他表參考 (FK),`DROP TABLE` 會失敗拋錯。 | 先查 `sys.foreign_keys` 篩選無參考表,或捕捉錯誤記錄不刪除。 |
| 觸發器/檢視表/預存程序相依 | 刪除表會導致相依物件失效。 | 先 `sp_depends` / `sys.sql_expression_dependencies` 掃描相依性。 |
| 計算碰撞極低機率 | 非全 NULL 列極罕見情況下 `CHECKSUM(*) = 2147483511` (雜湊碰撞)。 | 極低機率可忽略;嚴謹場景改用 `WHERE (c1 IS NOT NULL OR c2 IS NOT NULL ...)` 逐欄判斷。 |
| 大表效能 | 全表掃描計算 CHECKSUM 耗時。 | 加 `TOP 1` 並建立適當索引 (難),或離線維護窗口執行。 |
-- 簡化版:先篩選符合條件的表,再逐一處理錯誤 -- 實際生產建議加入 TRY...CATCH、記錄 Log 表、發送通知
`CHECKSUM(*)` 偵測全 NULL 表是巧妙技巧,但**生產環境務必處理型別限制、FK 相依、相依物件**。建議納入 ETL 後處理流程,搭配 `TRY...CATCH` 記錄失敗案例人工複核,而非全自動無人值守刪除。