57 votes

À l'aide de "ALLER" dans une transaction

Je suis en train de construire une application web qui tente d'installer/mettre à niveau la base de données sur App_Start. Le cadre de la procédure d'installation est de veiller à ce que la base de données a l'asp.net les fonctionnalités installées. Pour cela, je suis en utilisant le Système.Web.De la gestion.SqlServices objet.

Mon intention est de faire tout le travail de base de données à l'intérieur d'une transaction SQL et si tout cela échoue, annuler la transaction et de laisser la base de données intactes.

le SqlServices objet possède une méthode "Installer" qui prend un ConnectionString mais pas une opération. Ainsi, au lieu-je utiliser SqlServices.GenerateApplicationServicesScripts comme suit:

string script = SqlServices.GenerateApplicationServicesScripts(true, SqlFeatures.All, _connection.Database);
SqlHelper.ExecuteNonQuery(transaction, CommandType.Text, script, ...);

puis-je utiliser le SqlHelper à partir de la Bibliothèque d'Entreprise.

mais cela déclenche une Exception avec un bout-charge d'erreurs, quelques-uns sont ci-dessous

Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near the keyword 'USE'.
Incorrect syntax near the keyword 'CREATE'.
Incorrect syntax near 'GO'.
The variable name '@cmd' has already been declared. Variable names must be unique within a query batch or stored procedure.

Je suis en supposant que c'est une question avec l'aide de l'instruction GO à l'intérieur d'une Transaction SQL.

Comment puis-je obtenir ce script généré de travail lors de l'exécution de cette manière.

66voto

gbn Points 197263

GO n'est pas un mot clé SQL.

C'est un lot de séparateur utilisé par le client des outils (comme SSMS) pour briser le script en entier en lots

Vous aurez à briser le script en lots vous-même ou utiliser quelque chose comme sqlcmd avec l'option "-c ALLER" ou osql pour faire face à "ALLER"

46voto

CodeGrue Points 2109

Je veux juste ajouter que si vous avez le nom de votre transaction, vous pouvez inclure plusieurs ALLER sections à l'intérieur et ils vont tous revenir sous la forme d'une unité. Tels que:

BEGIN TRANSACTION TransactionWithGos;
GO

SET XACT_ABORT ON; -- Roll back everything if error occurs in script
GO

-- do stuff
GO

COMMIT TRANSACTION TransactionWithGos;
GO

18voto

Wyatt Barnett Points 12541

Pauvre homme moyen de résoudre ce problème: diviser le SQL sur la route des déclarations. Quelque chose comme:

private static List<string> getCommands(string testDataSql)
{
    string[] splitcommands = File.ReadAllText(testDataSql).Split(new string[]{"GO\r\n"}, StringSplitOptions.RemoveEmptyEntries);
    List<string> commandList = new List<string>(splitcommands);
    return commandList;
}

[qui a été copiée de l'application que je suis en train de travailler sur maintenant. Je garoun-freaking-té de ce code]

Puis juste ExecuteNonQuery() - dessus de la liste. Obtenir la fantaisie et à l'utilisation des transactions pour des points bonus.

# # # # # POINTS BONUS # # # # # #

Comment gérer la transaction bits dépend vraiment des objectifs opérationnels. Fondamentalement, vous pourriez faire de deux façons:

a) renvoyer l'ensemble de l'exécution en une seule opération, ce qui ferait de sens si l'on voulait vraiment tout pour soit exécuter ou de l'échec (meilleure option à mon humble avis)

b) Enrouler chaque appel à l' ExecuteNonQuery() dans sa propre transaction. Eh bien, en fait, chaque appel est sa propre transaction. Mais vous pourriez attraper les exceptions et les transporter à l'élément suivant. Bien sûr, si c'est typique généré DDL choses, souvent de la partie suivante dépend de la partie précédente, donc une partie défaillante sera probablement bugger tout le toutou.

5voto

cmsjr Points 16766

MODIFIER comme indiqué ci-dessous, j'ai spécifié tran où le lot a été fait correct.

Le problème n'est pas que vous ne pouvez pas utiliser d'ALLER dans une transaction tant qu'indique la fin d'un lot, et n'est pas en soi une commande T-SQL. Vous pouvez exécuter le script en entier à l'aide de l'utilitaire SQLCMD, ou de le diviser sur le GO et la réalisation de chaque lot à son tour.

2voto

KM. Points 51800

testez vos scripts:

  • restaurer une production de sauvegarde sur un serveur de sauvegarde
  • exécuter des scripts avec des GOs

installer vos scripts:

  • l'arrêt de l'application
  • passez en mode mono-utilisateur
  • sauvegarde de la base de données
  • exécuter des scripts avec GOs, sur l'échec de la sauvegarde de la restauration
  • revenir au mode multi-utilisateur
  • redémarrez l'application

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X