TSQL - Ausführen von CLR-Berechtigung
Ich habe eine sql-Prozedur aus einer CLR (.net-Assembly), die bei Ausführung einen Fehler zurückgibt
Msg 6522, Level 16, State 1, Procedure sp_HelloWorld, Line 0
A .NET Framework error occurred during execution of user defined routine or aggregate 'sp_HelloWorld':
System.Security.SecurityException: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
System.Security.SecurityException:
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.PermissionSet.Demand()
at System.Data.Common.DbConnectionOptions.DemandPermission()
at System.Data.SqlClient.SqlConnection.PermissionDemand()
at System.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at HelloWorld.SQLCLR.HelloWorld()
Dies ist mein SQL-Skript
go
drop procedure HelloWorld
drop assembly HelloWorld
GO
create assembly HelloWorld from 'F:\HelloWorld.dll'
with permission_set = safe
Go
create procedure sp_HelloWorld
as external name HelloWorld.[HelloWorld.SQLCLR].HelloWorld
go
exec sp_HelloWorld
- und das ist meine Klasse (Montage)
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Security.Permissions;
using System.Data;
namespace HelloWorld
{
public class SQLCLR
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void HelloWorld()
{
string connectString1 = @"Data Source=localhost;Initial Catalog=ItemData;Integrated Security=True";
SqlClientPermission permission = new SqlClientPermission(PermissionState.None);
permission.Add(connectString1, "", KeyRestrictionBehavior.AllowOnly);
permission.PermitOnly();
SqlConnection sqlcon = new SqlConnection(connectString1);
sqlcon.Open();
SqlCommand sqlcmd = new SqlCommand("SELECT Top 1 * FROM ItemData.dbo.Item", sqlcon);
SqlDataReader reader = sqlcmd.ExecuteReader();
SqlContext.Pipe.Send(reader);
sqlcon.Close();
}
}
}
- Juvil, wenn Sie noch daran interessiert sind, habe ich Euch ein Antwort, die das Problem erläutert und korrigiert den code für best practices. Ich habe auch erklärt warum die anderen Antworten nicht funktionieren (in den Kommentaren auf die Antworten).
InformationsquelleAutor Juvil | 2010-11-05
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist einfach, dass Sie versuchen, Zugriff auf eine externe Ressource in einer Baugruppe, der markiert ist als
SAFE
. Der Zugriff auf externe Ressourcen erfordert das einstellen der Montage mindestensEXTERNAL_ACCESS
(und in einigen FällenUNSAFE
). Jedoch, suchen Sie in Ihrer code, Sie werden einfach versuchen eine Verbindung zu der lokalen Instanz, und in diesem Fall ist es viel einfacher (und schneller) bedeutet dies: mit"Context Connection = true;"
wie der ConnectionString.Kontext-Verbindung ist eine direkte Verbindung zu den aktuellen Prozess /session, und es ist manchmal auch als in-process-Verbindung. Die Vorteile der Verwendung von Kontext-Verbindung sind:
SAFE
#
statt Doppel -##
)SET CONTEXT_INFO
undCONTEXT_INFO()
Auch:
SqlClientPermission
Dispose()
Methode. Nicht alle Objekte verfügen über diese, aberSqlConnection
,SqlCommand
, undSqlDataReader
sicherlich tun. Es ist typisch für die Menschen zu wickeln Einweg-Objekte in einerusing()
block, wie es ist eine compiler-makro, das expandiert, um einen try /finally-Struktur, die Aufrufe derDispose()
Methode in derfinally
um sicherzustellen, dass es heißt, sogar wenn ein Fehler Auftritt.Dispose()
Methode von vielen /den meisten Wegwerf-Objekte automatisch den Anruf verarbeitet, umClose()
so dass Sie in der Regel nicht aufrufen müssenClose()
ausdrücklich.Ihr code sollte wie folgt Aussehen:
Ich wollte nur hinzufügen, meine zwei Sinn dieser. Ich mache etwas, das sehr ähnlich und ich bin immer der gleiche Fehler. Hier ist was ich gefunden habe, aber b/c ich nicht haben, diese Ebene der Zugriff auf die DB kann ich nicht testen.
Den Ganzen Beitrag Hier...
TRUSTWORTHY ON
, dann gibt es sehr wenig chance, dass Sie zurückkommen wird, das richtige zu tun später. So oder so, ich erkläre das wirkliche Problem in meinen Antwort.Haben Sie Ihre DB eingestellt Trusrtworth AUF und aktiviert clr?
Versuchen, diese
Habe ich eine Anleitung hier, wie CLR-Gespeicherten Prozeduren, die helfen könnten.