Làm thế nào tôi có thể phát hiện các thủ tục lưu trữ bị hỏng sau khi thay đổi lược đồ?


11

Tôi đã sửa đổi một bảng trung tâm trong cơ sở dữ liệu của mình và sp_depends thực sự trả về hàng trăm kết quả và tôi lo ngại một số quy trình được lưu trữ đó có thể không được biên dịch nữa sau khi tôi thay đổi.

Kiểm tra một thủ tục được lưu trữ là dễ dàng (tôi chỉ chạy lại tập lệnh thay đổi và xem liệu thao tác có thành công hay không), nhưng thực hiện điều đó trên 100 thủ tục thì hơi phức tạp.

Tôi biết tôi có thể sử dụng một tập lệnh như thế này để biên dịch lại tất cả các đối tượng của cơ sở dữ liệu của mình, nhưng hoạt động thực tế sẽ diễn ra vào lần tới khi thủ tục được lưu trữ được thực thi, không phải ngay lập tức, vì vậy có vẻ không phù hợp trong trường hợp của tôi.

Tôi cũng đã nghĩ rằng tôi có thể bỏ hoàn toàn tất cả các thủ tục được lưu trữ và tái cấu trúc lại cơ sở dữ liệu của mình với hệ thống kiểm soát nguồn của mình, nhưng tùy chọn đó, mặc dù khả thi, nhưng không thanh lịch lắm. Có cách nào tốt hơn để làm điều này?

Tôi đang sử dụng SQLServer 2008 R2 và các tập lệnh cơ sở dữ liệu của tôi được lưu trữ trong dự án cơ sở dữ liệu VS 2008.


Để làm rõ, tôi không ủng hộ người ta chỉ nên dựa vào cách tiếp cận này để kiểm tra mã. Cũng giống như trong c # bạn ngay lập tức phát hiện lỗi cú pháp trong các tệp phụ thuộc khác khi bạn viết mã (và sau đó sử dụng các chiến lược khác để kiểm tra, chẳng hạn như kiểm tra đơn vị, thường chậm hơn vài bậc), tôi nghĩ sẽ hợp lý khi phát hiện các phụ thuộc SQL lỗi trong vài giây thay vì phải chạy một bài kiểm tra chức năng đầy đủ, thường có thể mất vài giờ để hoàn thành.

Câu trả lời:


7

Làm thế nào về bạn chạy đơn vị, kiểm tra chức năng, tích hợp và hiệu suất của bạn? Nếu bạn không có bất kỳ thử nghiệm nào thì đây là thời gian nghiêm túc để bắt đầu xem xét lược đồ cơ sở dữ liệu của bạn dưới dạng và xử lý nó như vậy, bao gồm kiểm soát phiên bản và thử nghiệm. Alex Kuznetsov có toàn bộ cuốn sách dành riêng cho chủ đề này: Lập trình cơ sở dữ liệu phòng thủ với SQL Server .


Các thử nghiệm không phải lúc nào cũng bao gồm 100% mã và khi thực hiện, chúng thường mất vài giờ để chạy. Trong c #, tôi có thể phát hiện xem mã của mình có còn biên dịch sau vài giây hay không (bất kể tính chính xác của nó). Điều này không có nghĩa là tôi nên đẩy mã (bất kể mã là c # hoặc PLSQL) vào sản xuất mà không kiểm tra đúng cách, nhưng có vẻ không hợp lý khi có cách nhanh chóng phát hiện các phụ thuộc bị hỏng, phải không?
Brann

2
Thật không may, trạng thái hiện đại của SQL Server hiện tại phát hiện phụ thuộc trực quan trong thủ tục được lưu trữ là 'bị phá vỡ sâu sắc', xem Hiểu phụ thuộc SQL hoặc Luôn cập nhật sysdepends trong SQL Server 2008 . Thậm chí có những công cụ của bên thứ ba đang cố gắng giải quyết vấn đề
Remus Rusanu

2
Điều này làm cho các bài kiểm tra đơn vị / chức năng gần như là cách đáng tin cậy duy nhất để phát hiện các thay đổi vi phạm.
Remus Rusanu

1
Để kiểm tra nhanh, Dự án cơ sở dữ liệu Visual Studio thực hiện một công việc khá tốt trong việc xác nhận bất kỳ thay đổi nào.
Remus Rusanu

4

