Freigeben über


Verwenden parametrisierter Abfragen mit sqlDataSource (VB)

von Scott Mitchell

PDF herunterladen

In diesem Tutorial setzen wir unsere Betrachtung des SqlDataSource-Steuerelements fort und lernen, wie parametrisierte Abfragen definiert werden. Die Parameter können sowohl deklarativ als auch programmgesteuert angegeben werden und aus einer Reihe von Speicherorten wie der Abfragezeichenfolge, dem Sitzungsstatus, anderen Steuerelementen und mehr abgerufen werden.

Einführung

Im vorherigen Lernprogramm haben wir erfahren, wie Sie das SqlDataSource-Steuerelement verwenden, um Daten direkt aus einer Datenbank abzurufen. Mithilfe des Assistenten "Datenquelle konfigurieren" können wir die Datenbank auswählen und dann entweder die Spalten auswählen, die aus einer Tabelle oder Ansicht zurückgegeben werden sollen. geben Sie eine benutzerdefinierte SQL-Anweisung ein; oder verwenden Sie eine gespeicherte Prozedur. Unabhängig davon, ob Sie Spalten aus einer Tabelle oder Ansicht auswählen oder eine benutzerdefinierte SQL-Anweisung eingeben, wird die Eigenschaft des SqlDataSource-Steuerelements SelectCommand der resultierenden Ad-hoc-SQL-Anweisung SELECT zugewiesen, und es handelt sich um diese SELECT Anweisung, die ausgeführt wird, wenn die SqlDataSource-Methode Select() aufgerufen wird (entweder programmgesteuert oder automatisch aus einem Datenwebsteuerelement).

Die SQL-Anweisungen SELECT in den Demos des vorherigen Lernprogramms fehlten WHERE Klauseln. In einer SELECT Anweisung kann die WHERE Klausel verwendet werden, um die zurückgegebenen Ergebnisse einzuschränken. Um beispielsweise die Namen von Produkten anzuzeigen, die mehr als 50,00 $ kosten, könnten wir die folgende Abfrage verwenden:

SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00

In der Regel werden die in einer WHERE Klausel verwendeten Werte von einer externen Quelle bestimmt, z. B. von einem Abfragezeichenfolgenwert, einer Sitzungsvariable oder von Benutzereingaben eines Websteuerelements auf der Seite. Im Idealfall werden solche Eingaben über die Verwendung von Parametern angegeben. Bei Microsoft SQL Server werden Parameter mit @parameterName angegeben, wie in:

SELECT ProductName
FROM Products
WHERE UnitPrice > @Price

SqlDataSource unterstützt parametrisierte Abfragen, sowohl für SELECT-Anweisungen als auch für INSERT, UPDATE und DELETE-Anweisungen. Darüber hinaus können die Parameterwerte automatisch aus einer Vielzahl von Quellen abgerufen werden, wie etwa der Abfragezeichenfolge, dem Sitzungszustand, Steuerelementen auf der Seite usw., oder sie können programmgesteuert zugewiesen werden. In diesem Lernprogramm wird erläutert, wie parametrisierte Abfragen definiert werden und wie sie die Parameterwerte sowohl deklarativ als auch programmgesteuert angeben.

Hinweis

Im vorherigen Lernprogramm haben wir die ObjectDataSource verglichen, die unser Wahltool für die ersten 46 Lernprogramme mit der SqlDataSource war, wobei sie ihre konzeptionellen Ähnlichkeiten notiert. Diese Ähnlichkeiten erstrecken sich auch auf Parameter. Die Parameter der ObjectDataSource werden den Eingabeparametern für die Methoden in der Geschäftslogikebene zugeordnet. Mit sqlDataSource werden die Parameter direkt in der SQL-Abfrage definiert. Beide Steuerelemente verfügen über Auflistungen von Parametern für ihre Methoden Select(), Insert(), Update() und Delete(); beide können diese Parameterwerte aus vordefinierten Quellen (wie Abfragezeichenfolgenwerten, Sitzungsvariablen usw.) beziehen oder programmgesteuert zuweisen lassen.

Erstellen einer parametrisierten Abfrage

Der Assistent zum Konfigurieren des SqlDataSource-Steuerelements bietet drei Möglichkeiten zum Definieren der auszuführenden Befehle zum Abrufen von Datenbankdatensätzen.

  • Indem Sie die Spalten aus einer vorhandenen Tabelle oder Ansicht auswählen,
  • Durch Eingabe einer benutzerdefinierten SQL-Anweisung oder
  • Durch Auswählen einer gespeicherten Prozedur

