2009-10-14 6 views
3

I et en essayant de créer une méthode pour exécuter un fichier .sql sur une base de données SQL Server.Exécuter le fichier SQL sur un serveur SQL en utilisant C#

Le code que j'ai est:

SqlConnection dbCon = new SqlConnection(connstr); 
FileInfo file = new FileInfo(Server.MapPath("~/Installer/JobTraksDB.sql")); 
StreamReader fileRead = file.OpenText(); 
string script = fileRead.ReadToEnd(); 
fileRead.Close(); 

SqlCommand command = new SqlCommand(script, dbCon); 
try 
{ 
    dbCon.Open(); 
    command.ExecuteNonQuery(); 
    dbCon.Close(); 
} 
catch (Exception ex) 
{ 
    throw new Exception("Failed to Update the Database, check your Permissions."); 
} 

Mais je continue à obtenir des erreurs sur "syntaxe incorrecte près de mot-clé 'GO'" Mon fichier SQL commence comme ceci: (généré à partir de SQL Management Studio)

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_PADDING ON 
GO 
CREATE TABLE [dbo].[Job_Types](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Name] [varchar](50) NOT NULL, 
CONSTRAINT [PK_JobTypes] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
SET ANSI_PADDING OFF 
GO 

Comment dois-je exécuter ce script?

Répondre

5

Voici comment nous le faisons:

protected virtual void ExecuteScript(SqlConnection connection, string script) 
    { 
     string[] commandTextArray = System.Text.RegularExpressions.Regex.Split(script, "\r\n[\t ]*GO"); 

     SqlCommand _cmd = new SqlCommand(String.Empty, connection); 

     foreach (string commandText in commandTextArray) 
     { 
      if (commandText.Trim() == string.Empty) continue; 
      if ((commandText.Length >= 3) && (commandText.Substring(0, 3).ToUpper() == "USE")) 
      { 
       throw new Exception("Create-script contains USE-statement. Please provide non-database specific create-scripts!"); 
      } 

      _cmd.CommandText = commandText; 
      _cmd.ExecuteNonQuery(); 
     } 

    } 

Charger le contenu de votre script en utilisant une fonction de lecture de fichiers.

+1

Je peux voir un bug: Supposons que j'ai une procédure nommée 'sp' et que le script est' 'sp ''. 'commandText.Substring (0, 3)' lancera une 'IndexOutOfRangeException'. –

+0

@Mehrdad: Oui, erreur commune, en supposant que String.Substring (0, xxx) fonctionne exactement comme la fonction VB Left (xxx). :-) –

+0

@WowtaH: A part ça, c'est bien fait. :-) –

4

GO est et non une instruction T-SQL. C'est un indice pour les outils client tels que sqlcmd ou Management Studio pour fractionner les instructions et les envoyer en tant que lots individuels. Ils utilisent une commande GO sur sa propre ligne comme marqueur pour indiquer la fin d'un lot. Vous ne devez pas envoyer le fichier dans son ensemble à SQL Server. Note latérale: Il existe une méthode File.ReadAllText que vous pouvez utiliser à la place de ces trois lignes.

+0

ok , alors quelle est la meilleure façon d'effectuer une fonction de création de table par lots? (ceci est pour un installateur Web) – dkarzon

+0

La manière naïve est de diviser le fichier par des lignes contenant la commande 'GO' et d'envoyer chaque partie à SQL Server dans une boucle. Cependant, je pense que vous réinventez la roue car certains projets open source (par exemple DotNetNuke) utilisent une technique similaire pour leur installation. Vous pouvez vérifier leur source. –

+0

vérifier ma réponse. L'échantillon de code fait le travail parfaitement. – WowtaH

0

Si vous êtes prêt à inclure quelques DLLs SMO, vous pouvez exécuter un script avec quelques lignes de code:

using Microsoft.SqlServer.Management.Smo; 
using Microsoft.SqlServer.Management.Common; 

    public void Exec(string script) 
    { 
     using (var conn = new SqlConnection(ConnString)) 
     { 
      var server = new Server(new ServerConnection(conn)); 
      server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError); 
     } 
    } 

Les poignées bibliothèque SMO la question GO vous n'avez pas . Vous aurez besoin de référencer les ensembles suivants:

Microsoft.SqlServer.ConnectionInfo.dll

Microsoft.SqlServer.Management.Sdk.Sfc.dll

Microsoft.SqlServer.Smo.dll

Questions connexes