Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Parametry předávají hodnoty příkazu samostatně od jeho textu jazyka Transact-SQL (T-SQL). Používejte SqlParameter objekty místo spojování nebo interpolace hodnot do SQL příkazů. Parametry pomáhají chránit před SQL injekcí a zachovávají databázový typ hodnoty.
Příklady v tomto článku předpokládají, že otevřené připojení SqlConnection s názvem connection cílí na ukázkovou databázi AdventureWorks.
Příklady v C# vyžadují using Microsoft.Data.SqlClient;. Příklady, které používají SqlDbType, také vyžadují using System.Data;.
Přidejte vstupní parametry
Přidejte parametr pro každý zástupný symbol hodnoty v textu příkazu. Zadejte typ SQL Server parametru a přiřadte jeho hodnotu:
const string sql = """
SELECT ProductID, Name, ListPrice
FROM Production.Product
WHERE ProductSubcategoryID = @subcategoryId
AND ListPrice >= @minimumPrice
ORDER BY ListPrice;
""";
using var command = new SqlCommand(sql, connection);
command.Parameters.Add("@subcategoryId", SqlDbType.Int).Value = 2;
command.Parameters.Add("@minimumPrice", SqlDbType.Money).Value = 1_000m;
using SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(
$"{reader.GetInt32(0)}: {reader.GetString(1)} ({reader.GetDecimal(2):C})");
}
Použijte stejnou velikost písmen pro název parametru v textu příkazu a v SqlParameter. SQL Server porovnává názvy proměnných pomocí kolace serveru, takže nesoulad selže s chybou „Je nutné deklarovat skalární proměnnou“ na serveru s kolací rozlišující velká a malá písmena.
Práce se zástupnými symboly parametrů
Microsoft.Data.SqlClient používá pojmenované parametry ve tvaru @parameterName. Zástupné symboly pozičního otazníku (?) nejsou podporovány.
Zástupné symboly parametrů představují hodnoty, nikoli SQL identifikátory nebo syntaxi. Nemůžete použít parametr pro název tabulky, název sloupce, směr třídění nebo celý SQL fragment. Pokud aplikace dynamicky vybere identifikátor, ověřte jej podle seznamu povolených a přidejte jej do textu příkazu až po ověření. Pokračujte v předávání všech datových hodnot jako parametrů.
Pro textové příkazy Microsoft.Data.SqlClient posílá parametrizované příkazy do serveru SQL Server přes sp_executesql. SQL Server může znovu použít plán vykonání, pokud text příkazu a definice parametrů zůstanou stejné.
Zadání datových typů parametrů
Nastavte SqlDbType explicitně, když aplikace zná cílový typ SQL Server. Nastavte také typově specifická metadata, jako jsou Size, Precision a Scale, pokud je to relevantní.
Tento příklad odpovídá hodnotám ve sloupcích nvarchar(50) a datetime v Person.Person:
const string sql = """
SELECT BusinessEntityID, FirstName, LastName
FROM Person.Person
WHERE LastName = @lastName
AND ModifiedDate >= @modifiedSince
ORDER BY BusinessEntityID;
""";
using var command = new SqlCommand(sql, connection);
SqlParameter lastName = command.Parameters.Add(
"@lastName",
SqlDbType.NVarChar,
50);
lastName.Value = "O'Brien";
SqlParameter modifiedSince = command.Parameters.Add(
"@modifiedSince",
SqlDbType.DateTime);
modifiedSince.Value = new DateTime(2013, 1, 1);
Přizpůsobení metadat parametru cílovému sloupci zabraňuje implicitním převodům a brání tomu, aby změny délky řetězce nebo počtu desetinných míst měnily definici parametru.
Pro desetinné hodnoty nastavte přesnost a počet desetinných míst explicitně. Sloupec Weight v Production.Product používá decimal(8, 2):
const string sql = """
SELECT ProductID, Name, Weight
FROM Production.Product
WHERE Weight >= @minimumWeight
ORDER BY Weight;
""";
using var command = new SqlCommand(sql, connection);
SqlParameter minimumWeight = command.Parameters.Add(
"@minimumWeight",
SqlDbType.Decimal);
minimumWeight.Precision = 8;
minimumWeight.Scale = 2;
minimumWeight.Value = 10.25m;
Předat hodnoty NULL databázi
Přiřaďte Value, aby se odeslala databáze NULL. C# null nereprezentuje parametr SQL Server NULL pro běžné skalární parametry:
const string sql = """
SELECT SalesOrderID, OrderDate, SalesPersonID
FROM Sales.SalesOrderHeader
WHERE (@salesPersonId IS NULL OR SalesPersonID = @salesPersonId)
ORDER BY SalesOrderID;
""";
using var command = new SqlCommand(sql, connection);
SqlParameter salesPersonId = command.Parameters.Add(
"@salesPersonId",
SqlDbType.Int);
int? selectedSalesPersonId = null;
salesPersonId.Value = selectedSalesPersonId.HasValue
? selectedSalesPersonId.Value
: DBNull.Value;
Selektivně používejte odvozená metadata
Metoda AddWithValue odvozuje metadata parametrů z hodnoty za běhu. Inference je praktická, když jsou odvozená metadata stabilní a odpovídají typu databáze. Může vytvářet různé definice parametrů, když se mění délka řetězce, desetinná přesnost nebo jiné hodnotové charakteristiky.
Preferujte Add s explicitním SqlDbType pro produkční příkazy, jejichž cílové schéma je známo. Nepředávejte C# null do proměnné AddWithValue; zadejte typ a místo něj přiřaďte DBNull.Value.
Znovu použít parametry příkazu
Vytvořte parametr jednou a změňte pouze jeho Value, když spustíte stejný příkaz s různými hodnotami:
const string sql = """
SELECT TOP (1) Name, ListPrice
FROM Production.Product
WHERE ProductSubcategoryID = @subcategoryId
ORDER BY ListPrice DESC;
""";
using var command = new SqlCommand(sql, connection);
SqlParameter subcategoryId = command.Parameters.Add(
"@subcategoryId",
SqlDbType.Int);
foreach (int id in new[] { 1, 2, 3 })
{
subcategoryId.Value = id;
using SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
Console.WriteLine($"{id}: {reader.GetString(0)}");
}
}
Nepřidávejte další parametr se stejným názvem při každém provedení. Znovu použijte existující parametr nebo vymažte kolekci před jejím znovuvytvořením.
Nastavte směr předávání parametru
Direction vlastnost určuje, jak příkaz používá parametr. Nastavte ji na ParameterDirection hodnotu:
| Direction | Použít |
|---|---|
| Input | Posílá hodnotu do příkazu SQL nebo uložené procedury. Tato hodnota je výchozí. |
| Output | Přijímá hodnotu z výstupního parametru uložené procedury. |
| InputOutput | Odešle počáteční hodnotu a přijme aktualizovanou hodnotu. |
| ReturnValue | Přijímá celočíselnou hodnotu z příkazu T-SQL RETURN . |
Pro výstupní, vstupní/výstupní a parametry návratové hodnoty čtěte Value až po dokončení příkazu. Pokud příkaz vrací řádky, před načtením těchto hodnot uzavřete nebo zlikvidujte SqlDataReader.
Pro kompletní příklady uložených procedur viz Úprava dat pomocí uložených procedur.
Použijte parametry s uloženou procedurou
Nastavte StoredProcedure a použijte názvy parametrů procedury. Tento příklad volá postup dbo.uspGetEmployeeManagers zahrnutý v AdventureWorks:
using var command = new SqlCommand(
"dbo.uspGetEmployeeManagers",
connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(
"@BusinessEntityID",
SqlDbType.Int).Value = 6;
using SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(
$"{reader.GetString(2)} {reader.GetString(3)}");
}
Název parametru musí odpovídat názvu deklarovanému ve specifikaci uložené procedury.
Nakonfigurujte parametry s hodnotou tabulky
Parametr typu tabulka odesílá více řádků do uložené procedury nebo parametrizovaného příkazu. Chcete-li jeden nakonfigurovat:
- Nastavte
SqlDbType.Structured. - Nastavte TypeName na uživatelsky definovaný typ tabulky v databázi.
- Přiřaďte zdroj řádků DataTable, DbDataReader nebo
IEnumerable<SqlDataRecord>.
DataTable s definovanými sloupci a bez řádků odesílá prázdnou tabulku. Prázdné pole IEnumerable<SqlDataRecord> vyvolá ArgumentException; přiřaďte C# null, aby se pro daný vstupní formulář odeslaly nulové řádky. Nepřiřazujte DBNull.Value k parametru s tabulkovou hodnotou.
Pro tvorbu typů, mapování řádků a kompletní příklady viz Parametry s hodnotou tabulky.
Nastavení hodnot streamování
Přiřaďte Stream, TextReader nebo XmlReader k Value, a postupně tak poskytněte velkou hodnotu. Pro přenos s omezenou pamětí použijte typ parametru (max), xml nebo json. Microsoft. Data.SqlClient před vykonáním bufferuje zdroj pro(max) jiné než znakové typy a binární soubory a pro starší velké objektové typy.
Typ parametru musí odpovídat hodnotě:
| Value | Kompatibilní SqlDbType hodnoty |
|---|---|
| Stream |
Binary, VarBinary nebo starší typ Image |
| TextReader |
Char, NChar, NVarChar, VarChar, starší typy Text a NText, Xml, nebo Json |
| XmlReader |
Char, NChar, NVarChar, VarChar, starší typy Text a NText, Xml, nebo Json |
Microsoft.Data.SqlClient vyvolá ArgumentException, InvalidCastException nebo SqlTypeException, když je typ objektu, SqlDbType nebo deklarovaná velikost nekompatibilní. Pro kompletní příklady nahrávání a stahování viz podpora streamování SqlClient.
Odvození informací o parametrech
DeriveParametersdotazuje SQL Server na metadata parametrů uložené procedury a nahrazuje stávající kolekci parametrů příkazu:
using var command = new SqlCommand(
"dbo.uspGetEmployeeManagers",
connection);
command.CommandType = CommandType.StoredProcedure;
SqlCommandBuilder.DeriveParameters(command);
command.Parameters["@BusinessEntityID"].Value = 6;
DeriveParameters vyžaduje pokaždé, když je volán, další komunikaci s databází. Během vývoje odvozujte metadata, když je to nutné, a poté explicitně definujte parametry v cestách citlivých na výkon.