2009-07-06 6 views
0

J'ai un petit travail qui prend un fichier texte d'e-mails/codes postaux et les insère dans une table sql server 2005. Il lit chaque ligne du fichier source, vérifie qu'il analyse une adresse e-mail/un code postal valide, crée une commande d'insertion sql, l'ajoute à un générateur de chaîne et l'exécute éventuellement. Je veux faire une seule exécution au lieu des appels sql individuels car il y aura peut-être plusieurs milliers d'insertions.Création d'instructions sql par lots

Cela fonctionne, mais j'aimerais savoir si c'est une mauvaise approche. Quelle est la meilleure pratique ici?

Dim SqlString As String = "insert into [CollectedEmail] values('{0}','{1}');" 

Do Until sourceFile.Peek = -1 
     line = sourceFile.ReadLine 
     If line.Length > 0 Then 

      Dim emailAddress As String = Trim(line.Substring(0, EmailLength)) 
      Dim zipcode As String = Trim(line.Substring(EmailLength + 2, ZipCodeLength)) 

      If CVal.validEmail(emailAddress) AndAlso CVal.validZip(zipcode) Then 
       SQL.AppendLine(String.Format(SqlString, emailAddress, zipcode)) 
      ElseIf CVal.validEmail(emailAddress) Then 
       SQL.AppendLine(String.Format(SqlString, emailAddress, "")) 
      Else 
       badAddresses.WriteLine(emailAddress) 
      End If 
     End If 

    Loop 
InsertToDatabase(SQL.ToString) 

Merci

Répondre

1

Pour inserts en vrac, consultez la classe .NET 2.0 partir, SqlBulkCopy (dans l'espace de noms System.Data.SqlClient)

Marc Gravell a posté un exemple de son utilisation ici SO: Copy from one database table to another C#

Mise à jour en réponse à des commentaires: vous pouvez lire les données dépolluées dans un DataTable, et l'utiliser avec SqlBulkCopy , similaire à example.

+0

Est-ce que l'approche correcte est alors de nettoyer le fichier source d'origine dans un autre fichier plat, puis d'utiliser la classe SqlBulkCopy? – GernBlandston

0

Vous pouvez également regrouper vos e-mails dans un paramètre XML et disposer d'une procédure stockée capable de le traiter.

CREATE PROCEDURE [dbo].[saveEmails] 
( 
    @emails xml 
) 
AS 
BEGIN 
SET NOCOUNT ON; 


insert into collectedemail 
(address 
,zipcode) 
select 
x.value('address[1]', 'nvarchar(255)') 
,x.value('zipcode[1]', 'nvarchar(10)') 
from @emails.nodes('/items/item') emails(x) 

END 
GO 

Vous pouvez garder un compteur qui stocke le nombre d'enregistrements que vous avez mis en attente et puis exécuter après une taille de lot que vous spécifiez.

Questions connexes