Làm cách nào để giải quyết tên của trình kích hoạt cơ sở dữ liệu với các hàm dựng sẵn?


8

Tôi có một trình kích hoạt cơ sở dữ liệu mà tôi sử dụng để ngăn tôi tạo một số thủ tục nhất định trong cơ sở dữ liệu người dùng.

Nó xuất hiện trong sys.triggers, với một object_id, nhưng tôi không thể sử dụng object_idchức năng để tìm thấy nó.

SELECT OBJECT_ID(t.name, t.type) AS object_id, *
FROM   sys.triggers AS t;

QUẢ HẠCH

Tương tự như vậy, tôi có thể tìm thấy nó trong sys.dm_exec_trigger_stats. Tôi không thể object_namegiải quyết, nhưng object_definitionkhông.

SELECT OBJECT_NAME(dets.object_id, dets.database_id) AS object_name,
       OBJECT_DEFINITION(dets.object_id) AS object_definition,
       *
FROM   sys.dm_exec_trigger_stats AS dets;

QUẢ HẠCH

Có một hàm sẽ chấp nhận id đối tượng của trình kích hoạt mức cơ sở dữ liệu và trả về tên của nó không?


Không chắc chắn 100% nhưng bạn có thể thử sys.sql_expression_dependencies-> referenced_idtham gia sys.objectskhông?
Kin Shah

@Kin nó không hiển thị trong sys> đối tượng hoặc tất cả các đối tượng. Khá kỳ lạ!
Erik Darling

Đó là điều thú vị .. làm thế nào về parent_idmỗi bol, ví dụobject_id(object_name(parent_id))
Kin Shah

Câu trả lời:


9

Các trình kích hoạt cấp cơ sở dữ liệu và máy chủ không được đặt trong phạm vi "đối tượng" mỗi lần (đây là lý do tại sao bạn không thể tạo chúng theo lược đồ và tại sao chúng không hiển thị trong sys.objects).

Bạn có thể thấy rằng các đối tượng này có những hạn chế nhất định đối với chúng, ví dụ như trong các OBJECTPROPERTY()tài liệu :

Hàm này không thể được sử dụng cho các đối tượng không nằm trong phạm vi lược đồ, chẳng hạn như kích hoạt ngôn ngữ định nghĩa dữ liệu (DDL) và thông báo sự kiện.

Và tương tự trong các OBJECTPROPERTYEX()tài liệu :

OBRIPROPERTYEX không thể được sử dụng cho các đối tượng không nằm trong phạm vi lược đồ, chẳng hạn như kích hoạt ngôn ngữ định nghĩa dữ liệu (DDL) và thông báo sự kiện.

Các OBJECT_ID()tài liệu rõ ràng hơn một chút:

Các đối tượng không nằm trong phạm vi lược đồ, chẳng hạn như trình kích hoạt DDL, có thể được truy vấn bằng cách sử dụng OBJECT_ID. Đối với các đối tượng không được tìm thấy trong chế độ xem danh mục sys.objects, hãy lấy các số nhận dạng đối tượng bằng cách truy vấn chế độ xem danh mục phù hợp. Ví dụ: để trả về số nhận dạng đối tượng của trình kích hoạt DDL, hãy sử dụng SELECT OBJECT_ID FROM sys.triggers WHERE name = 'DatabaseTriggerLog'.

Các OBJECT_NAME()tài liệu ít rõ ràng hơn, nhưng chúng đề cập đến cùng một hạn chế ngầm (nhấn mạnh của tôi):

Trả về tên đối tượng cơ sở dữ liệu cho các đối tượng trong phạm vi lược đồ .


Đối với truy vấn đầu tiên, không chắc chắn lý do tại sao bạn cần lấy tên qua hàm, vì namecột trong sys.triggersđã cung cấp cho bạn câu trả lời đó. Đối với truy vấn thứ hai, bạn chỉ cần tham gia sys.triggers:

SELECT tr.*, ts.*
FROM sys.dm_exec_trigger_stats AS ts
LEFT OUTER JOIN sys.triggers AS tr
ON ts.[object_id] = tr.[object_id];

Tất nhiên, bạn có thể tạo chức năng của riêng mình, nhưng tôi không biết bất kỳ chức năng tích hợp nào thực hiện mối tương quan này cho bạn (và tôi khuyên bạn nên tránh xa các chức năng siêu dữ liệu tích hợp ).

Kích hoạt DDL là một loại động vật đặc biệt. Vì vậy, nếu bạn lo lắng về việc cũng phải tham gia vào sys.procedures, sys.view, v.v., thì không.


Cảm ơn, Aaron. Không, tôi chỉ thấy lạ là họ không giải quyết bình thường . Vui mừng vì thịt kỳ lạ đã không giết bạn;)
Erik Darling
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.