2014-12-03 23 views
7

Tôi đã tạo một SqlDependency để một sự kiện sẽ kích hoạt khi kết quả của một truy vấn cụ thể thay đổi.Mã hóa quy trình được lưu trữ được tạo bởi SqlDependency

// Create a command 
SqlConnection conn = new SqlConnection(connectionString); 
string query = "SELECT MyColumn FROM MyTable;"; 
SqlCommand cmd = new SqlCommand(query, conn) 
cmd.CommandType = CommandType.Text; 

// Register a dependency 
SqlDependency dependency = new SqlDependency(cmd); 
dependency.OnChange += DependencyOnChange; 

Khi mã này thực hiện, một thủ tục lưu trữ được tự động tạo ra với một cái tên như

SqlQueryNotificationStoredProcedure-82ae1b92-21c5-46ae-a2a1-511c4f849f76

Thủ tục này không được mã hóa, vi phạm các yêu cầu tôi đã được đưa ra. Tôi có hai lựa chọn:

  1. Thuyết phục khách hàng rằng nó không quan trọng mà tự động thủ tục tạo ra không được mã hóa bởi vì nó chỉ làm việc dọn dẹp và không chứa thông tin thực tế (nhờ ScottChamberlain cho trỏ này ra).
  2. Tìm cách mã hóa quy trình được lưu trữ do SqlDependency tạo ra.

Tôi có thể thực hiện tùy chọn 2 bằng cách nào?


Nội dung của thủ tục lưu trữ trong câu hỏi:

CREATE PROCEDURE [dbo].[SqlQueryNotificationStoredProcedure-b124707b-23fc-4002-aac3-4d52a71c5d6b] 
AS 
BEGIN 
    BEGIN TRANSACTION; 

    RECEIVE TOP (0) conversation_handle 
    FROM [SqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b]; 

    IF (
     SELECT COUNT(*) 
     FROM [SqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b] 
     WHERE message_type_name = 'http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer' 
    ) > 0 
    BEGIN 
     IF (
      ( 
       SELECT COUNT(*) 
       FROM sys.services 
       WHERE NAME = 'SqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b' 
      ) > 0 
     ) 
     DROP SERVICE [SqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b]; 

     IF (OBJECT_ID('SqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b', 'SQ') IS NOT NULL) 
      DROP QUEUE [SqlQueryNotificationService-b124707b-23fc-4002-aac3-4d52a71c5d6b]; 

     DROP PROCEDURE [SqlQueryNotificationStoredProcedure-b124707b-23fc-4002-aac3-4d52a71c5d6b]; 
    END 

    COMMIT TRANSACTION; 
END 
GO 
+0

Quy trình thực hiện yêu cầu mã hóa là gì? Tôi không có môi trường dev của tôi trước mặt tôi nhưng tôi nghĩ rằng tất cả những gì proc là để làm sạch trong trường hợp ngắt kết nối. Nó không chứa thông tin cần mã hóa (nhưng như tôi đã nói tôi không có môi trường thử nghiệm trước mặt nên tôi có thể sai). –

+0

@ScottChamberlain Tôi đã thêm nội dung của quy trình vào câu hỏi để bạn có thể xem nó. Tôi hiểu rằng các thủ tục được lưu trữ không cần phải được mã hóa, nhưng tôi có một yêu cầu nói rằng nó phải được mã hóa. Tôi có thể đẩy lùi, và khách hàng có thể làm ngoại lệ cho tôi, nhưng đó không phải là vấn đề. – Rainbolt

+0

Bạn đã thử VỚI ENCRYPTION chưa? – idstam

Trả lời

4

Tạo trình kích hoạt DDL để kiểm tra nếu một thủ tục với một cái tên như "SqlQueryNotificationStoredProcedure-" đã được tạo ra, và nếu như vậy, ngay lập tức thay đổi nó WITH ENCRYPTION thay thế:

