-- 找到所有有該欄位的資料表 SELECTDISTINCT t.TABLE_SCHEMA, -- 資料表的結構描述名稱 t.TABLE_NAME -- 資料表名稱 FROM INFORMATION_SCHEMA.COLUMNS c INNERJOIN INFORMATION_SCHEMA.TABLES t ON c.TABLE_NAME = t.TABLE_NAME AND c.TABLE_SCHEMA = t.TABLE_SCHEMA WHERE c.COLUMN_NAME ='MaintainClassID'-- 要查找的欄位名稱 AND t.TABLE_TYPE ='BASE TABLE'; -- 排除視圖,只保留實體資料表
語句解析
INFORMATION_SCHEMA.COLUMNS:包含所有欄位的中繼資料
INFORMATION_SCHEMA.TABLES:包含所有資料表與視圖的中繼資料
INNER JOIN:合併兩個視圖,確保欄位與資料表資訊對應
WHERE 條件:
指定要查找的欄位名稱
TABLE_TYPE = 'BASE TABLE' 排除視圖,只保留實體資料表
步驟二:產生 UPDATE 語句
1 2 3 4 5 6 7 8 9 10 11 12 13 14
-- 產生批量更新語句 SELECTDISTINCT 'UPDATE ['+ t.TABLE_SCHEMA +'].['+ t.TABLE_NAME + '] SET [MaintainClassID] = 4851206 WHERE [MaintainClassID] = 4851204;' AS UpdateStatement FROM INFORMATION_SCHEMA.COLUMNS c INNERJOIN INFORMATION_SCHEMA.TABLES t ON c.TABLE_NAME = t.TABLE_NAME AND c.TABLE_SCHEMA = t.TABLE_SCHEMA WHERE c.COLUMN_NAME ='MaintainClassID' AND t.TABLE_TYPE ='BASE TABLE';
SELECT@sql+= 'UPDATE ['+ t.TABLE_SCHEMA +'].['+ t.TABLE_NAME + '] SET [MaintainClassID] = 4851206 WHERE [MaintainClassID] = 4851204;'+CHAR(13) FROM INFORMATION_SCHEMA.COLUMNS c INNERJOIN INFORMATION_SCHEMA.TABLES t ON c.TABLE_NAME = t.TABLE_NAME AND c.TABLE_SCHEMA = t.TABLE_SCHEMA WHERE c.COLUMN_NAME ='MaintainClassID' AND t.TABLE_TYPE ='BASE TABLE';
-- 先印出來確認再決定要不要執行 PRINT @sql;
-- 確認無誤後再取消註解執行 -- EXEC sp_executesql @sql;
這段先把所有 UPDATE 語句串成一個字串並印出,確認無誤後再取消 EXEC 那行的註解執行。
使用注意事項
執行更新前先備份資料庫,或至少確認目前有完整備份
建議先跑步驟一確認影響的資料表清單,再決定是否執行更新
大量更新會產生交易記錄,如果資料庫是 FULL 復原模式且交易記錄檔沒有定期備份,可能撐爆磁碟。執行前用 DBCC SQLPERF(LOGSPACE) 看剩餘空間;若空間緊張,考慮分批執行或暫時切換到 BULK_LOGGED 復原模式
建議在非尖峰時段執行,避免長時間鎖定資料表影響線上作業
INFORMATION_SCHEMA 的限制
INFORMATION_SCHEMA 是 ANSI 標準相容層,對跨資料庫引擎的查詢有一定優勢,但在純 SQL Server 環境,sys.columns 和 sys.tables 是更完整的選擇:
INFORMATION_SCHEMA 不包含 IDENTITY 屬性、計算欄位、稀疏欄位等 SQL Server 特有屬性
-- 用 sys 目錄檢視查找特定欄位(更完整) SELECTDISTINCT s.name AS TABLE_SCHEMA, t.name AS TABLE_NAME FROM sys.columns c INNERJOIN sys.tables t ON c.object_id = t.object_id INNERJOIN sys.schemas s ON t.schema_id = s.schema_id WHERE c.name ='MaintainClassID';
實用擴展
同樣的查詢骨架可以用在其他常見場景:
查找在多張資料表中重複出現的欄位名稱
1 2 3 4 5 6 7 8 9 10 11 12
-- 找出出現在兩張(含)以上資料表的欄位名稱 SELECT COLUMN_NAME, COUNT(DISTINCT TABLE_NAME) AS TableCount FROM INFORMATION_SCHEMA.COLUMNS GROUPBY COLUMN_NAME HAVING COUNT(DISTINCT TABLE_NAME) >=2 ORDERBY TableCount DESC;
檢查同名欄位在不同資料表中的型別是否一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-- 找出同名欄位但資料型別不同的情況 SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COUNT(*) AS OccurrenceCount, STRING_AGG(TABLE_SCHEMA +'.'+ TABLE_NAME, ', ') AS Tables FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME ='MaintainClassID' GROUPBY COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH ORDERBY COLUMN_NAME;
產生欄位存在某張資料表的 ALTER TABLE 語句(新增遺漏欄位)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
-- 找出哪些資料表缺少 MaintainClassID 欄位(假設應該要有) SELECT t.TABLE_SCHEMA, t.TABLE_NAME, 'ALTER TABLE ['+ t.TABLE_SCHEMA +'].['+ t.TABLE_NAME + '] ADD [MaintainClassID] INT NULL;'AS AlterStatement FROM INFORMATION_SCHEMA.TABLES t WHERE t.TABLE_TYPE ='BASE TABLE' ANDNOTEXISTS ( SELECT1 FROM INFORMATION_SCHEMA.COLUMNS c WHERE c.TABLE_NAME = t.TABLE_NAME AND c.TABLE_SCHEMA = t.TABLE_SCHEMA AND c.COLUMN_NAME ='MaintainClassID' );