當您呼叫程式或函式、在 Common Language Runtime (CLR) 使用者定義型別上呼叫方法,或當您的動作引發任何Microsoft .NET Framework 語言中定義的觸發程式時,請在伺服器中叫用 Managed 程式代碼。 由於執行此程式代碼是要求作為用戶連線的一部分,因此需要從伺服器中執行之程式代碼存取呼叫端的內容。 此外,只有在呼叫端的內容下執行時,特定數據存取作業才有效。 例如,存取觸發程式作業中使用的插入和刪除虛擬數據表,只有在呼叫端的內容下才有效。
呼叫者的內容會在 SqlContext 物件中抽象化。 如需方法和屬性的詳細資訊 SqlTriggerContext ,請參閱 Microsoft.SqlServer.Server.SqlTriggerContext .NET Framework SDK 中的類別參考檔。
SqlContext 提供下列元件的存取權:
SqlPipe:物件SqlPipe代表結果流向用戶端的「管道」。 如需對象的詳細資訊SqlPipe,請參閱 SqlPipe 物件。SqlTriggerContextSqlTriggerContext:物件只能從 CLR 觸發程式內擷取。 它提供導致觸發程式引發之作業的相關信息,以及已更新之數據行的對應。 如需對象的詳細資訊SqlTriggerContext,請參閱 SqlTriggerContext 物件。IsAvailable:屬性IsAvailable是用來判斷內容可用性。WindowsIdentity:屬性WindowsIdentity是用來擷取呼叫端的 Windows 身分識別。
判斷內容可用性
查詢 類別 SqlContext ,以查看目前執行的程式代碼是否正在進程內執行。 若要這樣做,請檢查 IsAvailable 對象的屬性 SqlContext 。
IsAvailable 屬性是唯讀的,如果呼叫程式代碼是在 SQL Server 內執行,而且如果可以存取其他 True 成員,則會傳回 SqlContext。 如果 IsAvailable 屬性傳回 False,則所有其他 SqlContext 成員都會擲回 InvalidOperationException,如果使用的話。 如果 IsAvailable 傳回 False,則任何嘗試開啟連接字串中有 “context connection=true” 的連接物件會失敗。
擷取 Windows 身分識別
在 SQL Server 內執行的 CLR 程式代碼一律會在行程帳戶的內容中叫用。 如果程式代碼應該使用呼叫使用者的身分識別來執行特定動作,而不是 SQL Server 進程識別,則應該透過 WindowsIdentity 物件的 SqlContext 屬性來取得模擬令牌。 屬性 WindowsIdentity 會傳 WindowsIdentity 回實例,代表呼叫者的Microsoft Windows 身分識別,如果用戶端是使用 SQL Server 驗證進行驗證,則傳回 null。 只有標示 EXTERNAL_ACCESS 或 UNSAFE 許可權的元件才能存取此屬性。
取得 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 觸發程式
SQL Server In-Process ADO.NET 的特定擴充功能