2010-06-12 6 views

Trả lời

2

Couple cách mà đến với tâm trí

  1. cách rõ ràng Hầu hết chạy thủ tục
  2. 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
  3. 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
  4. Query sysobjects
6

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 
      ) 
+1

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) –

+0

@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ả. –

42

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; 
+2

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

+0

Đ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

+4

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; –

2

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 
+0

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. –

1

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;' 
+0

Vui lòng định dạng mã. – rajuGT

3

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 
+1

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

+0

Con trỏ không hoạt động hiệu quả. Họ là những con heo nhớ. –

+0

Đ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. –