CREATE TRIGGER [TR_EncryptQueryNotificationProcedures] 
ON DATABASE 
AFTER CREATE_PROCEDURE, ALTER_PROCEDURE 
AS 
BEGIN 
    SET ARITHABORT ON; 
    SET NOCOUNT ON; 
    IF TRIGGER_NESTLEVEL() > 1 RETURN; 

    -- For debugging purposes only 
    PRINT CONVERT(NVARCHAR(MAX), EVENTDATA()); 

    DECLARE @DatabaseName NVARCHAR(128); 
    SET @DatabaseName = EVENTDATA().value(
     '(/EVENT_INSTANCE/DatabaseName)[1]', 'NVARCHAR(128)' 
    ); 
    DECLARE @Schema NVARCHAR(128); 
    SET @Schema = EVENTDATA().value(
     '(/EVENT_INSTANCE/SchemaName)[1]', 'NVARCHAR(128)' 
    ); 
    DECLARE @Name NVARCHAR(128); 
    SET @Name = EVENTDATA().value(
     '(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(128)' 
    ); 

    DECLARE @Definition NVARCHAR(MAX); 
    SELECT @Definition = 
     OBJECT_DEFINITION(
      OBJECT_ID(
       QUOTENAME(@DatabaseName) + '.' + 
       QUOTENAME(@Schema) + '.' + 
       QUOTENAME(@Name), 
       'P' 
      ) 
     ) 
    ; 

    -- If the sproc is already encrypted, we can't do anything with it 
    IF @Definition IS NULL RETURN; 

    SELECT @Definition = STUFF(
     @Definition, 
     CHARINDEX('CREATE', @Definition), 
     LEN('CREATE'), 
     'ALTER' 
    ); 

    IF 
     @Name LIKE 'SqlQueryNotificationStoredProcedure-%' AND 
     -- this should always be false since we can't read encrypted definitions, 
     -- but just to make sure 
     @Definition NOT LIKE '%WITH ENCRYPTION AS BEGIN%' 
    BEGIN; 
     SET @Definition = REPLACE(
      @Definition, 'AS' + CHAR(13) + CHAR(10) + 'BEGIN', 
      'WITH ENCRYPTION AS BEGIN' 
     ); 
     EXEC (@Definition); 
    END; 
END; 
GO 
ENABLE TRIGGER [TR_EncryptQueryNotificationProcedures] ON DATABASE; 

Tuyên bố từ chối: không được kiểm tra với thông báo phụ thuộc thực tế, nhưng ý tưởng cơ bản là âm thanh. Nó khá giòn vì nó phụ thuộc vào hình thức chính xác của thủ tục, tất nhiên - làm cho nó mạnh mẽ hơn là có thể, nhưng tẻ nhạt.

+0

Điều này thực sự gọn gàng. Tôi không có ý tưởng rằng bạn có thể thay đổi SQL trong khi nó đang được chuyển tiếp. Tôi sẽ xem xét việc loại bỏ '@Name LIKE 'SqlQueryNotificationStoredProcedure -%'' điều kiện vì nó là dự phòng. Tôi sẽ chấp nhận câu trả lời này khi tôi có thời gian để kiểm tra. – Rainbolt

+0

@Rainbolt: điều này không chính xác thay đổi nó trong khi quá cảnh - thủ tục lưu trữ thực sự được tạo trước, sau đó một 'ALTER' riêng biệt được ban hành để thay đổi thủ tục lưu sẵn mà chúng ta vừa tạo ra. Hiệu ứng ròng là như nhau, nhưng sự khác biệt có thể quan sát được đối với những thứ như kiểm tra, sao chép và theo dõi hồ sơ. –

+0

@Rainbolt: việc kiểm tra tên không chính xác là thừa, bởi vì chúng tôi đang thực hiện thay thế văn bản trên một quy trình mà chúng tôi giả định có một biểu mẫu cụ thể. Nó luôn luôn là một ý tưởng tốt để làm cho rằng càng mạnh càng tốt (đó là: càng cụ thể càng tốt). Cụ thể, trình kích hoạt này không thành công nếu quy trình được lưu trữ chứa "AS \ nBEGIN" ở bất kỳ nơi nào khác trong văn bản, điều này là không thể xảy ra nhưng không phải là không thể. Nhưng có lẽ tôi quá thận trọng với những thứ này. :-) –

Các vấn đề liên quan