Share via


SqlContext 物件

適用於:SQL Server

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

呼叫端的內容會在 SqlCoNtext 物件中抽象化。 如需SqlTriggerCoNtext方法和屬性的詳細資訊,請參閱 .NET Framework SDK 中的Microsoft.SqlServer.Server.SqlTriggerCoNtext類別參考檔。

SqlCoNtext 提供下列元件的存取權:

  • SqlPipeSqlPipe 物件代表結果流向用戶端的「管道」。 如需 SqlPipe 物件的詳細資訊,請參閱 SqlPipe 物件

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

  • IsAvailableIsAvailable 屬性是用來判斷內容可用性。

  • WindowsIdentityWindowsIdentity 屬性是用來擷取呼叫者的 Windows 身分識別。

決定內容可用性

查詢 SqlCoNtext 類別,以查看目前正在執行的程式碼是否正在進程中執行。 若要這樣做,請檢查SqlCoNtext物件的IsAvailable屬性。 IsAvailable屬性是唯讀的,如果呼叫程式碼是在SQL Server內執行,而且如果可以存取其他SqlCoNtext成員,則會傳回True。 如果IsAvailable屬性傳回False,則如果使用了 InvalidOperationException,所有其他SqlCoNtext成員都會擲回 InvalidOperationException。 如果 IsAvailable 傳回 False,則嘗試開啟連接字串中具有 「coNtext connection=true」 的連線物件會失敗。

擷取 Windows 識別

在處理序帳戶的內容中,永遠會叫用在 SQL Server 內執行的 CLR 程式碼。 如果程式碼應該使用呼叫使用者的身分識別來執行特定動作,而不是SQL Server進程識別,則應該透過SqlCoNtext物件的WindowsIdentity屬性取得模擬權杖。 WindowsIdentity屬性會傳回代表呼叫端 Microsoft Windows 身分識別的WindowsIdentity實例,如果用戶端是使用 SQL Server Authentication 進行驗證,則傳回 null。 只有標示 EXTERNAL_ACCESSUNSAFE 許可權的元件才能存取此屬性。

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

如果起始執行預存程式或函式的用戶端使用 Windows 驗證,則呼叫端的身分識別只能透過 SqlCoNtext.WindowsIdentity 取得。 如果使用 SQL Server 驗證來代替,則此屬性為 Null,而且程式碼無法模擬呼叫端。

範例

下列範例示範如何取得呼叫用戶端的 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  

另請參閱

SqlPipe 物件
SqlTriggerContext 物件
CLR 觸發程序
ADO.NET 的 SQL Server 同處理序特定擴充