Làm thế nào để kiểm tra tất cả các thủ tục được lưu trữ là ok trong máy chủ sql nếu tôi thả một bảng hoặc các lĩnh vực?Làm thế nào để kiểm tra tất cả các thủ tục lưu trữ là ok trong máy chủ sql?
Trả lời
Couple cách mà đến với tâm trí
- cách rõ ràng Hầu hết chạy thủ tục
- kiểm tra phụ thuộc trên bàn trước khi bạn thả các bảng hoặc một lĩnh vực. sau đó kiểm tra những proceudres phụ thuộc
- tạo ra các script trên tất cả các thủ tục và tìm kiếm các lĩnh vực đó hoặc bảng
- Query sysobjects
Nó sẽ không bắt tất cả mọi thứ (SQL động hoặc đối tượng latebound), nhưng nó có thể hữu ích - gọi sp_refreshsqlmodule trên tất cả các phi schema thủ tục lưu trữ bị ràng buộc (bạn có thể gọi nó trước để đảm bảo rằng phụ thuộc được cập nhật và sau đó truy vấn phụ thuộc, hay gọi nó là sau đó và xem nếu bất cứ điều gì bị tổn thương):
DECLARE @template AS varchar(max)
SET @template = 'PRINT ''{OBJECT_NAME}''
EXEC sp_refreshsqlmodule ''{OBJECT_NAME}''
'
DECLARE @sql AS varchar(max)
SELECT @sql = ISNULL(@sql, '') + REPLACE(@template, '{OBJECT_NAME}',
QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME))
FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
EXEC (
@sql
)
tôi tìm thấy câu trả lời của Cade eful trong việc xây dựng kịch bản của riêng tôi để kiểm tra các đối tượng trong một cơ sở dữ liệu, vì vậy tôi nghĩ rằng tôi muốn chia sẻ kịch bản của tôi cũng như:
DECLARE @Name nvarchar(1000);
DECLARE @Sql nvarchar(1000);
DECLARE @Result int;
DECLARE ObjectCursor CURSOR FAST_FORWARD FOR
SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(OBJECT_NAME(o.object_id))
FROM sys.objects o
WHERE type_desc IN (
'SQL_STORED_PROCEDURE',
'SQL_TRIGGER',
'SQL_SCALAR_FUNCTION',
'SQL_TABLE_VALUED_FUNCTION',
'SQL_INLINE_TABLE_VALUED_FUNCTION',
'VIEW')
--include the following if you have schema bound objects since they are not supported
AND ISNULL(OBJECTPROPERTY(o.object_id, 'IsSchemaBound'), 0) = 0
;
OPEN ObjectCursor;
FETCH NEXT FROM ObjectCursor INTO @Name;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Sql = N'EXEC sp_refreshsqlmodule ''' + @Name + '''';
--PRINT @Sql;
BEGIN TRY
EXEC @Result = sp_executesql @Sql;
IF @Result <> 0 RAISERROR('Failed', 16, 1);
END TRY
BEGIN CATCH
PRINT 'The module ''' + @Name + ''' does not compile.';
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
END CATCH
FETCH NEXT FROM ObjectCursor INTO @Name;
END
CLOSE ObjectCursor;
DEALLOCATE ObjectCursor;
Cách duy nhất để làm mới bộ kích hoạt là thay đổi chúng nếu không được mã hóa. (http://connect.microsoft.com/SQLServer/feedback/details/261905/sp-refreshsqlmodule-does-not-work-with-triggers). Vì vậy, kịch bản trên cho phép tích cực sai khi nó gặp một kích hoạt – buckley
Điều này làm việc thực sự tốt cho tôi. (mặc dù tôi không có bất kỳ kích hoạt nào) – ClearCloud8
Bài đăng hay, hoạt động hoàn hảo! Một bổ sung nữa, bạn phải kiểm tra xem đối tượng có phải là lược đồ bị ràng buộc như sp_refreshsqlmodule hay không sẽ cung cấp các phần tử phủ định sai khi các đối tượng liên kết lược đồ không được hỗ trợ. Vì vậy, thêm vào truy vấn của bạn như sau: và \t isnull (objectproperty (o.object_id, 'IsSchemaBound'), 0) = 0 \t; –
Ngoài kịch bản từ Michael Petito bạn có thể kiểm tra xem có vấn đề với các đối tượng cuối-bound trong SPs (chậm phân giải tên) như thế này:
-- Based on comment from http://blogs.msdn.com/b/askjay/archive/2012/07/22/finding-missing-dependencies.aspx
-- Check also http://technet.microsoft.com/en-us/library/bb677315(v=sql.110).aspx
select o.type, o.name, ed.referenced_entity_name, ed.is_caller_dependent
from sys.sql_expression_dependencies ed
join sys.objects o on ed.referencing_id = o.object_id
where ed.referenced_id is null
Vấn đề là nó vẫn sẽ trả về các bí danh CTE và các bảng tạm thời dưới dạng tham chiếu null. –
tôi đã cố gắng "Cade Roux" trả lời, nó đã đi sai và tôi cố định nó như sau
SELECT 'BEGIN TRAN T1;' UNION
SELECT REPLACE('BEGIN TRY
EXEC sp_refreshsqlmodule ''{OBJECT_NAME}''
END TRY
BEGIN CATCH
PRINT ''{OBJECT_NAME} IS INVALID.''
END CATCH', '{OBJECT_NAME}',
QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME))
FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
UNION
SELECT 'ROLLBACK TRAN T1;'
Vui lòng định dạng mã. – rajuGT
tôi về cơ bản đã làm điều tương tự, nhưng đã viết nó để KHÔNG CURSORless siêu nhanh.
DECLARE @Name nvarchar(1000);
DECLARE @Sql nvarchar(1000);
DECLARE @Result int;
DECLARE @Objects TABLE (
Id INT IDENTITY(1,1),
Name nvarchar(1000)
)
INSERT INTO @Objects
SELECT QUOTENAME(SCHEMA_NAME(o.schema_id)) + '.' + QUOTENAME(OBJECT_NAME(o.object_id))
FROM sys.objects o
WHERE type_desc IN (
'SQL_STORED_PROCEDURE',
'SQL_TRIGGER',
'SQL_SCALAR_FUNCTION',
'SQL_TABLE_VALUED_FUNCTION',
'SQL_INLINE_TABLE_VALUED_FUNCTION',
'VIEW')
--include the following if you have schema bound objects since they are not supported
AND ISNULL(OBJECTPROPERTY(o.object_id, 'IsSchemaBound'), 0) = 0
DECLARE @x INT
DECLARE @xMax INT
SELECT @xMax = MAX(Id) FROM @Objects
SET @x = 1
WHILE @x < @xMax
BEGIN
SELECT @Name = Name FROM @Objects WHERE Id = @x
SET @Sql = N'EXEC sp_refreshsqlmodule ''' + @Name + '''';
--PRINT @Sql;
BEGIN TRY
EXEC @Result = sp_executesql @Sql;
IF @Result <> 0 RAISERROR('Failed', 16, 1);
END TRY
BEGIN CATCH
PRINT 'The module ''' + @Name + ''' does not compile.';
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
END CATCH
SET @x = @x + 1
END
Sử dụng câu lệnh while để lặp qua bảng dữ liệu về cơ bản giống như sử dụng con trỏ với fast_forward. Cả hai đều đang đi bằng hàng agonizing (RBAR). Đây là một tình huống mà nó được chấp nhận vì nó không thể được thay thế bằng một hoạt động dựa trên bộ. – Nicholas
Con trỏ không hoạt động hiệu quả. Họ là những con heo nhớ. –
Điều này thực hiện tốt hơn một chút so với sử dụng con trỏ, ngay cả khi nó vẫn sử dụng vòng lặp while. –
Dường sp_refreshsqlmodule [có thể kết thúc làm mới các mô-đun sai tuy nhiên!] (Https://connect.microsoft.com/SQLServer/feedback/details/656863/sp-refreshsqlmodule-corrupts-renamed-objects-definitions) –
@Martin Vâng, tôi nên đề cập đến điều đó. Trong trường hợp của tôi, bởi vì nó là ALTER và không có thủ tục nào khác sử dụng cùng tên, tôi gặp lỗi, nó không làm hại gì cả. –