Một cái gì đó như thế này:
SELECT
*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'
nhưng đối với chỉ số.
Một cái gì đó như thế này:
SELECT
*
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'
nhưng đối với chỉ số.
Câu trả lời:
Bạn có thể làm điều đó bằng cách sử dụng một chuyển tiếp thẳng như thế này:
SELECT *
FROM sys.indexes
WHERE name='YourIndexName' AND object_id = OBJECT_ID('Schema.YourTableName')
IF EXISTS(SELECT * ...) BEGIN ... END
.
YourTableName
là tên đầy đủ với lược đồ
Đối với SQL 2008 và mới hơn , một phương pháp ngắn gọn hơn, mã hóa khôn ngoan, để phát hiện sự tồn tại của chỉ mục là sử dụng hàm INDEXPROPERTY
dựng sẵn:
INDEXPROPERTY ( object_ID , index_or_statistics_name , property )
Cách sử dụng đơn giản nhất là với thuộc IndexID
tính:
If IndexProperty(Object_Id('MyTable'), 'MyIndex', 'IndexID') Is Null
Nếu chỉ mục tồn tại, ở trên sẽ trả về ID của nó; nếu không, nó sẽ quay trở lại NULL
.
AdaTheDEV, tôi đã sử dụng cú pháp của bạn và tạo ra sau đây và tại sao.
Vấn đề: Quá trình chạy một lần một phần tư mất một giờ do thiếu chỉ số.
Khắc phục: Thay đổi quy trình truy vấn hoặc Quy trình để kiểm tra chỉ mục và tạo chỉ mục nếu thiếu ... Cùng một mã được đặt ở cuối truy vấn và thủ tục để xóa chỉ mục vì không cần thiết nhưng hàng quý. Chỉ hiển thị cú pháp thả ở đây
-- drop the index
begin
IF EXISTS (SELECT * FROM sys.indexes WHERE name='Index_Name'
AND object_id = OBJECT_ID('[SchmaName].[TableName]'))
begin
DROP INDEX [Index_Name] ON [SchmaName].[TableName];
end
end
Tuy nhiên, một sai lệch nhỏ so với câu hỏi ban đầu có thể chứng minh hữu ích cho những người tương lai đến đây muốn DROP
và CREATE
một chỉ mục, tức là trong một kịch bản triển khai.
Bạn có thể bỏ qua kiểm tra tồn tại chỉ bằng cách thêm phần sau vào câu lệnh tạo của bạn:
CREATE INDEX IX_IndexName
ON dbo.TableName
WITH (DROP_EXISTING = ON);
Đọc thêm tại đây: CREATE INDEX (Transact-SQL) - Điều khoản DROP_EXISTING
NB Như đã đề cập trong các ý kiến, chỉ mục phải tồn tại để mệnh đề này hoạt động mà không gây ra lỗi.
Nếu mục đích ẩn của câu hỏi của bạn là DROP
chỉ mục trước khi thực hiện INSERT
một bảng lớn, thì đây là một mục đích hữu ích:
DROP INDEX IF EXISTS [IndexName] ON [dbo].[TableName]
Cú pháp này có sẵn kể từ SQL Server 2016. Tài liệu cho IF EXISTS
:
Trong trường hợp bạn xử lý một khóa mồi thay thế, sau đó sử dụng:
ALTER TABLE [TableName] DROP CONSTRAINT IF EXISTS [PK_name]
Đã viết hàm dưới đây cho phép tôi nhanh chóng kiểm tra xem liệu chỉ mục có tồn tại không; hoạt động giống như OBarget_ID.
CREATE FUNCTION INDEX_OBJECT_ID (
@tableName VARCHAR(128),
@indexName VARCHAR(128)
)
RETURNS INT
AS
BEGIN
DECLARE @objectId INT
SELECT @objectId = i.object_id
FROM sys.indexes i
WHERE i.object_id = OBJECT_ID(@tableName)
AND i.name = @indexName
RETURN @objectId
END
GO
EDIT: Điều này chỉ trả về OBarget_ID của bảng, nhưng nó sẽ là NULL nếu chỉ mục không tồn tại. Tôi cho rằng bạn có thể thiết lập điều này để trả về index_id, nhưng điều đó không hữu ích lắm.
-- Delete index if exists
IF EXISTS(SELECT TOP 1 1 FROM sys.indexes indexes INNER JOIN sys.objects
objects ON indexes.object_id = objects.object_id WHERE indexes.name
='Your_Index_Name' AND objects.name = 'Your_Table_Name')
BEGIN
PRINT 'DROP INDEX [Your_Index_Name] ON [dbo].[Your_Table_Name]'
DROP INDEX [our_Index_Name] ON [dbo].[Your_Table_Name]
END
GO
Để kiểm tra Clustered Index có tồn tại trên bảng cụ thể hay không:
SELECT * FROM SYS.indexes
WHERE index_id = 1 AND name IN (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'Table_Name')