Beim Auswählen von Spalten aus einer vorhandenen Tabelle oder Ansicht müssen die Parameter für die WHERE Klausel über das Dialogfeld "Klausel hinzufügen WHERE " angegeben werden. Beim Erstellen einer benutzerdefinierten SQL-Anweisung können Sie jedoch die Parameter direkt in die WHERE Klausel eingeben, wobei @parameterName für jeden Parameter steht. Eine gespeicherte Prozedur besteht aus einer oder mehreren SQL-Anweisungen, und diese Anweisungen können parametrisiert werden. Die in den SQL-Anweisungen verwendeten Parameter müssen jedoch als Eingabeparameter an die gespeicherte Prozedur übergeben werden.

Da das Erstellen einer parametrisierten Abfrage davon abhängt, wie die SqlDataSource s SelectCommand angegeben wird, werfen wir einen Blick auf alle drei Ansätze. Um zu beginnen, öffnen Sie die ParameterizedQueries.aspx Seite im SqlDataSource Ordner, ziehen Sie ein SqlDataSource-Steuerelement aus der Toolbox auf den Designer, und legen Sie dessen ID auf Products25BucksAndUnderDataSource fest. Klicken Sie als Nächstes auf den Link "Datenquelle konfigurieren" aus dem Smarttag des Steuerelements. Wählen Sie die zu verwendende Datenbank (NORTHWINDConnectionString) aus, und klicken Sie auf "Weiter".

Schritt 1: Hinzufügen einer WHERE-Klausel beim Auswählen der Spalten aus einer Tabelle oder Ansicht

Wenn Sie die Daten auswählen, die mit dem SqlDataSource-Steuerelement aus der Datenbank zurückgegeben werden sollen, können wir im Assistenten zum Konfigurieren von Datenquellen einfach die Spalten auswählen, die aus einer vorhandenen Tabelle oder Ansicht zurückgegeben werden sollen (siehe Abbildung 1). Dadurch wird automatisch eine SQL-Anweisung SELECT erstellt, die an die Datenbank gesendet wird, wenn die SqlDataSource-Methode Select() aufgerufen wird. Wie im vorherigen Lernprogramm wählen Sie die Tabelle "Produkte" aus der Dropdownliste aus und überprüfen Sie die Spalten ProductID, ProductName und UnitPrice.

Auswählen der Spalten, die aus einer Tabelle oder Ansicht zurückgegeben werden sollen

