共用方式為


SqlContext 物件

當您呼叫程序或函數、在 Common Language Runtime (CLR) 使用者定義型別上呼叫方法,或您的動作引發以任何 Microsoft .NET Framework 語言定義的觸發程序時,會在伺服器中叫用 Managed 程式碼。因為要求執行此程式碼做為使用者連接的一部分,所以需要從伺服器上執行的程式碼,存取呼叫端的內容。此外,特定資料存取作業只有在呼叫端的內容下執行才會有效。例如,對在觸發程序作業中使用之插入及刪除虛擬資料表的存取,只有在呼叫端的內容下才有效。

呼叫端的內容會在 SqlContext 物件中擷取。如需有關 SqlTriggerContext 方法和屬性的詳細資訊,請參閱 .NET Framework SDK 中的 Microsoft.SqlServer.Server.SqlTriggerContext 類別參考文件。

SqlContext 會提供下列元件的存取:

  • SqlPipe:SqlPipe 物件表示結果藉以流向用戶端的「管道」。如需有關 SqlPipe 物件的詳細資訊,請參閱<SqlPipe 物件>。

  • SqlTriggerContext:SqlTriggerContext 物件只能在 CLR 觸發程序內擷取。它提供造成引發觸發程序的作業及已更新資料行之對應的相關資訊。如需有關 SqlTriggerContext 物件的詳細資訊,請參閱<SqlTriggerContext 物件>。

  • IsAvailable:IsAvailable 屬性用於判斷內容可用性。

  • WindowsIdentity:WindowsIdentity 屬性用於擷取呼叫端的 Windows 識別。

決定內容可用性

查詢 SqlContext 類別,以查看目前執行的程式碼是否同處理序執行。若要這樣做,請檢查 SqlContext 物件的 IsAvailable 屬性。如果呼叫程式碼在 SQL Server 內執行,且可存取其他 SqlContext 成員,則 IsAvailable 屬性是唯讀的,並會傳回 True。如果 IsAvailable 屬性傳回 False,則使用的其他所有 SqlContext 成員會擲回 InvalidOperationException。如果 IsAvailable 傳回 False,則開啟連接字串中包括 "context connection=true" 之連接物件的任何嘗試都會失敗。

擷取 Windows 識別

在處理序帳戶的內容中,永遠會叫用在 SQL Server 內執行的 CLR 程式碼。如果程式碼應使用呼叫使用者的識別 (而非 SQL Server 處理序識別) 執行特定動作,則應透過 SqlContext 物件的 WindowsIdentity 屬性取得模擬 Token。WindowsIdentity 屬性會傳回表示呼叫端之 Microsoft Windows 識別的 WindowsIdentity 執行個體,或者,如果使用 SQL Server 驗證來驗證用戶端,則會傳回 Null。只有以 EXTERNAL_ACCESS 或 UNSAFE 使用權限標記的組件才能存取此屬性。

取得 WindowsIdentity 物件之後,呼叫端可以模擬用戶端帳戶,並代表它執行動作。

如果開始執行預存程序或函數的用戶端連接至使用 Windows 驗證的伺服器,則只能透過 SqlContext.WindowsIdentity 使用呼叫端的識別。如果改用 SQL Server 驗證,則此屬性為 Null,而且程式碼無法模擬呼叫端。CodePlex 上的模擬範例將示範如何使用模擬;如需詳細資訊,請參閱<SQL Server Database Engine 範例>。

範例

下列範例示範如何取得呼叫用戶端的 Windows 識別以及模擬該用戶端。

C#

[Microsoft.SqlServer.Server.SqlProcedure]
public static void WindowsIDTestProc()
{
    WindowsIdentity clientId = null;
    WindowsImpersonationContext impersonatedUser = null;

    // Get the client ID.
    clientId = SqlContext.WindowsIdentity;

    // This outer try block is used to thwart exception filter 
    // attacks which would prevent the inner finally 
    // block from executing and resetting the impersonation.
    try
    {
        try
        {
            impersonatedUser = clientId.Impersonate();
            if (impersonatedUser != null)
            {
                // Perform some action using impersonation.
            }
        }
        finally
        {
            // Undo impersonation.
            if (impersonatedUser != null)
                impersonatedUser.Undo();
        }
    }
    catch
    {
        throw;
    }
}

Visual Basic

<Microsoft.SqlServer.Server.SqlProcedure()> _
Public Shared Sub  WindowsIDTestProcVB ()
    Dim clientId As WindowsIdentity
    Dim impersonatedUser As WindowsImpersonationContext

    ' Get the client ID.
    clientId = SqlContext.WindowsIdentity

    ' This outer try block is used to thwart exception filter 
    ' attacks which would prevent the inner finally 
    ' block from executing and resetting the impersonation.

    Try
        Try

            impersonatedUser = clientId.Impersonate()

            If impersonatedUser IsNot Nothing Then
                ' Perform some action using impersonation.
            End If

        Finally
            ' Undo impersonation.
            If impersonatedUser IsNot Nothing Then
                impersonatedUser.Undo()
            End If
        End Try

    Catch e As Exception

        Throw e

    End Try
End Sub