Question

exécuter des scripts SQL pour modifier le schéma de base de données. Il ressemble à ceci:

using (var command = connection.CreateCommand())
{
    command.CommandText = script;
    command.ExecuteNonQuery();
}

En outre, les commandes sont exécutées dans une transaction.

Les regards scrip comme ceci:

Alter Table [TableName]
ADD [NewColumn] bigint NULL

Update [TableName]
SET [NewColumn] = (SELECT somevalue FROM anothertable)

Je reçois une erreur, parce que NewColumn n'existe pas. Il semble analyser et valider avant son exécution.

Quand j'exécute l'ensemble des choses dans le Management Studio, je peux mettre GO entre les déclarations, il fonctionne. Quand je mets GO dans le script, ADO.NET se plaint (syntaxe incorrecte près de 'GO').

Je pourrais diviser le script dans des scripts séparés et l'exécuter dans les commandes séparées, ce serait difficile à gérer. Je pourrais partager sur tous les GO, l'analyse moi-même script. Je pense juste qu'il devrait y avoir une meilleure solution et que je ne comprenais pas quelque chose. Comment les scripts comme celui-ci être exécutés?


Ma mise en œuvre si quelqu'un est intéressé, selon la réponse de John Saunders:

List<string> lines = new List<string>();
while (!textStreamReader.EndOfStream)
{
    string line = textStreamReader.ReadLine();
    if (line.Trim().ToLower() == "go" || textStreamReader.EndOfStream)
    {
        ExecuteCommand(
            string.Join(Environment.NewLine, lines.ToArray()));

        lines.Clear();
    }
    else
    {
        lines.Add(line);
    }
}
Était-ce utile?

La solution

Vous devez exécuter chaque lot séparément. En particulier, pour exécuter un script qui peut contenir plusieurs lots (mots-clés « GO »), vous devez diviser le script sur les mots-clés « GO ».

Non testé:

string script = File.ReadAllText("script.sql");
string[] batches = script.Split(new [] {"GO"+Environment.NewLine}, StringSplitOptions.None);
foreach (string batch in batches)
{
    // run ExecuteNonQuery on the batch
}

Autres conseils

Ne pas utiliser l'une des bibliothèques je ne sais combien ORM pour le faire? Bon: -)

Pour être complètement sûr lors de l'exécution des scripts qui font des changements structurels utilisent SMO plutôt que SqlClient et faire MARS sûr n'est pas activée par la chaîne de connexion (SMO se plaindra normalement si elle est de toute façon). Rechercher ServerConnection classe et ExecuteNonQuery - autre DLL bien sûr: -)

La diff est que dll SMO Pases le script-est de SQL il est donc authentique équivalent de courir dans SSMS ou via la ligne isql cmd. Slicing sur les extrémités GO-s jusqu'à de plus en plus dans l'analyse beaucoup plus à chaque fois que vous rencontrez un autre pépin (comme GO peut être au milieu d'un commentaire sur plusieurs lignes, il peut y avoir plusieurs instructions USE, un script peut être laisser tomber le très DB SQLClient connecté à - oups :-). Je viens de tuer une telle chose dans le code de base que j'ai hérité (après des scripts plus complexes en conflit avec MARS et MARS est bon pour le code de production, mais pas pour des trucs admin).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top