Abbildung 1: Auswählen der spalten, die aus einer Tabelle oder Ansicht zurückgegeben werden sollen (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Um eine WHERE Klausel in die SELECT Anweisung einzuschließen, klicken Sie auf die WHERE Schaltfläche, die das Dialogfeld "Klausel hinzufügen WHERE " anzeigt (siehe Abbildung 2). Wenn Sie einen Parameter hinzufügen möchten, um die von der SELECT Abfrage zurückgegebenen Ergebnisse einzuschränken, wählen Sie zuerst die Spalte aus, nach der die Daten gefiltert werden sollen. Wählen Sie als Nächstes den Operator aus, der für die Filterung verwendet werden soll (=, <= <, >usw.). Wählen Sie schließlich die Quelle des Parameterwerts aus, z. B. aus der Abfragezeichenfolge oder dem Sitzungszustand. Klicken Sie nach dem Konfigurieren des Parameters auf die Schaltfläche "Hinzufügen", um ihn in die SELECT Abfrage einzuschließen.

In diesem Beispiel geben wir nur die Ergebnisse zurück, bei denen der UnitPrice Wert kleiner oder gleich 25,00 $ ist. Daher wählen Sie in der Dropdownliste "Spalte" UnitPrice und in der Dropdownliste "Operator" <= aus. Wenn Sie einen hartcodierten Parameterwert (z. B. $25,00) verwenden oder wenn der Parameterwert programmgesteuert angegeben werden soll, wählen Sie "Keine" aus der Dropdownliste "Quelle" aus. Geben Sie als Nächstes den hartcodierten Parameterwert in das Textfeld Wert 25.00 ein, und schließen Sie den Vorgang ab, indem Sie auf die Schaltfläche "Hinzufügen" klicken.

Einschränken der ergebnisse, die aus dem Dialogfeld

Abbildung 2: Einschränken der ergebnisse, die aus dem Dialogfeld "Klausel hinzufügen WHERE " zurückgegeben werden (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Klicken Sie nach dem Hinzufügen des Parameters auf "OK", um zum Assistenten "Datenquelle konfigurieren" zurückzukehren. Die SELECT-Anweisung am unteren Rand des Assistenten sollte nun eine WHERE-Klausel mit einem Parameter namens @UnitPrice enthalten:

SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)

Hinweis

Wenn Sie mehrere Bedingungen in der WHERE Klausel aus dem Dialogfeld "Klausel hinzufügen WHERE " angeben, verknüpft der Assistent sie mit dem AND Operator. Wenn Sie eine OR in die WHERE Klausel einschließen müssen (z. B. WHERE UnitPrice <= @UnitPrice OR Discontinued = 1), müssen Sie die SELECT Anweisung über den benutzerdefinierten SQL-Anweisungsbildschirm erstellen.

Konfigurieren Sie die SqlDataSource (klicken Sie auf Weiter, dann fertig stellen), und prüfen Sie dann das deklarative Markup von SqlDataSource. Das Markup enthält nun eine <SelectParameters> Sammlung, die die Quellen für die Parameter in der SelectCommand darlegt.

<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT [ProductID], [ProductName], [UnitPrice]
        FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
    <SelectParameters>
        <asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
    </SelectParameters>
</asp:SqlDataSource>

Wenn die SqlDataSource-Methode Select() aufgerufen wird, wird der UnitPrice Parameterwert (25.00) auf den Parameter in der @UnitPriceSelectCommand Datenbank angewendet, bevor er an die Datenbank gesendet wird. Das Nettoergebnis ist, dass nur die Produkte, die kleiner oder gleich 25,00 $ sind, aus der Products Tabelle zurückgegeben werden. Um dies zu bestätigen, fügen Sie der Seite eine GridView hinzu, binden Sie sie an diese Datenquelle, und zeigen Sie die Seite dann über einen Browser an. Sie sollten nur die Produkte sehen, die höchstens 25,00 $ kosten, wie in Abbildung 3 bestätigt.

Nur die Produkte, die kleiner als oder gleich 25,00 $ sind, werden angezeigt.

Abbildung 3: Nur diese Produkte, die kleiner oder gleich 25,00 $ sind, werden angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Schritt 2: Hinzufügen von Parametern zu einer benutzerdefinierten SQL-Anweisung

Beim Hinzufügen einer benutzerdefinierten SQL-Anweisung können Sie die WHERE Klausel explizit eingeben oder einen Wert in der Zelle "Filter" des Abfrage-Generators angeben. Um dies zu veranschaulichen, zeigen wir nur die Produkte in einer GridView an, deren Preise kleiner als ein bestimmter Schwellenwert sind. Fügen Sie der Seite zunächst ein TextBox-Objekt hinzu ParameterizedQueries.aspx , um diesen Schwellenwert vom Benutzer zu erfassen. Legen Sie die Eigenschaft ID der TextBox auf MaxPrice fest. Fügen Sie ein Schaltflächenweb-Steuerelement hinzu, und legen Sie dessen Text Eigenschaft auf "Übereinstimmende Produkte anzeigen" fest.

Ziehen Sie als Nächstes ein GridView auf die Seite und wählen Sie im Smarttag aus, um eine neue SqlDataSource mit dem Namen ProductsFilteredByPriceDataSource zu erstellen. Gehen Sie im Assistenten "Datenquelle konfigurieren" zum Bildschirm "Angeben einer benutzerdefinierten SQL-Anweisung oder gespeicherten Prozedur" (siehe Abbildung 4), und geben Sie die folgende Abfrage ein:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

Klicken Sie nach der Eingabe der Abfrage (manuell oder über den Abfrage-Generator) auf "Weiter".

Nur die Produkte zurückgeben, die kleiner oder gleich einem Parameterwert sind

Abbildung 4: Nur die Produkte zurückgeben, die kleiner oder gleich einem Parameterwert sind (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Da die Abfrage Parameter enthält, fordert der nächste Bildschirm im Assistenten uns zur Quelle der Parameterwerte auf. Wählen Sie "Steuerelement" aus der Dropdownliste "Parameterquelle" und MaxPrice (den Wert des TextBox-Steuerelements ID) aus der Dropdownliste "ControlID" aus. Sie können auch einen optionalen Standardwert eingeben, der verwendet werden soll, wenn der Benutzer keinen Text in das MaxPrice Textfeld eingegeben hat. Geben Sie vorerst keinen Standardwert ein.

Die TextBox-Eigenschaft

Abbildung 5: Die MaxPrice TextBox-Eigenschaft Text wird als Parameterquelle verwendet (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Schließen Sie den Assistenten zum Konfigurieren der Datenquelle ab, indem Sie auf "Weiter" und dann auf "Fertig stellen" klicken. Das deklarative Markup für GridView, TextBox, Button und SqlDataSource folgt:

Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
 
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
    Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
    DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            HtmlEncode="False" DataFormatString="{0:c}"
            SortExpression="UnitPrice" />
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand=
        "SELECT ProductName, UnitPrice 
        FROM Products WHERE UnitPrice <= @MaximumPrice">
    <SelectParameters>
        <asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
            PropertyName="Text" />
    </SelectParameters>
</asp:SqlDataSource>

Beachten Sie, dass der Parameter im Abschnitt "SqlDataSource" <SelectParameters> ein ControlParameter ist, der zusätzliche Eigenschaften wie ControlID und PropertyName enthält. Wenn die SqlDataSource-Methode Select() aufgerufen wird, greift der ControlParameter den Wert aus der angegebenen Websteuerelementeigenschaft ab und weist ihn dem zugehörigen Parameter in der SelectCommand zu. In diesem Beispiel wird die Texteigenschaft von MaxPrice als @MaxPrice Parameterwert verwendet.

Nehmen Sie sich eine Minute Zeit, um diese Seite über einen Browser anzuzeigen. Wenn Sie die Seite zum ersten Mal besuchen oder wenn das MaxPrice TextBox-Objekt keinen Wert aufweist, werden keine Datensätze in gridView angezeigt.

Es werden keine Datensätze angezeigt, wenn das MaxPrice-Textfeld leer ist.

Abbildung 6: Es werden keine Datensätze angezeigt, wenn das MaxPrice Textfeld leer ist (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Der Grund, warum keine Produkte angezeigt werden, ist, dass standardmäßig eine leere Zeichenfolge für einen Parameterwert in einen Datenbankwert NULL konvertiert wird. Da der Vergleich von [UnitPrice] <= NULL immer als „False“ ausgewertet wird, werden keine Ergebnisse zurückgegeben.

Geben Sie einen Wert in das Textfeld ein, z. B. 5,00, und klicken Sie auf die Schaltfläche "Übereinstimmende Produkte anzeigen". Bei postback informiert sqlDataSource die GridView, dass eine seiner Parameterquellen geändert wurde. Folglich wird die GridView mit der SqlDataSource verknüpft und zeigt Produkte an, die kleiner oder gleich 5,00 $ sind.

Produkte, die kleiner oder gleich 5,00 $ sind, werden angezeigt

Abbildung 7: Produkte, die kleiner als oder gleich 5,00 $ sind, werden angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Anfängliches Anzeigen aller Produkte

Anstatt beim ersten Laden der Seite keine Produkte anzuzeigen, möchten wir möglicherweise alle Produkte anzeigen. Eine Möglichkeit zum Auflisten aller Produkte, wenn das MaxPrice TextBox-Objekt leer ist, besteht darin, den Standardwert des Parameters auf einen unsinnig hohen Wert festzulegen, z. B. 1000000, da es unwahrscheinlich ist, dass Northwind Traders jemals über Lagerbestände verfügen, deren Einzelpreis 1.000.000 $ überschreitet. Dieser Ansatz ist jedoch kurzsichtig und funktioniert in anderen Situationen möglicherweise nicht.

In früheren Lernprogrammen – Deklarative Parameter und Master/Detail-Filterung mit einem DropDownList-Element waren wir mit einem ähnlichen Problem konfrontiert. Unsere Lösung bestand darin, diese Logik in die Geschäftslogikebene zu setzen. Insbesondere untersuchte die BLL den eingehenden Wert, und wenn er NULL oder ein reservierter Wert war, wurde der Aufruf an die DAL-Methode weitergeleitet, die alle Datensätze zurückgab. Wenn der eingehende Wert ein normaler Filterwert war, wurde ein Aufruf der DAL-Methode ausgeführt, die eine SQL-Anweisung ausgeführt hat, die eine parametrisierte WHERE Klausel mit dem angegebenen Wert verwendet hat.

Leider umgehen wir die Architektur bei Verwendung von SqlDataSource. Stattdessen müssen wir die SQL-Anweisung so anpassen, dass alle Datensätze intelligent abgerufen werden, wenn der @MaximumPrice Parameter NULL ist oder einen reservierten Wert hat. Für diese Übung haben wir es so, dass, wenn der @MaximumPrice Parameter gleich -1.0ist, alle Datensätze zurückgegeben werden sollen (-1.0 funktioniert als reservierter Wert, da kein Produkt einen negativen UnitPrice Wert haben kann). Dazu können wir die folgende SQL-Anweisung verwenden:

SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0

Diese WHERE Klausel gibt alle Datensätze zurück, wenn der @MaximumPrice Parameter gleich ist -1.0. Wenn der Parameterwert nicht -1.0ist, werden nur die Produkte zurückgegeben, deren UnitPrice Wert kleiner oder gleich dem @MaximumPrice Parameterwert ist. Durch Festlegen des Standardwerts des @MaximumPrice-Parameters auf -1.0 hat @MaximumPrice beim ersten Laden der Seite (oder wenn die MaxPrice TextBox leer ist) einen Wert von -1.0, und alle Produkte werden angezeigt.

Jetzt werden alle Produkte angezeigt, wenn das MaxPrice-Textfeld leer ist

Abbildung 8: Jetzt werden alle Produkte angezeigt, wenn das MaxPrice Textfeld leer ist (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Es gibt ein paar Vorbehalte, die mit diesem Ansatz zu beachten sind. Stellen Sie zunächst fest, dass der Datentyp des Parameters von der Verwendung in der SQL-Abfrage abgeleitet wird. Wenn Sie die WHERE Klausel von @MaximumPrice = -1.0 zu @MaximumPrice = -1 ändern, behandelt die Runtime-Umgebung den Parameter als Integer. Wenn Sie dann versuchen, das MaxPrice TextBox-Objekt einem Dezimalwert (z. B. 5,00) zuzuweisen, tritt ein Fehler auf, da 5,00 nicht in eine ganze Zahl konvertiert werden kann. Um dies zu beheben, stellen Sie entweder sicher, dass Sie @MaximumPrice = -1.0 in der WHERE Klausel verwenden oder, noch besser, die Eigenschaft des ControlParameterType Objekts auf Decimal festlegen.

Zweitens kann das Abfragemodul durch Hinzufügen der OR @MaximumPrice = -1.0 zur WHERE-Klausel keinen Index auf UnitPrice verwenden, vorausgesetzt, dass einer existiert, wodurch ein Tabellenscan entsteht. Dies kann sich auf die Leistung auswirken, wenn eine ausreichend große Anzahl von Datensätzen in der Products Tabelle vorhanden ist. Ein besserer Ansatz wäre das Verschieben dieser Logik in eine gespeicherte Prozedur, bei der eine IF Anweisung entweder eine SELECT Abfrage aus der Products Tabelle ohne WHERE Klausel ausführt, wenn alle Datensätze zurückgegeben werden müssen oder eine Klausel, deren WHERE Klausel nur die UnitPrice Kriterien enthält, sodass ein Index verwendet werden kann.

Schritt 3: Erstellen und Verwenden parametrisierter gespeicherter Prozeduren

Gespeicherte Prozeduren können eine Reihe von Eingabeparametern enthalten, die dann in den in der gespeicherten Prozedur definierten SQL-Anweisungen verwendet werden können. Beim Konfigurieren der SqlDataSource für die Verwendung einer gespeicherten Prozedur, die Eingabeparameter akzeptiert, können diese Parameterwerte mit denselben Techniken wie bei Ad-hoc-SQL-Anweisungen angegeben werden.

Um die Verwendung gespeicherter Prozeduren in sqlDataSource zu veranschaulichen, erstellen wir eine neue gespeicherte Prozedur in der Northwind-Datenbank namens GetProductsByCategory, die einen Parameter namens @CategoryID akzeptiert und alle Spalten der Produkte zurückgibt, deren CategoryID Spalten übereinstimmen @CategoryID. Um eine gespeicherte Prozedur zu erstellen, wechseln Sie zum Server-Explorer, und führen Sie einen Drilldown in die NORTHWND.MDF Datenbank durch. (Wenn der Server-Explorer nicht angezeigt wird, rufen Sie ihn auf, indem Sie zum Menü "Ansicht" wechseln und die Option "Server-Explorer" auswählen.)

Klicken Sie in der Datenbank mit der NORTHWND.MDF rechten Maustaste auf den Ordner "Gespeicherte Prozeduren", wählen Sie "Neue gespeicherte Prozedur hinzufügen" aus, und geben Sie die folgende Syntax ein:

CREATE PROCEDURE dbo.GetProductsByCategory
(
      @CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID

Klicken Sie auf das Symbol "Speichern" (oder STRG+S), um die gespeicherte Prozedur zu speichern. Sie können die gespeicherte Prozedur testen, indem Sie im Ordner "Gespeicherte Prozeduren" mit der rechten Maustaste darauf klicken und "Ausführen" auswählen. Dadurch werden Sie aufgefordert, die Parameter der gespeicherten Prozedur (@CategoryIDin dieser Instanz) einzugeben, nach der die Ergebnisse im Ausgabefenster angezeigt werden.

Die gespeicherte Prozedur GetProductsByCategory, ausgeführt mit einer <span class= @CategoryID von 1" />

Abbildung 9: Die GetProductsByCategory gespeicherte Prozedur, wenn sie mit einer @CategoryID von 1 ausgeführt wird (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Lassen Sie uns dieses gespeicherte Verfahren verwenden, um alle Produkte in der Kategorie "Getränke" in einer GridView anzuzeigen. Fügen Sie der Seite eine neue GridView hinzu, und binden Sie sie an eine neue SqlDataSource mit dem Namen BeverageProductsDataSource. Fahren Sie mit dem Bildschirm "Angeben einer benutzerdefinierten SQL-Anweisung oder gespeicherten Prozedur" fort, wählen Sie das Optionsfeld "Gespeicherte Prozedur" aus, und wählen Sie die GetProductsByCategory gespeicherte Prozedur aus der Dropdownliste aus.

Wählen Sie die gespeicherte Prozedur

Abbildung 10: Auswählen der GetProductsByCategory gespeicherten Prozedur aus der liste Drop-Down (Klicken Sie hier, um das Bild mit voller Größe anzuzeigen)

Da die gespeicherte Prozedur einen Eingabeparameter akzeptiert (@CategoryID), werden wir beim Klicken auf "Weiter" aufgefordert, die Quelle für den Wert dieses Parameters anzugeben. Das Getränk CategoryID ist 1, lassen Sie also die Dropdownliste "Parameterquelle" auf "Keine" und geben Sie "1" in das Textfeld "Standardwert" ein.

Verwenden Sie einen Hard-Coded Wert von 1, um die Produkte in der Kategorie

Abbildung 11: Verwenden eines Hard-Coded Werts von 1, um die Produkte in der Kategorie "Getränke" zurückzugeben (Klicken Sie hier, um das Bild mit voller Größe anzuzeigen)

Wie das folgende deklarative Markup zeigt, wird die SqlDataSource-Eigenschaft SelectCommand bei Verwendung einer gespeicherten Prozedur auf den Namen der gespeicherten Prozedur festgelegt, und die SelectCommandType Eigenschaft wird auf festgelegt StoredProcedure, wobei angegeben wird, dass es sich SelectCommand um den Namen einer gespeicherten Prozedur anstelle einer Ad-hoc-SQL-Anweisung handelt.

<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Testen Sie die Seite in einem Browser. Nur die Produkte, die zur Kategorie "Getränke" gehören, werden angezeigt, obwohl alle Produktfelder angezeigt werden, da die GetProductsByCategory gespeicherte Prozedur alle Spalten aus der Products Tabelle zurückgibt. Natürlich können wir die felder einschränken oder anpassen, die im GridView-Dialogfeld "Spalten bearbeiten" angezeigt werden.

Alle Getränke werden angezeigt

Abbildung 12: Alle Getränke werden angezeigt (Zum Anzeigen des Bilds mit voller Größe klicken)

Schritt 4: Programmgesteuertes Aufrufen der Select() -Anweisung einer SqlDataSource

Die Beispiele, die wir im vorherigen Lernprogramm und in diesem Lernprogramm bisher gesehen haben, haben SqlDataSource-Steuerelemente direkt an ein GridView gebunden. Auf die Daten des SqlDataSource-Steuerelements kann jedoch im Code zugegriffen und programmgesteuert aufgezählt werden. Dies kann besonders nützlich sein, wenn Sie Daten abfragen müssen, um sie zu prüfen, aber nicht anzeigen müssen. Anstatt den gesamten Textbaustein ADO.NET Code schreiben zu müssen, um eine Verbindung mit der Datenbank herzustellen, den Befehl anzugeben und die Ergebnisse abzurufen, können Sie die SqlDataSource diesen monotonen Code behandeln lassen.

Um die programmgesteuerte Arbeit mit den SqlDataSource-Daten zu veranschaulichen, stellen Sie sich vor, dass Ihr Vorgesetzter Sie mit einer Anforderung zum Erstellen einer Webseite angegangen hat, die den Namen einer zufällig ausgewählten Kategorie und der zugehörigen Produkte anzeigt. Das heißt, wenn ein Benutzer diese Seite besucht, möchten wir zufällig eine Kategorie aus der Categories Tabelle auswählen, den Kategorienamen anzeigen und dann die Produkte auflisten, die zu dieser Kategorie gehören.

Dazu benötigen wir zwei SqlDataSource-Steuerelemente, um eine zufällige Kategorie aus der Categories Tabelle und eine andere abzurufen, um die Produkte der Kategorie abzurufen. Wir erstellen die SqlDataSource, die in diesem Schritt einen zufälligen Kategoriedatensatz abruft. Schritt 5 befasst sich mit dem Erstellen der SqlDataSource, die die Produkte der Kategorie abruft.

Fügen Sie zunächst eine SqlDataSource zu ParameterizedQueries.aspx hinzu und legen Sie deren ID auf RandomCategoryDataSource fest. Konfigurieren Sie sie so, dass sie die folgende SQL-Abfrage verwendet:

SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()

ORDER BY NEWID() gibt die datensätze in zufälliger Reihenfolge sortiert zurück (siehe Verwenden NEWID() zur zufälligen Sortierung von Datensätzen). SELECT TOP 1 gibt den ersten Datensatz aus dem Resultset zurück. Diese Abfrage gibt die Werte aus den CategoryID- und CategoryName-Spalten aus einer einzelnen, zufällig ausgewählten Kategorie zurück.

Um den Wert der Kategorie CategoryName anzuzeigen, fügen Sie der Seite ein Label-Websteuerelement hinzu, legen Sie dessen Eigenschaft ID auf CategoryNameLabel fest und setzen Sie dessen Eigenschaft Text zurück. Um die Daten programmgesteuert aus einem SqlDataSource-Steuerelement abzurufen, müssen wir seine Select() Methode aufrufen. Die Select() Methode erwartet einen einzelnen Eingabeparameter vom Typ DataSourceSelectArguments, der angibt, wie die Daten vor der Rückgabe angezeigt werden sollen. Dies kann Anweisungen zum Sortieren und Filtern der Daten enthalten und wird von den Datenwebsteuerelementen beim Sortieren oder Ausblättern der Daten aus einem SqlDataSource-Steuerelement verwendet. In unserem Beispiel müssen die Daten jedoch nicht geändert werden, bevor sie zurückgegeben werden. Daher wird das DataSourceSelectArguments.Empty Objekt übergeben.

Die Select() Methode gibt ein Objekt zurück, das IEnumerable implementiert wird. Der zurückgegebene genaue Typ hängt vom Wert der Eigenschaft des SqlDataSource-Steuerelements DataSourceMode ab. Wie im vorherigen Lernprogramm erläutert, kann diese Eigenschaft auf einen der beiden Werte DataSet oder DataReader gesetzt werden. Bei Festlegung auf DataSet, gibt die Select() Methode ein DataView -Objekt zurück; wenn festgelegt auf DataReader, wird ein Objekt zurückgegeben, das implementiert IDataReaderwird. Da die RandomCategoryDataSource SqlDataSource-Eigenschaft DataSourceMode auf DataSet (der Standardeinstellung) festgelegt ist, werden wir mit einem DataView-Objekt arbeiten.

Der folgende Code veranschaulicht, wie die Datensätze aus der RandomCategoryDataSource SqlDataSource als DataView abgerufen und wie der CategoryName Spaltenwert aus der ersten DataView-Zeile gelesen wird:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
    Handles Me.Load
    ' Get the data from the SqlDataSource as a DataView
    Dim randomCategoryView As DataView = CType _
        (RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty), DataView)
    If randomCategoryView.Count > 0 Then
        ' Assign the CategoryName value to the Label
        CategoryNameLabel.Text = String.Format( _
            "Here are Products in the {0} Category...", _
            randomCategoryView(0)("CategoryName").ToString())
    End If
End Sub

randomCategoryView(0) gibt das erste DataRowView in der DataView zurück. randomCategoryView(0)("CategoryName") gibt den Wert der CategoryName Spalte in dieser ersten Zeile zurück. Beachten Sie, dass DataView lose-typisiert ist. Um auf einen bestimmten Spaltenwert zu verweisen, müssen wir den Namen der Spalte als Zeichenfolge übergeben ( CategoryName, in diesem Fall). Abbildung 13 zeigt die Meldung in CategoryNameLabel, die beim Anzeigen der Seite angezeigt wird. Natürlich wird der tatsächliche Kategoriename zufällig von der RandomCategoryDataSource SqlDataSource auf jedem Besuch der Seite (einschließlich Postbacks) ausgewählt.

Der Name der zufällig ausgewählten Kategorie wird angezeigt.

Abbildung 13: Der Name der zufällig ausgewählten Kategorie wird angezeigt (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Hinweis

Wenn die Eigenschaft des SqlDataSource-Steuerelements DataSourceMode auf DataReader festgelegt wurde, müsste der Rückgabewert der Methode Select() in IDataReader umgewandelt werden. Um den CategoryName Spaltenwert aus der ersten Zeile zu lesen, verwenden wir Code wie folgt:

If randomCategoryReader.Read() Then
   Dim categoryName as String = randomCategoryReader("CategoryName').ToString()
   ...
End If

Wenn SqlDataSource eine Kategorie zufällig auswählt, können wir die GridView hinzufügen, die die Produkte der Kategorie auflistet.

Hinweis

Anstatt ein Label-Websteuerelement zu verwenden, um den Kategorienamen anzuzeigen, hätten wir der Seite eine FormView oder DetailsView hinzufügen und an die SqlDataSource binden können. Mithilfe der Bezeichnung konnten wir jedoch untersuchen, wie die SqlDataSource-Anweisung Select() programmgesteuert aufgerufen und mit den resultierenden Daten im Code gearbeitet wird.

Schritt 5: Programmgesteuertes Zuweisen von Parameterwerten

Alle Beispiele, die wir bisher in diesem Lernprogramm gesehen haben, haben entweder einen hartcodierten Parameterwert oder einen aus einer der vordefinierten Parameterquellen (ein Abfragezeichenfolgenwert, ein Websteuerelement auf der Seite usw.) verwendet. Die Parameter des SqlDataSource-Steuerelements können jedoch auch programmgesteuert festgelegt werden. Zum Abschließen des aktuellen Beispiels benötigen wir eine SqlDataSource, die alle Produkte zurückgibt, die zu einer angegebenen Kategorie gehören. Diese SqlDataSource verfügt über einen CategoryID Parameter, dessen Wert basierend auf dem CategoryID von der RandomCategoryDataSource SqlDataSource im Page_Load Ereignishandler zurückgegebenen Spaltenwert festgelegt werden muss.

Beginnen Sie, indem Sie der Seite eine GridView hinzufügen und an eine neue SqlDataSource mit dem Namen ProductsByCategoryDataSourcebinden. Ähnlich wie in Schritt 3 konfigurieren Sie die SqlDataSource so, dass sie die GetProductsByCategory gespeicherte Prozedur aufruft. Lassen Sie die Dropdownliste "Parameterquelle" auf "Keine" festgelegt, geben Sie jedoch keinen Standardwert ein, da wir diesen Standardwert programmgesteuert festlegen.

Screenshot des Fensters

Abbildung 14: Keine Parameterquelle oder Standardwert angeben (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Nach Abschluss des SqlDataSource-Assistenten sollte das resultierende deklarative Markup ähnlich wie folgt aussehen:

<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
    <SelectParameters>
        <asp:Parameter Name="CategoryID" Type="Int32" />
    </SelectParameters>
</asp:SqlDataSource>

Wir können das DefaultValue des CategoryID-Parameters programmgesteuert im Page_Load-Ereignishandler zuweisen.

' Assign the ProductsByCategoryDataSource's
' CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters("CategoryID").DefaultValue = _
    randomCategoryView(0)("CategoryID").ToString()

Mit dieser Ergänzung enthält die Seite eine GridView, die die Produkte anzeigt, die der zufällig ausgewählten Kategorie zugeordnet sind.

Screenshot der Seite

Abbildung 15: Keine Parameterquelle oder keinen Standardwert angeben (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Zusammenfassung

Mit SqlDataSource können Seitenentwickler parametrisierte Abfragen definieren, deren Parameterwerte hartcodiert, aus vordefinierten Parameterquellen abgerufen oder programmgesteuert zugewiesen werden können. In diesem Lernprogramm haben wir erfahren, wie Sie eine parametrisierte Abfrage aus dem Assistenten zum Konfigurieren von Datenquellen für Ad-hoc-SQL-Abfragen und gespeicherte Prozeduren erstellen. Außerdem haben wir die Verwendung hartcodierter Parameterquellen, eines Websteuerelements als Parameterquelle und die programmgesteuerte Angabe des Parameterwerts untersucht.

Wie bei objectDataSource bietet die SqlDataSource auch Funktionen zum Ändern der zugrunde liegenden Daten. Im nächsten Lernprogramm sehen wir uns an, wie man INSERT, UPDATE und DELETE Anweisungen mit dem SqlDataSource definiert. Nachdem diese Anweisungen hinzugefügt wurden, können wir die integrierten Einfüge-, Bearbeitungs- und Löschfunktionen verwenden, die den GridView-, DetailsView- und FormView-Steuerelementen inhärent sind.

Glückliche Programmierung!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft Web Technologies zusammen. Scott arbeitet als unabhängiger Berater, Trainer und Schriftsteller. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Stunden. Er kann unter mitchell@4GuysFromRolla.com. oder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NET zu finden ist.

Besonderer Dank an

Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüfer für dieses Lernprogramm waren Scott Clyde, Randell Schmidt und Ken Pespisa. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn dies der Fall ist, schreiben Sie mir unter mitchell@4GuysFromRolla.com.