2012-07-30 43 views
3

我目前正在使用Master數據庫的CONTEXT_INFO屬性來存儲登錄的用戶名,以便稍後在表觸發器中進行審計。替換Context_Info SQL Azure

在遷移到SQL Azure時,跨數據庫連接問題突然出現,我無法找到針對此問題的直接解決方案。

以下是問題的詳細信息:

  1. 我打電話從數據訪問層存儲過程XXX並通過用戶名作爲參數
  2. 的用戶名被用於在XXX
  3. 的CONTEXT_INFO設置CONTEXT_INFO值值然後用於表插入/更新/刪除觸發器,以存儲用戶名的應用程序審計

的解決方案,我發現迄今:

  1. 創建表在數據庫中的數據訪問層工作,因爲CONTEXT_INFO
  2. 使用2連接字符串,一個主數據庫(設置CONTEXT_INFO),另一個是應用程序之前執行SET CONTEXT_INFO每次打開我的應用程序的連接

但我覺得這兩種解決方案都有風險,特別是將來在多個SQL Azure數據庫上擴展數據庫時。

感謝您的支持。

回答

4

我採取的方法如下所示。關於技巧是檢查運行沒有運行在SQL Azure上,那麼我們需要調用'SET CONTEXT_INFO ...'。這允許在本地SQL Server Express和Azure上執行相同的代碼而不做任何更改。

  1. 創建一個表來存儲上下文信息(不是高手,但在同一個數據庫)

    CREATE TABLE [dbo].[ContextInfo] (
        [ContextInfo] varbinary(128) not null, 
        [ApplicationUsername] nvarchar(128) not null, 
        [UpdatedAt] datetime NOT NULL, 
        CONSTRAINT [PK_UserContextInfo] PRIMARY KEY CLUSTERED ([ContextInfo] ASC) 
    ) 
    
  2. 創建一個存儲過程,以「設置上下文信息」這是從應用

    稱爲
    CREATE PROCEDURE [dbo].[SetContextInfo] 
        @ApplicationUsername nvarchar(128) 
    AS 
    
    SET NOCOUNT ON 
    
    -- Remove all context items older than an 5 minutes ago 
    DELETE 
        FROM [dbo].[ContextInfo] 
    WHERE [UpdatedAt] < DATEADD(mi, -5, GETUTCDATE()) 
    
    -- 
    -- Use the MERGE command to do an update/insert 
    -- See: http://technet.microsoft.com/en-us/library/bb510625.aspx 
    -- 
    
    IF SERVERPROPERTY('edition') <> 'SQL Azure' 
    BEGIN 
        DECLARE @b varbinary(128) 
        SET @b = CONVERT(varbinary(128),newid()) 
        EXEC sp_executesql @statement=N'SET CONTEXT_INFO @b',@params=N'@b varbinary(128)',@[email protected] 
    END 
    
    DECLARE @ContextInfo varbinary(128) 
    SELECT @ContextInfo = CONTEXT_INFO() 
    
    MERGE [dbo].[ContextInfo] AS target 
    USING (SELECT @ContextInfo, @ApplicationUsername) AS source ([ContextInfo], [ApplicationUsername]) 
        ON (target.[ContextInfo] = source.[ContextInfo]) 
    WHEN MATCHED THEN 
         UPDATE SET [ApplicationUsername] = source.[ApplicationUsername], [UpdatedAt] = GETUTCDATE() 
    WHEN NOT MATCHED THEN 
         INSERT ([ContextInfo], [ApplicationUsername], [UpdatedAt]) 
         VALUES (source.[ContextInfo], source.[ApplicationUsername], GETUTCDATE()); 
    
  3. 創建一個存儲過程,以 '獲取上下文信息'

    CREATE PROCEDURE [dbo].[GetContextInfo] 
    AS 
        SET NOCOUNT ON 
        DECLARE @ContextInfo varbinary(128) 
        SELECT @ContextInfo = CONTEXT_INFO() 
    
        SELECT [ApplicationUsername] 
         FROM [dbo].[ContextInfo] 
        WHERE [ContextInfo] = @ContextInfo 
    GO 
    
  4. 在觸發源,使用方法:

    DECLARE @UserContext TABLE ([Username] VARCHAR(128)) 
    INSERT INTO @UserContext (Username) 
    EXEC [dbo].[GetContextInfo] 
    

現在,你必須存儲在表變量名。如果您的應用程序之外的管理員應用了更改,則可能還需要檢查用戶名是否未設置,並且默認爲* SYSTEM_USER *。

+0

非常感謝Phil,但是如果我使用Table解決方案,則不需要再使用CONTEXT_INFO。 – 2012-11-19 09:00:03