在撰寫部署腳本、升級腳本或動態 SQL 時,常需先判斷目標物件是否存在,再決定是否建立、修改或刪除。本文彙整 SQL Server 常見物件的存在性檢查模式,涵蓋資料庫、資料表、預存程序、暫存表、檢視表、函數、欄位、身分識別欄位、索引等,並提供可直接套用的範本程式碼。
IF EXISTS (SELECT * FROM sys.databases WHERE name = N'資料庫名')
DROP DATABASE [資料庫名];
IF EXISTS (
SELECT * FROM sysobjects
WHERE id = OBJECT_ID(N'[資料表名]')
AND OBJECTPROPERTY(id, N'IsUserTable') = 1
)
DROP TABLE [資料表名];
現代寫法(SQL Server 2005+)建議改用:
IF OBJECT_ID(N'[資料表名]', 'U') IS NOT NULL
DROP TABLE [資料表名];
IF EXISTS (
SELECT * FROM sysobjects
WHERE id = OBJECT_ID(N'[預存程序名]')
AND OBJECTPROPERTY(id, N'IsProcedure') = 1
)
DROP PROCEDURE [預存程序名];
現代寫法:
IF OBJECT_ID(N'[預存程序名]', 'P') IS NOT NULL
DROP PROCEDURE [預存程序名];
IF OBJECT_ID('tempdb..#暫存表名') IS NOT NULL
DROP TABLE #暫存表名;
-- 方式一:INFORMATION_SCHEMA(符合 ANSI 標準)
IF EXISTS (
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME = N'MyView52'
)
PRINT N'存在';
ELSE
PRINT N'不存在';
-- 方式二:OBJECT_ID(效能較佳)
IF OBJECT_ID(N'[MyView52]', 'V') IS NOT NULL
PRINT N'存在';
IF EXISTS (
SELECT * FROM dbo.sysobjects
WHERE id = OBJECT_ID(N'[dbo].[函數名]')
AND xtype IN (N'FN', N'IF', N'TF') -- FN=純量, IF=內嵌資料表值, TF=多陳述式資料表值
)
DROP FUNCTION [dbo].[函數名];
現代寫法:
IF OBJECT_ID(N'[dbo].[函數名]', 'FN') IS NOT NULL
DROP FUNCTION [dbo].[函數名];
SELECT [name], [id], crdate FROM sysobjects WHERE xtype = 'U';
-- 相容舊版寫法
IF EXISTS (
SELECT * FROM syscolumns
WHERE id = OBJECT_ID('資料表名') AND name = '欄位名'
)
ALTER TABLE 資料表名 DROP COLUMN 欄位名;
-- 現代寫法(SQL Server 2005+)
IF COL_LENGTH('資料表名', '欄位名') IS NOT NULL
ALTER TABLE 資料表名 DROP COLUMN 欄位名;
-- 方式一:COLUMNPROPERTY
IF COLUMNPROPERTY(OBJECT_ID('資料表名'), '欄位名', 'IsIdentity') = 1
PRINT N'身分識別欄位';
ELSE
PRINT N'非身分識別欄位';
-- 方式二:sys.columns(建議)
SELECT *
FROM sys.columns
WHERE object_id = OBJECT_ID('資料表名')
AND is_identity = 1;
IF EXISTS (
SELECT * FROM sysindexes
WHERE id = OBJECT_ID('資料表名') AND name = '索引名'
)
PRINT N'存在';
ELSE
PRINT N'不存在';
-- 刪除索引(兩種語法皆可)
DROP INDEX 資料表名.索引名;
-- 或
DROP INDEX 索引名 ON 資料表名; -- SQL Server 2005+
SELECT * FROM sys.sysobjects WHERE name = '物件名';
OBJECT_ID() 搭配型別代碼('U'=使用者表, 'P'=預存程序, 'V'=檢視表, 'FN'=函數等),語法簡潔且效能優於查詢系統表。sysobjects、syscolumns 等舊版相容性檢視,未來版本可能移除。INFORMATION_SCHEMA 檢視中查詢,符合標準且跨平台可移植性較好。QUOTENAME() 包裹物件名稱,防止 SQL 注入與特殊字元錯誤。| 代碼 | 物件類型 |
|---|---|
| U | 使用者資料表 |
| P | 預存程序 |
| V | 檢視表 |
| FN | 純量函數 |
| IF | 內嵌資料表值函數 |
| TF | 多陳述式資料表值函數 |
| TR | 觸發器 |
| PK | 主鍵約束 |
| F | 外鍵約束 |
| D | 預設約束 |
| C | 檢查約束 |