Geschrieben von: Christian Holm
Kategorie: ADO.NET
This printed page brought to you by AlphaSierraPapa
Manche (in grauer Vorzeit implementierte) Sachen funktionieren so gut, daß man sie auch weiterhin verwendet. So auch Stored Procedures. Auf diese muß nämlich in ADO.NET nicht verzichtet werden. Bis auf die Anpassungen für den ADO.NET Code hat sich eigentlich nichts verändert. Und diese Änderungen stellen das heutige Artikelthema dar.
So allmählich wird ADO.NET ganz stabil und man braucht die Stabilität nicht mehr mit einem Kartenhaus zu vergleichen. Aus diesem Grund ist es wieder mal Zeit einen ADO.NET Artikel zu schreiben, da (anscheinend) keine Änderungen im Aufbau (Namespaces, Klassen) von ADO.NET mehr zu erwarten sind. Der heutige Artikel soll Ihnen den Umstieg zu ADO.NET etwas erleichtern, indem er Lösungen zu den wichtigsten Aufgaben zeigt. Also z.B. das Zurückgeben von Recordsets oder die Verwendung von Input Parametern.
Es sei darauf hingewiesen, daß dieser Artikel nicht Grundlagen über Stored Procedures und Ihren Verwendungszweck erläutert, sondern wie schon eingangs erwähnt, einen leichteren Umstieg zu ADO.NET ermöglichen soll. AspHeute bietet ausreichende Lektüre über Stored Procedures, in der die Basics und die Performanceissues erklärt werden.
Die Verwendung bzw. das Zugreifen auf Stored Procedures in ADO.NET ist eigentlich (relativ) einfach - leichter als ich mir vorgestellt habe. Nach den vielen Änderungen war dies schwer vorherzusehen. Also habe ich zwei Beispiele erstellt, die ich heute in diesem Artikel präsentieren werde.
Wie Sie ja wissen, bringt die Nutzung von Stored Procedures einiges an Vorteilen mit sich. Natürlich auch im Hinblick auf die Performance von Datenbankoperationen, da diese bei Stored Procedures am Datenbankserver ablaufen. Warscheinlich eines der auschlaggebenden Argumente für die Weiterverwendung dieser. Mit Stored Procedures können Sie die Abfragestatements einfach kapseln, Sicherheitsvorkehrungen treffen und sie leichter optimieren.
Auch die Einbindung in eine ASP bzw. ASP.NET Seite gestaltet sich wesentlich einfacher als die herkömmliche Verwendung von SQL Statements im Code. Ihre (hoch) optimierten Abfragestatements und sonstiger eingebetteter Code wird einfach durch den Aufruf des Namens der Stored Procedures und Übergabe gegebenenfalls vorhandener Parameter ausgeführt.
Passend für ADO.NET müssen Sie sich hier natürlich auf die Parameters Collection des ADO.NET SqlCommand Objektes beziehen. Mit dieser lassen sich Input-, Output-Parameter, etc. natürlich viel leichter angeben und andererseits noch mehr Performance aus Ihrem Code herausquetschen - was einem halt immer so von den Anbietern einer neueren Version suggeriert wird.
Im ersten Beispiel rufen wir eine bereits in der Northwind SQL-Datenbank vorhandene Stored Procedure (Ten Most Expensive Products, was für ein Zufall) auf. Um dies zu erreichen legen wir den CommandType des SqlCommand Objektes als StoredProcedure fest. Das nun folgende Beispiel (RetRS.aspx) zeigt den einfachen Aufruf einer Stored Procedure und die nachfolgende Ausgabe der Ergebnisrecordsets:
<%@Page Language="C#" %> <%@Import Namespace="System.Data" %> <%@Import Namespace="System.Data.SqlClient" %> <% string strConn ="server=(local)\\NetSDK;database=northwind;Trusted_Connection=yes"; SqlConnection MyNWConn = new SqlConnection(strConn); SqlCommand TenMostExpCmd = new SqlCommand("Ten Most Expensive Products",MyNWConn); TenMostExpCmd.CommandType = CommandType.StoredProcedure; MyNWConn.Open(); SqlDataReader MySqlReader = TenMostExpCmd.ExecuteReader();
Wie bei allen ASP.NET Seiten sind zuerst immer die Directives anzugeben. Hier legen wir mit @Page die verwendete Sprache fest, und danach sind mit @Import die benötigten Namespaces aus dem .NET Framework einzubinden. Hier ist die Namensänderung im Gegensatz zur Beta 1 des .NET Frameworks zu beachten.
Nach der Festlegung des Connectionstrings und Erstellung einer neuen Verbindung zur Northwind SQL-Datenbank können wir dann den Namen der zu verwendenden Stored Procedure und das SqlConnection Objekt dem SqlCommand Objekt übergeben. Wie schon erwähnt, setzten wir den CommandType des SqlCommand Objektes auf StoredProcedure. Danach wird die Verbindung geöffnet und ein neues Objekt für den SqlDataReader instanziert.
Response.Write("<table cellspacing=\"2\" cellpadding=\"2\" border=\"2\">"); Response.Write("<th>" + MySqlReader.GetName(0) + "</th><th>" _ + MySqlReader.GetName(1) + "</th>"); while (MySqlReader.Read()) { Response.Write("<tr>"); Response.Write("<td>" + MySqlReader.GetString(0) + "</td>"); Response.Write("<td>" + MySqlReader.GetDecimal(1) + "</td>"); Response.Write("</tr>"); } Response.Write("</table>"); MySqlReader.Close(); MyNWConn.Close(); %>
Der restliche Code ist eigentlich nur Formsache, d.h. er trägt wesentlich dazu bei, wie die Daten ausgegeben werden. Da ich einen SqlDataReader verwendet habe, ist die Sache wortwörtlich straight forward. Das soll nicht nur simpel heißen, sondern auch, daß der Output Stream auch nur read only und forward ist. Ergo nix mit Datenmanipulation. Wenn dies jedoch erforderlich wäre, würde ich auch meine Daten zuerst "binden" (.Bind()) und dann einem DataGrid zuweisen.
Was trotz aller Schnelle noch zu erwähnen ist, ist die richtige Zuweisung der Datentypen bei der Gewinnung der einzelnen Felder der Recordsets (GetDatenTyp Methode):
Response.Write("<td>" + MySqlReader.GetString(0) + "</td>"); Response.Write("<td>" + MySqlReader.GetDecimal(1) + "</td>");
Da es den Datentyp mit der Bezeichnung Money nur mehr in SQL gibt, tritt hier Decimal in den Vordergrund.
Da dies alles ist, was der Code imstande ist zu produzieren (außer Exceptions vielleicht), können wir uns das Ergebnis nach der erfolgreichen Ausführung der .aspx Seite in einem Webbrowser ansehen:
Ein bischen aufwendiger ist das nächste Beispiel (InputParam.aspx), das wie der Name schon sagt sich Input Parameters bedient. Ähnlich wie bei Methoden bzw. Funktionen in der VB Welt können Sie hier Werte übergeben, die das zurückgelieferte Resultat einer Stored Procedure beeinflußen. Kurze Rede, langes Beispiel:
<%@Page Language="C#" %> <%@Import Namespace="System.Data" %> <%@Import Namespace="System.Data.SqlClient" %> <% string strConn ="server=(local)\\NetSDK;database=northwind;Trusted_Connection=yes"; SqlConnection MyNWConn = new SqlConnection(strConn); SqlCommand SqlCmd = new SqlCommand("SalesByCategory",MyNWConn); SqlCmd.CommandType = CommandType.StoredProcedure; SqlParameter MyParam = SqlCmd.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 15); MyParam.Value = "Seafood"; MyNWConn.Open(); SqlDataReader MySqlReader = SqlCmd.ExecuteReader(); Response.Write("<table cellspacing=\"2\" cellpadding=\"2\" border=\"2\">"); Response.Write("<th>" + MySqlReader.GetName(0) + "</th><th>" + MySqlReader.GetName(1) + "</th>"); while (MySqlReader.Read()) { Response.Write("<tr>"); Response.Write("<td>" + MySqlReader.GetString(0) + "</td>"); Response.Write("<td>" + MySqlReader.GetDecimal(1) + "</td>"); Response.Write("</tr>"); } Response.Write("</table>"); MySqlReader.Close(); MyNWConn.Close(); %>
Abgesehen von der Verwendung einer anderen Stored Procedure (SalesByCategory) und des ähnlichen Codes zum vorigen Beispiel, sind hier folgende Zeilen interessant:
SqlParameter MyParam = SqlCmd.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 15); MyParam.Value = "Seafood";
Wie in diesem Beispiel gezeigt wird, können Sie nun durch die Setzung der CommandType Property auf StoredProcedure auf die zur Verfügung gestellte Parameters Collection zugreifen. Hier fügen wir einen neuen Parameter (MyParameter) dem SqlCommand Objekt hinzu. Dieser bezieht sich auf die Tabellenspalte CategoryName und ist vom Enumtyp NVarChar, sowie von der Länge 15. Was noch fehlt ist natürlich der Wert, den der Parameter haben soll. Dies erreichen wir indem wir die Value Property auf den gewünschten Wert setzen (hier: Seafood).
Der nun folgende Screenshot präsentiert das Ergebnis der erfolgreichen Ausführung der ASP.NET Seite:
Dieser Artikel sollte Ihnen einen schnellen Überblick über die wichtigsten Änderungen für Stored Procedures gegenüber dem old-fashioned ASP geben, damit Ihre geliebten Stored Procedures auch in Zukunft weiter existieren können. Da sich seit der Beta 2 des .NET Frameworks die Bezeichnungen gefestigt haben und sich bis zum Release der Erstversion (eigentlich) nichts mehr ändern sollte, macht es jetzt um so mehr Sinn sich mit dieser neuen und sehr umfangreichen Materie auseinanderzusetzen.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010626.zip
Datenaufbereitung in ADO.NET
http:/www.aspheute.com/artikel/20001106.htm
Datenbankzugriff mittels ADO.NET
http:/www.aspheute.com/artikel/20001102.htm
Der ODBC .NET Data Provider
http:/www.aspheute.com/artikel/20020206.htm
Gegengifte für SQL Injection
http:/www.aspheute.com/artikel/20011031.htm
Performancemessungen in .NET
http:/www.aspheute.com/artikel/20011206.htm
Records zählen mit Stored Procedures
http:/www.aspheute.com/artikel/20010326.htm
Verhinderung von SQL Injection Marke .NET
http:/www.aspheute.com/artikel/20011203.htm
Was ist neu in ADO.NET
http:/www.aspheute.com/artikel/20001031.htm
DotNetGerman Diskussionslisten
http://www.dotnetgerman.com/
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.