Verwenden von parametrisierten Abfragen mit dem SqlDataSource-Steuerelement (VB)
von Scott Mitchell
In diesem Tutorial setzen wir unseren Blick auf das SqlDataSource-Steuerelement fort und erfahren, wie sie parametrisierte Abfragen definieren. Die Parameter können sowohl deklarativ als auch programmgesteuert angegeben und von einer Reihe von Speicherorten wie der Abfragezeichenfolge, dem Sitzungsstatus, anderen Steuerelementen usw. abgerufen werden.
Einführung
Im vorherigen Tutorial haben wir erfahren, wie Sie das SqlDataSource-Steuerelement verwenden, um Daten direkt aus einer Datenbank abzurufen. Mit dem Assistenten Datenquelle konfigurieren können Sie die Datenbank auswählen und dann entweder die Spalten auswählen, die aus einer Tabelle oder Sicht 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 Sicht auswählen oder eine benutzerdefinierte SQL-Anweisung eingeben, wird der Eigenschaft des SqlDataSource-Steuerelements SelectCommand
die resultierende Ad-hoc-SQL-Anweisung SELECT
zugewiesen, und diese SELECT
Anweisung wird ausgeführt, wenn die SqlDataSource-Methode Select()
aufgerufen wird (entweder programmgesteuert oder automatisch aus einem Datenwebsteuerelement).
Die SQL-Anweisungen SELECT
, die in den vorherigen Tutorialdemos verwendet wurden, fehlen Klauseln WHERE
. In einer SELECT
-Anweisung kann die WHERE
-Klausel verwendet werden, um die zurückgegebenen Ergebnisse zu begrenzen. Um beispielsweise die Namen von Produkten anzuzeigen, die mehr als 50,00 USD kosten, können wir die folgende Abfrage verwenden:
SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00
In der Regel werden die in einer Klausel verwendeten Werte von einer WHERE
externen Quelle bestimmt, z. B. von einem Abfragezeichenfolgenwert, einer Sitzungsvariablen oder von einer Benutzereingabe aus einem Websteuerelement auf der Seite. Im Idealfall werden solche Eingaben durch die Verwendung von Parametern angegeben. Bei Microsoft SQL Server werden Parameter mit @parameterName
bezeichnet, wie in:
SELECT ProductName
FROM Products
WHERE UnitPrice > @Price
SqlDataSource unterstützt parametrisierte Abfragen sowohl für -Anweisungen als auch für SELECT
- UPDATE
und DELETE
INSERT
-Anweisungen. Darüber hinaus können die Parameterwerte automatisch aus einer Vielzahl von Quellen abgerufen werden: Abfragezeichenfolge, Sitzungsstatus, Steuerelemente auf der Seite usw. oder können programmgesteuert zugewiesen werden. In diesem Tutorial erfahren Sie, wie Sie parametrisierte Abfragen definieren und die Parameterwerte sowohl deklarativ als auch programmgesteuert angeben.
Hinweis
Im vorherigen Tutorial haben wir die ObjectDataSource, die unsere Wahl in den ersten 46 Tutorials war, mit der SqlDataSource verglichen und dabei ihre konzeptionellen Ähnlichkeiten festgestellt. Diese Ähnlichkeiten erstrecken sich auch auf Parameter. Die Parameter von ObjectDataSource, die den Eingabeparametern für die Methoden in der Geschäftslogikebene zugeordnet sind. Mit der SqlDataSource werden die Parameter direkt in der SQL-Abfrage definiert. Beide Steuerelemente verfügen über Auflistungen von Parametern für ihre Select()
Methoden , Insert()
, und Update()
Delete()
beide können diese Parameterwerte aus vordefinierten Quellen (Querystringwerte, Sitzungsvariablen usw.) aufgefüllt oder programmgesteuert zugewiesen werden.
Erstellen einer parametrisierten Abfrage
Der Assistent zum Konfigurieren von Datenquellen des SqlDataSource-Steuerelements bietet drei Möglichkeiten zum Definieren des Befehls, der zum Abrufen von Datenbankdatensätzen ausgeführt werden soll:
- Durch Auswählen der Spalten aus einer vorhandenen Tabelle oder Sicht,
- Wenn Sie eine benutzerdefinierte SQL-Anweisung eingeben, oder
- Durch Auswählen einer gespeicherten Prozedur
Beim Auswählen von Spalten aus einer vorhandenen Tabelle oder Sicht 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 die Parameter jedoch direkt in die WHERE
-Klausel eingeben (indem @parameterName
Sie die einzelnen Parameter bezeichnen). Eine gespeicherte Prozedur besteht aus mindestens einer SQL-Anweisung, 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 sqlDataSource s SelectCommand
angegeben wird, sehen wir uns alle drei Ansätze an. Öffnen Sie zunächst die ParameterizedQueries.aspx
Seite im SqlDataSource
Ordner, ziehen Sie ein SqlDataSource-Steuerelement aus der Toolbox auf die Designer, und legen Sie es ID
auf festProducts25BucksAndUnderDataSource
. Klicken Sie als Nächstes im Smarttag des Steuerelements auf den Link Datenquelle konfigurieren. 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 Sicht
Wenn Sie die Daten auswählen, die mit dem SqlDataSource-Steuerelement aus der Datenbank zurückgegeben werden sollen, können Sie mit dem Assistenten Datenquelle konfigurieren einfach die Spalten auswählen, die aus einer vorhandenen Tabelle oder Sicht 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. Wählen Sie wie im vorherigen Tutorial die Tabelle Products aus der Dropdownliste aus, und überprüfen Sie die ProductID
Spalten , ProductName
und UnitPrice
.
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 aufzunehmen, klicken Sie auf die WHERE
Schaltfläche, die das Dialogfeld Klausel hinzufügen WHERE
öffnet (siehe Abbildung 2). Um einen Parameter hinzuzufügen, 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 zum Filtern verwendet werden soll (=, <, <=, >usw.). Wählen Sie schließlich die Quelle des Werts des Parameters 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 aufzunehmen.
In diesem Beispiel geben wir nur die Ergebnisse zurück, bei denen der UnitPrice
Wert kleiner oder gleich $25,00 ist. Wählen Sie UnitPrice
daher aus der Dropdownliste Spalte und <= aus der Dropdownliste Operator aus. Wenn Sie einen hartcodierten Parameterwert verwenden (z. B. $25,00) oder wenn der Parameterwert programmgesteuert angegeben werden soll, wählen Sie in der Dropdownliste Quelle die Option Keine 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.
Abbildung 2: Einschränken der aus dem Dialogfeld Klausel hinzufügen WHERE
zurückgegebenen Ergebnisse (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 jetzt eine WHERE
Klausel mit einem Parameter namens @UnitPrice
enthalten:
SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)
Hinweis
Wenn Sie im Dialogfeld Klausel hinzufügen WHERE
mehrere Bedingungen in der WHERE
-Klausel angeben, verknüpft der Assistent diese mit dem AND
Operator. Wenn Sie eine OR
in die WHERE
-Klausel einschließen müssen (z WHERE UnitPrice <= @UnitPrice OR Discontinued = 1
. B. ), müssen Sie die SELECT
Anweisung über den Bildschirm für benutzerdefinierte SQL-Anweisungen erstellen.
Schließen Sie die Konfiguration der SqlDataSource ab (klicken Sie auf Weiter und dann auf Fertig stellen), und überprüfen Sie dann das deklarative Markup des SqlDataSource-Markups. Das Markup enthält jetzt eine <SelectParameters>
Auflistung, die die Quellen für die Parameter in der SelectCommand
beschreibt.
<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 @UnitPrice
Parameter in angewendet SelectCommand
, bevor er an die Datenbank gesendet wird. Das Nettoergebnis ist, dass nur Produkte unter oder gleich 25,00 USD aus der Products
Tabelle zurückgegeben werden. Um dies zu bestätigen, fügen Sie der Seite eine GridView hinzu, binden sie an diese Datenquelle, und zeigen Sie die Seite dann über einen Browser an. Es sollten nur die Produkte aufgeführt werden, die kleiner als oder gleich 25,00 USD sind, wie Abbildung 3 bestätigt.
Abbildung 3: Nur Produkte, die kleiner als oder gleich 25,00 USD 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 unter einem bestimmten Schwellenwert liegen. Fügen Sie zunächst ParameterizedQueries.aspx
der Seite ein Textfeld hinzu, um diesen Schwellenwert vom Benutzer zu erfassen. Legen Sie die TextBox-Eigenschaft ID
auf fest MaxPrice
. Fügen Sie ein Button-Websteuerelement hinzu, und legen Sie dessen Text
Eigenschaft auf Übereinstimmende Produkte anzeigen fest.
Ziehen Sie als Nächstes eine GridView auf die Seite, und wählen Sie aus ihrem Smarttag aus, um eine neue SqlDataSource mit dem Namen ProductsFilteredByPriceDataSource
zu erstellen. Fahren Sie im Assistenten Datenquelle konfigurieren mit dem Bildschirm Angeben einer benutzerdefinierten SQL-Anweisung oder gespeicherten Prozedur fort (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.
Abbildung 4: Zurückgeben nur der Produkte, die kleiner als oder gleich einem Parameterwert sind (Klicken Sie, um das bild in voller Größe anzuzeigen)
Da die Abfrage Parameter enthält, werden wir auf dem nächsten Bildschirm im Assistenten zur Quelle der Parameterwerte aufgefordert. Wählen Sie in der Dropdownliste Parameterquelle die Option Steuerelement und MaxPrice
(der Wert des TextBox-Steuerelements ID
) in der Dropdownliste ControlID aus. Sie können auch einen optionalen Standardwert eingeben, der für den Fall verwendet werden soll, dass der Benutzer keinen Text in das MaxPrice
Textfeld eingegeben hat. Geben Sie vorerst keinen Standardwert ein.
Abbildung 5: Die MaxPrice
TextBox s-Eigenschaft Text
wird als Parameterquelle verwendet (Klicken Sie, um das bild in voller Größe anzuzeigen)
Schließen Sie den Assistenten Datenquelle konfigurieren 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 von SqlDataSource <SelectParameters>
ein ControlParameter
ist, der zusätzliche Eigenschaften wie ControlID
und PropertyName
enthält. Wenn die SqlDataSource-Methode Select()
aufgerufen wird, greift die den ControlParameter
Wert aus der angegebenen Websteuerelementeigenschaft ab und weist ihn dem entsprechenden Parameter in der SelectCommand
zu. In diesem Beispiel wird die MaxPrice
s Text-Eigenschaft 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 dem MaxPrice
Textfeld ein Wert fehlt, werden keine Datensätze in der GridView angezeigt.
Abbildung 6: Keine Datensätze werden angezeigt, wenn das MaxPrice
Textfeld leer ist (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Der Grund, warum keine Produkte angezeigt werden, liegt daran, 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 wie 5.00 in das Textfeld ein, und klicken Sie auf die Schaltfläche Übereinstimmende Produkte anzeigen. Beim Postback informiert SqlDataSource die GridView darüber, dass sich eine ihrer Parameterquellen geändert hat. Folglich wird gridView an die SqlDataSource neu gebunden und zeigt diese Produkte unter oder gleich 5,00 USD an.
Abbildung 7: Produkte, die kleiner als oder gleich 5,00 USD sind, werden angezeigt (Klicken Sie, um das bild in voller Größe anzuzeigen)
Anfängliche Anzeige aller Produkte
Anstatt beim ersten Laden der Seite keine Produkte anzuzeigen, sollten alle Produkte angezeigt werden. Eine Möglichkeit, alle Produkte aufzulisten, wenn das MaxPrice
TextBox leer ist, besteht darin, den Standardwert des Parameters auf einen wahnsinnig hohen Wert wie 1000000 festzulegen, da es unwahrscheinlich ist, dass Northwind Traders jemals einen Bestand haben wird, dessen Einzelpreis 1.000.000 USD überschreitet. Dieser Ansatz ist jedoch kurzsichtig und funktioniert in anderen Situationen möglicherweise nicht.
In den vorherigen Tutorials – Deklarative Parameter und Master-/Detailfilterung mit einer DropDownList sahen wir uns mit einem ähnlichen Problem konfrontiert. Unsere Lösung bestand darin, diese Logik in die Geschäftslogikebene zu bringen. Insbesondere untersuchte die BLL den eingehenden Wert, und wenn es sich um einen reservierten Wert handelte NULL
, wurde der Aufruf an die DAL-Methode weitergeleitet, die alle Datensätze zurückgibt. Wenn der eingehende Wert ein normaler Filterwert war, wurde ein Aufruf der DAL-Methode durchgeführt, die eine SQL-Anweisung ausgeführt hat, die eine parametrisierte WHERE
Klausel mit dem angegebenen Wert verwendet.
Leider umgehen wir die Architektur, wenn wir die SqlDataSource verwenden. Stattdessen müssen wir die SQL-Anweisung anpassen, um alle Datensätze intelligent zu erfassen, wenn der @MaximumPrice
Parameter oder ein reservierter Wert ist NULL
. Für diese Übung haben wir es so, dass, wenn der @MaximumPrice
Parameter gleich -1.0
ist, alle Datensätze zurückgegeben werden (-1.0
funktioniert als reservierter Wert, da kein Produkt einen negativen UnitPrice
Wert haben kann). Um dies zu erreichen, 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.0
ist, werden nur die Produkte zurückgegeben, deren UnitPrice
Wert kleiner oder gleich dem @MaximumPrice
Parameterwert ist. Wenn Sie den Standardwert des @MaximumPrice
Parameters auf -1.0
festlegen, wird auf der ersten Seite geladen (oder immer, wenn das MaxPrice
Textfeld leer ist), @MaximumPrice
der Wert von -1.0
aufweist, und alle Produkte werden angezeigt.
Abbildung 8: Jetzt werden alle Produkte angezeigt, wenn das MaxPrice
Textfeld leer ist (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Bei diesem Ansatz gibt es einige Einschränkungen zu beachten. Beachten Sie zunächst, dass der Datentyp des Parameters von seiner Verwendung in der SQL-Abfrage abgeleitet wird. Wenn Sie die WHERE
Klausel von @MaximumPrice = -1.0
in @MaximumPrice = -1
ändern, behandelt die Runtime den Parameter als ganze Zahl. Wenn Sie dann versuchen, das MaxPrice
Textfeld 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 in der WHERE
-Klausel verwenden@MaximumPrice = -1.0
, oder legen Sie die ControlParameter
Eigenschaft des Type
Objekts auf Decimal fest.
Zweitens kann die Abfrage-Engine durch Hinzufügen von WHERE
zur OR @MaximumPrice = -1.0
-Klausel keinen Index für UnitPrice
verwenden (vorausgesetzt, dass ein Index vorhanden ist), was zu einer Tabellenüberprüfung führt. Dies kann sich auf die Leistung auswirken, wenn eine ausreichende Anzahl von Datensätzen in der Products
Tabelle vorhanden ist. Ein besserer Ansatz wäre es, diese Logik in eine gespeicherte Prozedur zu verschieben, in der eine IF
Anweisung entweder eine SELECT
Abfrage aus der Products
Tabelle ohne Klausel WHERE
ausführt, wenn alle Datensätze zurückgegeben werden müssen, oder eine, 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 SQL-Anweisungen verwendet werden können, die in der gespeicherten Prozedur definiert sind. Beim Konfigurieren der SqlDataSource für die Verwendung einer gespeicherten Prozedur, die Eingabeparameter akzeptiert, können diese Parameterwerte mit den gleichen Techniken wie mit 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, GetProductsByCategory
die einen Parameter namens @CategoryID
akzeptiert und alle Spalten der Produkte zurückgibt, deren CategoryID
Spalte mit übereinstimmt @CategoryID
. Um eine gespeicherte Prozedur zu erstellen, wechseln Sie zum server-Explorer, und führen Sie einen Drilldown in die Datenbank ausNORTHWND.MDF
. (Wenn die 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 NORTHWND.MDF
Datenbank mit der 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 zur Eingabe der Parameter der gespeicherten Prozedur (@CategoryID
in diesem instance) aufgefordert, wonach die Ergebnisse im Ausgabefenster angezeigt werden.
Abbildung 9: Die GetProductsByCategory
gespeicherte Prozedur bei Ausführung mit einer @CategoryID
von 1 (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Verwenden Sie diese gespeicherte Prozedur, 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 Benutzerdefinierte SQL-Anweisung oder gespeicherte Prozedur angeben fort, wählen Sie das Optionsfeld Gespeicherte Prozedur aus, und wählen Sie die GetProductsByCategory
gespeicherte Prozedur aus der Dropdownliste aus.
Abbildung 10: Auswählen der GetProductsByCategory
gespeicherten Prozedur aus der liste Drop-Down (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Da die gespeicherte Prozedur einen Eingabeparameter akzeptiert (@CategoryID
), werden wir durch Klicken auf Weiter aufgefordert, die Quelle für diesen Parameterwert anzugeben. CategoryID
Getränke ist 1. Behalten Sie daher die Dropdownliste Parameterquelle bei Keine bei, und geben Sie 1 in das Textfeld DefaultValue ein.
Abbildung 11: Verwenden Sie einen Hard-Coded Wert von 1, um die Produkte in der Getränkekategorie zurückzugeben (Klicken Sie hier, um das bild in 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 und die SelectCommandType
-Eigenschaft auf StoredProcedure
festgelegt, was angibt, dass der name SelectCommand
einer gespeicherten Prozedur und nicht eine Ad-hoc-SQL-Anweisung ist.
<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. Es werden nur die Produkte angezeigt, die zur Kategorie Getränke gehören, obwohl alle Produktfelder angezeigt werden, da die GetProductsByCategory
gespeicherte Prozedur alle Spalten aus der Products
Tabelle zurückgibt. Natürlich können wir die im GridView-Dialogfeld Spalten bearbeiten angezeigten Felder einschränken oder anpassen.
Abbildung 12: Alle Getränke werden angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Schritt 4: Programmgesteuertes Aufrufen einer Select()-Anweisung von SqlDataSource
Die Beispiele, die wir im vorherigen Tutorial und in diesem Tutorial bisher gesehen haben, haben SqlDataSource-Steuerelemente direkt an eine GridView gebunden. Auf die Daten des SqlDataSource-Steuerelements kann jedoch programmgesteuert zugegriffen und im Code aufgezählt werden. Dies kann besonders nützlich sein, wenn Sie Daten abfragen müssen, um sie zu überprüfen, aber nicht anzeigen müssen. Anstatt den gesamten Boilerplate-ADO.NET Code schreiben zu müssen, um eine Verbindung mit der Datenbank herzustellen, den Befehl angeben und die Ergebnisse abrufen zu müssen, können Sie sqlDataSource diesen monotonen Code verarbeiten lassen.
Stellen Sie sich zum programmgesteuerten Arbeiten mit den SqlDataSource-Daten vor, dass Ihr Chef Sie mit einer Anforderung zum Erstellen einer Webseite angesprochen hat, auf der der Name einer zufällig ausgewählten Kategorie und der zugehörigen Produkte angezeigt wird. Das heißt, wenn ein Benutzer diese Seite besucht, möchten wir nach dem Zufallsprinzip 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, eines zum Abrufen einer zufälligen Kategorie aus der Categories
Tabelle und eines, um die Produkte der Kategorie abzurufen. In diesem Schritt erstellen wir die SqlDataSource, die einen zufälligen Kategoriedatensatz abruft. Schritt 5 befasst sich mit dem Erstellen der SqlDataSource, die die Produkte der Kategorie abruft.
Beginnen Sie mit dem Hinzufügen einer SqlDataSource zu ParameterizedQueries.aspx
, und legen Sie ihre ID
auf fest RandomCategoryDataSource
. Konfigurieren Sie sie so, dass die folgende SQL-Abfrage verwendet wird:
SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()
ORDER BY NEWID()
gibt die Datensätze in zufälliger Reihenfolge zurück (siehe Verwenden NEWID()
von Datensätzen nach dem Zufallsprinzip). SELECT TOP 1
gibt den ersten Datensatz aus dem Resultset zurück. Zusammen gibt diese Abfrage die CategoryID
Spaltenwerte und CategoryName
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 ihre ID
Eigenschaft auf fest CategoryNameLabel
, und löschen Sie dessen Text
Eigenschaft. Um die Daten programmgesteuert aus einem SqlDataSource-Steuerelement abzurufen, müssen wir dessen Select()
Methode aufrufen. Die Select()
-Methode erwartet einen einzelnen Eingabeparameter vom Typ DataSourceSelectArguments
, der angibt, wie die Daten vor der Rückgabe gesendet werden sollen. Dies kann Anweisungen zum Sortieren und Filtern der Daten enthalten und wird von den Datenwebsteuerelementen beim Sortieren oder Paging der Daten aus einem SqlDataSource-Steuerelement verwendet. Für unser Beispiel müssen die Daten jedoch nicht geändert werden, bevor sie zurückgegeben werden, und daher wird das DataSourceSelectArguments.Empty
Objekt übergeben.
Die Select()
-Methode gibt ein -Objekt zurück, das implementiert IEnumerable
. Der genaue Typ, der zurückgegeben wird, hängt vom Wert der Eigenschaft des SqlDataSource-Steuerelements DataSourceMode
ab. Wie im vorherigen Tutorial erläutert, kann diese Eigenschaft auf einen Wert von oder DataSet
DataReader
festgelegt werden. Wenn auf DataSet
festgelegt ist, gibt die Select()
-Methode ein DataView-Objekt zurück. Wenn auf DataReader
festgelegt ist, gibt sie ein Objekt zurück, das implementiert IDataReader
. Da die RandomCategoryDataSource
SqlDataSource-Eigenschaft DataSourceMode
auf DataSet
(Standard) festgelegt ist, arbeiten wir mit einem DataView-Objekt.
Der folgende Code veranschaulicht, wie sie die Datensätze aus der RandomCategoryDataSource
SqlDataSource als DataView abrufen 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 die 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 die DataView lose typisiert ist. Um auf einen bestimmten Spaltenwert zu verweisen, müssen wir den Namen der Spalte als Zeichenfolge übergeben ( in diesem Fall CategoryName). Abbildung 13 zeigt die Meldung, die beim Anzeigen der CategoryNameLabel
Seite in angezeigt wird. Natürlich wird der angezeigte tatsächliche Kategoriename von der RandomCategoryDataSource
SqlDataSource bei jedem Seitenbesuch (einschließlich Postbacks) zufällig ausgewählt.
Abbildung 13: Der Zufällig ausgewählte Kategoriename wird angezeigt (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Hinweis
Wenn die Eigenschaft des SqlDataSource-Steuerelements DataSourceMode
auf DataReader
festgelegt wurde, hätte der Rückgabewert der Select()
-Methode in IDataReader
umgewandelt werden müssen. Um den CategoryName
Spaltenwert aus der ersten Zeile zu lesen, verwenden wir Code wie:
If randomCategoryReader.Read() Then
Dim categoryName as String = randomCategoryReader("CategoryName').ToString()
...
End If
Wenn SqlDataSource zufällig eine Kategorie auswählt, können wir die GridView hinzufügen, in der die Produkte der Kategorie aufgelistet sind.
Hinweis
Anstatt ein Label-Websteuerelement zum Anzeigen des Kategorienamens zu verwenden, hätten wir der Seite eine FormView oder DetailsView hinzufügen können, die an die SqlDataSource gebunden ist. 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 Tutorial gesehen haben, haben entweder einen hartcodierten Parameterwert oder einen wert 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. Um unser aktuelles Beispiel abzuschließen, 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
Spaltenwert festgelegt werden muss, der von sqlDataSource RandomCategoryDataSource
im Page_Load
Ereignishandler zurückgegeben wird.
Fügen Sie zunächst der Seite ein GridView-Element hinzu, und binden Sie sie an eine neue SqlDataSource namens ProductsByCategoryDataSource
. Wie in Schritt 3 konfigurieren Sie sqlDataSource so, dass die GetProductsByCategory
gespeicherte Prozedur aufgerufen wird. Lassen Sie die Dropdownliste Parameterquelle auf Keine festgelegt, geben Sie jedoch keinen Standardwert ein, da wir diesen Standardwert programmgesteuert festlegen.
Abbildung 14: Geben Sie keine Parameterquelle oder einen Standardwert an (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nach Abschluss des SqlDataSource-Assistenten sollte das resultierende deklarative Markup in etwa 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 den 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.
Abbildung 15: Geben Sie keine Parameterquelle oder einen Standardwert an (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 Tutorial haben wir erfahren, wie Sie eine parametrisierte Abfrage über den Assistenten zum Konfigurieren von Datenquellen sowohl für Ad-hoc-SQL-Abfragen als auch für gespeicherte Prozeduren erstellen. Außerdem haben wir die Verwendung hartcodierter Parameterquellen, eines Websteuerelements als Parameterquelle und der programmgesteuerten Angabe des Parameterwerts untersucht.
Wie bei ObjectDataSource bietet sqlDataSource auch Funktionen zum Ändern der zugrunde liegenden Daten. Im nächsten Tutorial erfahren Sie, wie Sie die Anweisungen , UPDATE
und DELETE
mit sqlDataSource definierenINSERT
. Nachdem diese Anweisungen hinzugefügt wurden, können wir die integrierten Funktionen zum Einfügen, Bearbeiten und Löschen verwenden, die den GridView-, DetailsView- und FormView-Steuerelementen innewohnen.
Viel Spaß beim Programmieren!
Zum Autor
Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.
Besonderer Dank an
Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Hauptprüfer für dieses Tutorial waren Scott Clyde, Randell Schmidt und Ken Pespisa. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.