Đó là một công việc xung quanh, nhưng bạn có thể tạo tập lệnh CREATE PROCEDURE cho cơ sở dữ liệu (cơ sở dữ liệu nhấp chuột phải -> tác vụ -> tạo tập lệnh), tìm và thay thế TẠO QUY TRÌNH bằng THỦ TỤC THAY ĐỔI rồi phân tích cú pháp.

Tôi hy vọng bạn nhận được câu trả lời tốt hơn ở đây - Tôi cũng quan tâm! :)


Tôi không đánh dấu câu trả lời của bạn là được chấp nhận vì tôi vẫn hy vọng giải pháp sạch hơn (hy vọng là giải pháp có thể viết được), nhưng bạn chắc chắn nhận được +1 của mình! Cảm ơn.
Brann

3
Cách tiếp cận này sẽ không cho bạn biết nếu bạn đang tham khảo một bảng không tồn tại .
Nick Chammas

Cách tiếp cận này cũng sẽ không hiệu quả nếu tập lệnh được tạo lớn hơn khoảng 30 nghìn dòng. Tôi ghét rằng tôi biết điều này ..
Eonasdan

3

Bạn có thể sử dụng Công cụ dữ liệu máy chủ Sql (SSDT). Microsoft Visual Studio cho phép bạn tạo một dự án Sql Server. Một sau đó nhập cơ sở dữ liệu vào dự án và sau đó xây dựng dự án. Nếu có bất kỳ thủ tục hoặc đối tượng lưu trữ bị hỏng, bạn sẽ gặp lỗi biên dịch.


Tôi sẽ thêm rằng bạn có thể dễ dàng tạo tập lệnh tạo cơ sở dữ liệu mới từ dự án SSDT và chạy trong môi trường thử nghiệm, đây sẽ là một xác minh khá kỹ lưỡng rằng không có procs / kích hoạt / bị hỏng do thay đổi lược đồ.
AaronLS

3

Bạn có thể muốn xem xét câu hỏi SO này Tôi đang tìm kiếm một cách đáng tin cậy để xác minh các thủ tục được lưu trữ T-SQL. Có ai có một cái không? đó là hỏi về cơ bản cùng một điều, với một số câu trả lời.

Để xây dựng dựa trên kịch bản Alaa Awad đã đăng ... điều này sẽ hiển thị lược đồ và cơ sở dữ liệu của các đối tượng được tham chiếu và tham chiếu. Nếu bạn đang sử dụng nhiều bảng tạm thời thông qua các bí danh (đôi khi hiển thị khi sử dụng sys.sql_expression_dependencies), các tham số UDTT hoặc các tính năng động khác bạn có thể cần sử dụng các chức năng sys.dm_sql_referenced_entitieshoặc sys.dm_sql_referencing_entitiesthay vào đó / cũng có thể.

SELECT
    DB_NAME() + '.' + OBJECT_SCHEMA_NAME(sed.referencing_id) + '.' + OBJECT_NAME(sed.referencing_id) AS [referencingObject],
    isnull(sed.referenced_server_name + '.', '') + isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies sed
WHERE 
    sed.is_ambiguous = 0
    AND OBJECT_ID(isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name) IS NULL
ORDER BY
    [referencingObject], [missingReference]

1
Nên thêm chúng vào mệnh đề where: / * Không phải là loại người dùng hiện tại / VÀ sed.referenced_entity_name NOT IN (SELECT [name] TỪ sys.types) / Không một bí danh * / VÀ sed.referenced_schema_name IS NOT NULL
JasonBluefire

1

sử dụng sys.sql_expression_dependencies được thêm vào máy chủ sql 2008

CREATE PROCEDURE [dbo].[spMaintenance_Find_Broken_Dependencies]

AS
SELECT
    OBJECT_NAME(referencing_id) AS [referencingObject],
    referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0
    AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY 
    OBJECT_NAME(referencing_id), referenced_entity_name

GO

Điều này có thể hữu ích, tuy nhiên nó không đơn giản vì lược đồ cũng cần tính đến. Tôi cũng đang gặp vấn đề trong đó sys.sql_Exession_dependencies đang hiển thị bí danh được sử dụng thay vì bảng phụ thuộc thực tế, điều này rõ ràng không thực hiện kiểm tra object_id (). Cuối cùng, nó đưa ra các bảng do người dùng định nghĩa được chuyển dưới dạng tham số cho các thủ tục được lưu trữ - điều này không thực sự hữu ích.
Tabloo Quijico
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.