Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Használd a(z) SqlBatch egy rendezett objektumgyűjtemény SqlBatchCommand elküldésére egy nyitott SqlConnection-n keresztül. Minden batch parancsnak megvan a saját parancsszövege, parancstípusa, paraméterei, parancsviselkedése és az érintett sorok száma.
Használd SqlBatch , amikor egy alkalmazásnak különálló parancsai vannak, amelyeket együtt szeretne küldeni. Használj egy paraméterezett SqlCommand példányt, ha a munka egy utasításból vagy tárolt eljárásból áll. Nagy sorkészletek esetén használjon SqlBulkCopy elemet vagy táblázatértékű paramétert.
A cikkben szereplő példák feltételezik, hogy egy megnyitott, connection nevű SqlConnection az AdventureWorks mintaadatbázist célozza meg.
A C#-példákhoz using Microsoft.Data.SqlClient; szükséges. Azok a példák, amelyek SqlDbType-t vagy CommandBehavior-et használnak, using System.Data;-t is megkövetelnek. A(z) DbDataReader használó példákhoz using System.Data.Common; szükséges.
Verzió és platform támogatás
A példák a Microsoft.Data.SqlClient 7.1.0-t célozzák. Válassz egy csomagverziót és célkeretrendszert, amelyet a Microsoft.Data.SqlClient támogatási életciklusa támogat az alkalmazásod számára.
SqlBatch a DbBatch-ből származik modern .NET-en. A Microsoft.Data.SqlClient a .NET Framework és a .NET Standard 2.0 csomagösszetevőiben is elérhetővé teszi a SqlBatch-t. A nyilvános felület a célkeretrendszertől függően eltérhet, ezért fordítsd le az alkalmazást minden kiadott célhoz.
Köteg létrehozása
Hozz létre egy köteget egy nyitott kapcsolathoz, majd parancsokat adj hozzá végrehajtási sorrendben:
using var batch = new SqlBatch(connection);
batch.BatchCommands.Add(new SqlBatchCommand("""
SELECT TOP (3) ProductID, Name
FROM Production.Product
ORDER BY ProductID;
"""));
batch.BatchCommands.Add(new SqlBatchCommand("""
SELECT TOP (3) SalesOrderID, OrderDate
FROM Sales.SalesOrderHeader
ORDER BY SalesOrderID;
"""));
using DbDataReader reader = batch.ExecuteReader();
do
{
while (reader.Read())
{
Console.WriteLine($"{reader.GetValue(0)} | {reader.GetValue(1)}");
}
}
while (reader.NextResult());
CommandType.Text az alapértelmezett érték. Állíts be egy CommandType.StoredProcedure kötegparancsot egy tárolt eljáráshoz. A(z) CommandType.TableDirect beállítása ArgumentOutOfRangeException hibát dob.
Paraméterek hozzáadása a batch parancsokhoz
A paraméterek egy egyénhez SqlBatchCommandtartoznak. Ugyanaz a helyőrzőnév két batch parancsban nem ugyanazt az értéket használja:
using var batch = new SqlBatch(connection);
var products = new SqlBatchCommand("""
SELECT ProductID, Name
FROM Production.Product
WHERE ProductSubcategoryID = @id
ORDER BY ProductID;
""");
products.Parameters.Add("@id", SqlDbType.Int).Value = 2;
batch.BatchCommands.Add(products);
var orders = new SqlBatchCommand("""
SELECT SalesOrderID, OrderDate
FROM Sales.SalesOrderHeader
WHERE SalesPersonID = @id
ORDER BY SalesOrderID;
""");
orders.Parameters.Add("@id", SqlDbType.Int).Value = 279;
batch.BatchCommands.Add(orders);
using DbDataReader reader = batch.ExecuteReader();
Állítsd be minden paraméter SQL típusát, valamint az alkalmazandó méretét, pontosságát és léptékét az adatbázis szerződéséből. További információ: Paraméterek konfigurálása.
Adatmódosító parancsok végrehajtása
Használd ExecuteNonQuery vagy ExecuteNonQueryAsync amikor a batch megváltoztatja az adatokat, és nincs szükséged eredménysorokra. A visszaadott érték az érintett sorok teljes száma, amikor a sorszámok rendelkezésre állnak. Végrehajtás után minden parancs RecordsAffected a saját darabszámát jelzi.
Ez a példa visszavonja a változtatásait:
using SqlTransaction transaction = connection.BeginTransaction();
using var batch = new SqlBatch(connection, transaction);
var firstUpdate = new SqlBatchCommand("""
UPDATE Sales.SalesOrderHeader
SET Status = @status
WHERE SalesOrderID = @salesOrderId;
""");
firstUpdate.Parameters.Add("@status", SqlDbType.TinyInt).Value = 2;
firstUpdate.Parameters.Add("@salesOrderId", SqlDbType.Int).Value = 43659;
batch.BatchCommands.Add(firstUpdate);
var secondUpdate = new SqlBatchCommand("""
UPDATE Sales.SalesOrderHeader
SET Status = @status
WHERE SalesOrderID = @salesOrderId;
""");
secondUpdate.Parameters.Add("@status", SqlDbType.TinyInt).Value = 2;
secondUpdate.Parameters.Add("@salesOrderId", SqlDbType.Int).Value = 43660;
batch.BatchCommands.Add(secondUpdate);
int totalRows = batch.ExecuteNonQuery();
Console.WriteLine($"Total rows: {totalRows}");
foreach (SqlBatchCommand command in batch.BatchCommands)
{
Console.WriteLine(command.RecordsAffected);
}
transaction.Rollback();
Több eredmény olvasása
Használd ExecuteReader vagy ExecuteReaderAsync, amikor bármelyik parancs sorokat ad vissza. Az olvasó az eredményeket a kötegelt parancsok sorrendjében mutatja be. Hívd NextResult vagy NextResultAsync amíg a visszatérési értéke false nem lesz.
Egy parancs nem hozhat létre sorkészletet, egyetlen sorkészletet vagy több sorkészletet. Ne feltételezd, hogy egy NextResult hívás egy SqlBatchCommand-nek felel meg.
Parancsviselkedés használata
Adjon át egy csomagszintű CommandBehavior elemet a(z) ExecuteReaderAsync vagy ExecuteReader számára, ha az olvasónak szekvenciális hozzáférésre van szüksége, vagy le kell zárnia a kapcsolatot:
using var batch = new SqlBatch(connection);
batch.BatchCommands.Add(new SqlBatchCommand("""
SELECT DocumentSummary
FROM Production.Document
WHERE DocumentSummary IS NOT NULL;
"""));
using DbDataReader reader =
batch.ExecuteReader(CommandBehavior.SequentialAccess);
char[] buffer = new char[4096];
while (reader.Read())
{
using TextReader summary = reader.GetTextReader(0);
int count;
while ((count = summary.Read(buffer, 0, buffer.Length)) > 0)
{
Console.Out.Write(buffer, 0, count);
}
Console.WriteLine();
}
A kötegszintű túlterhelt változatok csak CommandBehavior.Default, CommandBehavior.SequentialAccess, CommandBehavior.CloseConnection és ezeknek az értékeknek a kombinációit fogadják el. Más érvényes értékek, például SingleRow, SchemaOnly és KeyInfo, ArgumentOutOfRangeException kivételt dobnak, ha egy kötegszintű overloadnak adják át. A batch-szintű viselkedési túlterhelések a Microsoft.Data.SqlClient 7.1-es verziójától kezdve érhetők el.
Állítsa be a(z) CommandBehavior beállítást egy adott parancshoz olyan lehetőségekhez, mint a SingleRow, SchemaOnly és KeyInfo. Használd a batch-szintű túlterhelést a(z) SequentialAccess és CloseConnection esetén.
Használjon tranzakciót
SqlBatch nem teszi a parancsait atomi műveletté. Használj explicit tranzakciót, amikor minden parancsot együtt kell véglegesíteni vagy vissza kell vonni. Ez a példa visszagörgetődik, így az AdventureWorks változatlan marad:
using SqlTransaction transaction = connection.BeginTransaction();
using var batch = new SqlBatch(connection, transaction);
batch.BatchCommands.Add(new SqlBatchCommand("""
UPDATE Sales.SalesOrderHeader
SET Status = 2
WHERE SalesOrderID = 43659;
"""));
batch.BatchCommands.Add(new SqlBatchCommand("""
UPDATE Sales.SalesOrderHeader
SET Status = 2
WHERE SalesOrderID = 43660;
"""));
batch.ExecuteNonQuery();
transaction.Rollback();
Akkor hívd a(z) Commit elemet a(z) Rollback helyett, ha az alkalmazás elfogadja a teljes köteget. A tranzakciót a végrehajtás előtt rendeljük hozzá. A tranzakciónak és a batchnek ugyanazt a kapcsolatot kell használniuk. A SqlClient nem írja felül az aszinkron tranzakciós módszereket, tehát BeginTransactionAsync, CommitAsync és RollbackAsync szinkron módon fejeződik be. További információért lásd: Feladatalapú SQL tranzakciós módszerek használata.
Kezeld az időtúllépéseket, megszakításokat és hibákat
Állítsa be Timeout másodpercben a köteghez. A batch a kapcsolat Command Timeout beállítását használja, ha beállítasz egyet. Egyébként az alapértelmezett idő 30 másodperc. A(z) 0 értéknek nincs időkorlátja, és negatív értékek esetén a rendszer ArgumentException kivételt jelez. Adj át egy lemondási tokent egy aszinkron metódusnak, amikor a hívónak abba kell hagynia a várakozást, vagy hívd meg a(z) Cancel elemet. A lemondás csak a lehetőségekhez mérten történik. A művelet lehet, hogy a megszakítás hatálybalépése előtt befejeződik.
Ha a végrehajtás meghiúsul, kapd el a(z) SqlException kivételt, és vizsgáld meg az összes elemet annak Errors gyűjteményében.
BatchCommand azonosítja a kapcsolódó SqlBatchCommand elemet, amikor ez az információ elérhető:
using var batch = new SqlBatch(connection);
batch.BatchCommands.Add(new SqlBatchCommand(
"SELECT TOP (1) ProductID FROM Production.Product;"));
batch.BatchCommands.Add(new SqlBatchCommand("SELECT 1 / 0;"));
try
{
using DbDataReader reader = batch.ExecuteReader();
do
{
while (reader.Read())
{
Console.WriteLine(reader.GetValue(0));
}
}
while (reader.NextResult());
}
catch (SqlException exception)
{
Console.WriteLine(
exception.BatchCommand is null
? "The batch failed."
: $"Failed command: {exception.BatchCommand.CommandText}");
}
Az olvasó végrehajtása inkrementális. Egy későbbi batch parancsból származó hiba megjelenhet, amikor Read vagy NextResult előrehalad az adott parancsra, ezért dolgozd fel az olvasót a try blokk belsejében.
Ne naplózza az olyan paraméterértékeket, amelyek hitelesítő adatokat, tokeneket vagy érzékeny adatokat tartalmaznak. A hibamezőkkel és tájékoztató üzenetekkel kapcsolatban lásd: Hibák és üzenetek kezelése.