Là một phần của một số tác vụ quản trị, chúng tôi có nhiều bảng mà mỗi trình kích hoạt cần tạo. Trình kích hoạt sẽ thiết lập một cờ và ngày trong cơ sở dữ liệu Kiểm toán khi một đối tượng đã được sửa đổi. Để đơn giản, tôi có một bảng với tất cả các đối tượng cần kích hoạt được tạo ra.lỗi sql động: 'TẠO TRIGGER' phải là câu lệnh đầu tiên trong lô truy vấn
Tôi cố gắng để tạo ra một số sql năng động để làm điều này cho từng đối tượng, nhưng tôi nhận được lỗi này:
'CREATE TRIGGER' must be the first statement in a query batch.
Đây là đoạn mã để tạo ra sql.
CREATE PROCEDURE [spCreateTableTriggers]
AS
BEGIN
DECLARE @dbname varchar(50),
@schemaname varchar(50),
@objname varchar(150),
@objtype varchar(150),
@sql nvarchar(max),
@CRLF varchar(2)
SET @CRLF = CHAR(13) + CHAR(10);
DECLARE ObjectCursor CURSOR FOR
SELECT DatabaseName,SchemaName,ObjectName
FROM Audit.dbo.ObjectUpdates;
SET NOCOUNT ON;
OPEN ObjectCursor ;
FETCH NEXT FROM ObjectCursor
INTO @dbname,@schemaname,@objname;
WHILE @@FETCH_STATUS=0
BEGIN
SET @sql = N'USE '+QUOTENAME(@dbname)+'; '
SET @sql = @sql + N'IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'''+QUOTENAME(@schemaname)+'.[Tiud_'[email protected]+'_AuditObjectUpdates]'')) '
SET @sql = @sql + N'BEGIN DROP TRIGGER '+QUOTENAME(@schemaname)+'.[Tiud_'[email protected]+'_AuditObjectUpdates]; END; '[email protected]
SET @sql = @sql + N'CREATE TRIGGER '+QUOTENAME(@schemaname)+'.[Tiud_'[email protected]+'_AuditObjectUpdates] '[email protected]
SET @sql = @sql + N' ON '+QUOTENAME(@schemaname)+'.['[email protected]+'] '[email protected]
SET @sql = @sql + N' AFTER INSERT,DELETE,UPDATE'[email protected]
SET @sql = @sql + N'AS '[email protected]
SET @sql = @sql + N'IF EXISTS(SELECT * FROM Audit.dbo.ObjectUpdates WHERE DatabaseName = '''[email protected]+''' AND ObjectName = '''[email protected]+''' AND RequiresUpdate=0'[email protected]
SET @sql = @sql + N'BEGIN'[email protected]
SET @sql = @sql + N' SET NOCOUNT ON;'[email protected]
SET @sql = @sql + N' UPDATE Audit.dbo.ObjectUpdates'[email protected]
SET @sql = @sql + N' SET RequiresUpdate = 1'[email protected]
SET @sql = @sql + N' WHERE DatabaseName = '''[email protected]+''' '[email protected]
SET @sql = @sql + N' AND ObjectName = '''[email protected]+''' '[email protected]
SET @sql = @sql + N'END' [email protected]
SET @sql = @sql + N'ELSE' [email protected]
SET @sql = @sql + N'BEGIN' [email protected]
SET @sql = @sql + N' SET NOCOUNT ON;' [email protected]
SET @sql = @sql + @CRLF
SET @sql = @sql + N' -- Update ''SourceLastUpdated'' date.'[email protected]
SET @sql = @sql + N' UPDATE Audit.dbo.ObjectUpdates'[email protected]
SET @sql = @sql + N' SET SourceLastUpdated = GETDATE() '[email protected]
SET @sql = @sql + N' WHERE DatabaseName = '''[email protected]+''' '[email protected]
SET @sql = @sql + N' AND ObjectName = '''[email protected]+''' '[email protected]
SET @sql = @sql + N'END; '[email protected]
--PRINT(@sql);
EXEC sp_executesql @sql;
FETCH NEXT FROM ObjectCursor
INTO @dbname,@schemaname,@objname;
END
CLOSE ObjectCursor ;
DEALLOCATE ObjectCursor ;
END
Nếu tôi sử dụng PRINT
và dán đoạn mã vào một cửa sổ truy vấn mới, các đoạn mã thực thi mà không cần bất kỳ vấn đề.
Tôi đã xóa các tuyên bố GO
vì điều này cũng gây ra lỗi.
Tôi đang thiếu gì?
Tại sao tôi gặp lỗi khi sử dụng EXEC(@sql);
hoặc thậm chí EXEC sp_executesql @sql;
?
Đây có phải là điều cần làm với ngữ cảnh trong phạm vi EXEC()
không?
Cảm ơn rất nhiều vì đã giúp đỡ.
Rất cám ơn vì điều này. Giờ đây tôi đã chia mã thành hai phần '' như bạn đề xuất trong tùy chọn đầu tiên ở trên, như sau: – MarkusBee
[EDIT đã hết thời gian trên nhận xét trước.] Rất cám ơn. Tôi đã chia mã thành hai phần '' như bạn đề xuất trong tùy chọn đầu tiên của mình. Phần đầu tiên thực hiện hoàn hảo. Tôi sẽ làm rõ rằng quy trình được thực hiện từ cơ sở dữ liệu 'Kiểm toán' và các đối tượng yêu cầu trình kích hoạt nằm trong các cơ sở dữ liệu khác. Việc thi hành câu lệnh 'CREATE TRIGGER' bây giờ ném lỗi sau, ngay cả khi sử dụng tên bảng đầy đủ: " Không thể tạo trình kích hoạt trên [...] vì đích không nằm trong cơ sở dữ liệu hiện tại. " Có cách nào xung quanh vấn đề này không? Làm thế nào tôi có thể làm cho nó thực thi trong bối cảnh của cơ sở dữ liệu khác? Cảm ơn. – MarkusBee
@markb: Vui lòng xem cập nhật của tôi. Tôi không chắc liệu mọi thứ có rõ ràng như tôi muốn hay không, vì vậy xin đừng ngần ngại hỏi. –