![]() |
Datenbank: MSSQL • Version: 2005
SQL MessageId aus einer SQLCLR Funktion
Ich habe hier ein Problem mit den SQL Fehlercodes. Ich erklär erst einmal was ich überhaupt mache:
im SQL Server 2005 nutze ich eine .NET Funktion (SQLCLR). Innerhalb dieser .NET Funktion greife ich auf einen Webservice zu, der mir einen Wert einer bestimmten Berechnung zurückliefert. Diesen Wert soll die .NET Funktion dann an den Aufrufer zurückgeben. Das klappt auch alles so wie es soll, ne richtig feine Sache. Nur habe ich zur Zeit Probleme mit der Fehlerbehandlung. Tirtt im Webservice ein Fehler auf, so knallts mit in der .NET Funktion (in C# geschrieben), welche mir dann den Fehler an den SQL Server zurückliefert. Der sieht dann in etwa so aus: Msg 6522, Level 16, State 1, Line 2 A .NET Framework error occurred during execution of user defined routine or aggregate 'ReadInt': System.Web.Services.Protocols.SoapException: Server was unable to process request. --> Logical Itemname n12 for Device rbg does not exist in loaded itemslist. System.Web.Services.Protocols.SoapException: at System.Web.Services.Protocols.SoapHttpClientProtoc ol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtoc ol.Invoke(String methodName, Object[] parameters) at TOPCService.ReadInt(String Itemname, String DeviceName) at Functions.ReadInt(String Itemname, String DeviceName) . Aus dieser langen Fehlermeldung hab ich mal die wichtigen Dinge blau markiert. Der Fehlermeldungstext wird aus dem Webservice gesetzt, jedoch habe ich da natürlich keine Möglichkeit, die Msg Id zu setzen. Bei jedem Fehler, der auftritt, schmeisst mir der SQL Server immer nur die Msg 6522 zurück. Aber genau diesen Fehler muss ich auswerten, und zwar so effizient wie nur möglich. Ich dachte daran, in der .NET Funktion in C# den Fehler im catch Block abzufangen, und dort aufgrund des Fehlertextes "Logical Itemname n12 for Device rbg does not exist in loaded itemslist." diesen auszuwerten und eine benutzerdefinierte Msg Id zurückzuliefern. Somit hätte ich eine bessere Flexibilität bei der Auswertung des Fehlers im SQL Server. Und genau da häng ich. Die C# Funktion sieht zur Zeit so aus:
Code:
Nur krieg ich mit dem Code natürlich die MsgId nicht geändert. Ich müsste im Catch Block den Fehler analysieren können und eine entsprechende exception auslösen. In T-SQL ginge das mit
public static String ReadString(String Itemname, String DeviceName)
{ String S; TOPCService OPC; try { OPC = new TOPCService(); OPC.Url = RegSettings.UrlWebService(); S = OPC.ReadString(Itemname, DeviceName); OPC.Dispose(); } catch (Exception e) { S = ""; ArgumentException ec = new ArgumentException("Item not found"); throw ec; } return (String)S; }
SQL-Code:
aber in .NET ?
RAISEERROR MsgId,-1,-1
Ich hoff mein Problem wurde verstanden :wiejetzt: |
Re: SQL MessageId aus einer SQLCLR Funktion
Du kannst RaiseError als Command durch den Context abschicken. Du musst allerdings den Fehler, den RaiseError innerhalb der .Net Sproc auslöst abfangen und schlucken.
Dann könnte es funktionieren:
Code:
Keine Ahnung, ob das so stimmt. TSQL und das Fehlen von Exceptions darin sind so abartig... :kotz:
static void RaiseError(int messageId, int severity, int state)
{ using (SqlCommand command = new SqlCommand("RaiseError(@messageId, @severity, @state)")) { command.Parameters.AddWithValue("messageId", messageId); command.Parameters.AddWithValue("severity", severity); command.Parameters.AddWithValue("state", state); try { SqlContext.Pipe.ExecuteAndSend(command); } catch {/*nüschts*/} } } static void RaiseError(string messageText, int severity, int state) { using (SqlCommand command = new SqlCommand("RaiseError(@messageText, @severity, @state)")) { command.Parameters.AddWithValue("messageText", messageText); command.Parameters.AddWithValue("severity", severity); command.Parameters.AddWithValue("state", state); try { SqlContext.Pipe.ExecuteAndSend(command); } catch {/*nüschts*/} } } |
Re: SQL MessageId aus einer SQLCLR Funktion
Zitat:
1. In einer SQLCLR Funktion kann ich nichts über die Pipe senden, weil das in Funktionen leider und unverständlicherweise nicht erlaubt ist 2. Die Fehler sind nach meinem Wissen kummulativ. Durch den Raiseerror würde ich dann wohl höchstens einen weiteren Fehler übergeben. Aber damit könnte ich zur Not noch leben, denn die Variabel @@ERROR enthält ja wohl die zuletzt geworfene Exception. |
Re: SQL MessageId aus einer SQLCLR Funktion
OK, das mit dem RAISERROR innerhalb einer Funktion (egal ob .NET oder T-SQL) ist auch unterbunden. Die Fehlermeldung vom SQL Server lautet:
Code:
:wall:
Msg 6522, Level 16, State 1, Line 4
Invalid use of side-effecting or time-dependent operator in 'RAISERROR' within a function. Das kann doch nicht sein, dass ich aus einer Funktion heraus dem Aufrufer keinen Fehler übermitteln kann. |
Re: SQL MessageId aus einer SQLCLR Funktion
Hab' mich gerade mal schlau gemacht. Anscheinend gibt es keine hübsche Lösung dafür.
Das Errorhandling von TSQL ist einfach zu schrottig. Wie wär's mit einem Output parameter, der den Error code angibt? Dann kannst du die CLR SProc in eine TSQL SProc verpacken, in der kannst du dann RaiseError ausführen. (An deiner Stelle wäre ich spätestens ab diesem Absatz fuchsteufelswild.... :zwinker: ) Tja, was bringt einem CLR Integration wenn das DBMS noch genauso dämlich ist wie 2000? :wall: |
Re: SQL MessageId aus einer SQLCLR Funktion
Zitat:
Zitat:
Zitat:
Aber dein obiger Ansatz funktioniert... Für Stored Procedures. Neben lesenden (über Funktion) Zugriff auf Funktionen gibts auch schreibende Stored Procedures, die mit dem gleichem Webservice kommunizieren. Da krieg ich die Fehler abgefangen und kann sie an den Aufrufer mittels raiserror dort auch genau so anzeigen und auswerten. Zitat:
|
Re: SQL MessageId aus einer SQLCLR Funktion
Zitat:
Ich konnte zum Glück jemanden finden, der mir den MSSQL-Krempel freiwillig abgenommen hat. :) Nach 3 Monaten war ich reif für die Klapse... :wall: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:25 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz