Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Utilisez Microsoft. Data.SqlClient pour traiter de grandes valeurs sans charger d’abord la valeur complète dans la mémoire de l’application. Le streaming est utile pour les fichiers binaires, le gros texte, le XML, le JSON et le transfert serveur-à-serveur.
Le streaming ne rend pas la valeur recherchée ni les opérations simultanées sur un lecteur sûres. La connexion, la commande, le lecteur, le flux source et l’objet de destination doivent rester actifs jusqu’à la fin du transfert.
Les exemples de cet article supposent qu’un nom connection ouvert SqlConnection cible la base de données d’échantillons AdventureWorks.
Les exemples de C# nécessitent using Microsoft.Data.SqlClient;. Exemples qui utilisent SqlDbType ou CommandBehavior nécessitent using System.Data;également .
Flux de données à partir d’une base de données SQL
Exécutez la commande avec CommandBehavior.SequentialAccess et lisez les colonnes dans l’ordre ordinal. Avec l’accès séquentiel, après avoir avancé au-delà d’une colonne, ne lisez pas une colonne précédente dans la même ligne.
Utilisez ces SqlDataReader méthodes :
| Méthode | Résultat | Données SQL typiques |
|---|---|---|
| GetStream | Stream | données binaires, varbinaires, image et types définis par l’utilisateur (UDT) |
| GetTextReader | TextReader | Données de caractères et JSON |
| GetXmlReader | XmlReader | xml |
Appelez IsDBNull avant de demander un flux pour une colonne nullable. Un getter de streaming utilisé avec un type SQL incompatible jets. Consommez ou jetez le flux courant avant de lire une autre colonne, d’avancer la ligne ou de passer au résultat suivant.
GetStream n’est pas pris en charge pour les colonnes chiffrées.
GetTextReader ne supporte pas l’accès séquentiel à une colonne chiffrée.
CommandTimeouts’applique pendant que Microsoft. Data.SqlClient attend les paquets réseau lors de l’exécution et de la lecture. Le temps que votre demande passe à traiter les données déjà reçues n’est pas compté. Pour les annulations et les délais d’attente, voir Programmation asynchrone.
Données binaires de flux
AdventureWorks stocke le contenu des fichiers dans la colonne varbinary(maxProduction.Document.Document ) nullable. Cet exemple copie une valeur dans un fichier avec un tampon borné :
using var command = new SqlCommand("""
SELECT TOP (1) Document
FROM Production.Document
WHERE Document IS NOT NULL
ORDER BY ModifiedDate DESC;
""", connection);
using SqlDataReader reader = command.ExecuteReader(
CommandBehavior.SequentialAccess);
if (reader.Read())
{
using Stream source = reader.GetStream(0);
using FileStream destination = File.Create("document.bin");
source.CopyTo(destination);
}
Pour le texte, utilisez GetTextReader et copiez dans un TextWriterfichier . Pour le XML, utilisez GetXmlReader et traitez les nœuds XML sans convertir la valeur complète en chaîne.
Flux de données vers une base de données SQL
Définissez Value un objet de streaming et choisissez un type SQL compatible :
| Type de valeur | Types de paramètres compatibles |
|---|---|
| Stream |
Binary, VarBinary, et le type héritier Image |
| TextReader |
Char, NChar, VarChar, NVarChar, l’héritage Text et NText types, Xml, et Json |
| XmlReader |
Char, NChar, VarChar, NVarChar, l’héritage Text et NText types, Xml, et Json |
Définissez Size explicitement.
Size Limite le montant transféré. Utilisez-le -1(max) comme paramètre lorsque vous souhaitez envoyer le code source complet.
Pour le transfert en mémoire bornée, utiliser VarBinary, VarChar, ou NVarChar avec Size = -1, ou utiliser Xml ou Json. Microsoft. Data.SqlClient met en mémoire tampon la source dans un tableau d’octets ou une chaîne avant l’exécution pour les types non(max) caractères et binaires ainsi que pour les types hérités Image, Text, et NText .
Diffusez une valeur de paramètre
Cet exemple envoie un fichier via un paramètre varbinary(max) et renvoie le nombre d’octets reçus. Il ne stocke pas la valeur :
using FileStream input = File.OpenRead("document.bin");
using var command = new SqlCommand(
"SELECT DATALENGTH(@content);",
connection);
command.Parameters.Add(
new SqlParameter("@content", SqlDbType.VarBinary, -1)
{
Value = input
});
long length = (long)command.ExecuteScalar()!;
Console.WriteLine($"{length} bytes");
Gardez l’objet d’entrée ouvert jusqu’à la fin de l’exécution de la commande. Passer un jeton d’annulation à une méthode d’exécution asynchrone ou appeler Cancel pour demander l’annulation de l’opération de streaming. L’annulation est le meilleur effort. L’opération pourrait se terminer avant que l’annulation ne prenne effet.
Une exception au flux source ou aux erreurs de lecture : exécution de commande. Ne réessayez pas depuis le même objet à moins de pouvoir établir sa position et que l’opération de la base de données soit sûre à répéter.
Flux de données d’une base SQL à une autre
Cet exemple transmet un flux de documents AdventureWorks directement à un paramètre sur un autre ouvrage SqlConnection nommé destinationConnection. La commande d’exemple indique la longueur reçue. Remplacez-la par la commande paramétrée insert ou update de la base de données de destination :
using var readSource = new SqlCommand("""
SELECT TOP (1) Document
FROM Production.Document
WHERE Document IS NOT NULL
ORDER BY ModifiedDate DESC;
""", connection);
using SqlDataReader sourceReader = readSource.ExecuteReader(
CommandBehavior.SequentialAccess);
if (sourceReader.Read())
{
using Stream content = sourceReader.GetStream(0);
using var write = new SqlCommand(
"SELECT DATALENGTH(@content);",
destinationConnection);
write.Parameters.Add(
new SqlParameter("@content", SqlDbType.VarBinary, -1)
{
Value = content
});
Console.WriteLine(write.ExecuteScalar());
}
Les commandes source et destination ne partagent pas de transaction. Si votre application nécessite un travail atomique coordonné entre serveurs, concevez et testez cette frontière de transaction séparément.