SQL Server: Quelles sont les instructions de dosage (c'est à dire à l'aide de “GO”) bon pour?
Je sais que dans SQL Server GO
est considéré comme un séparateur de lots.
Ma question est: Quel est l'intérêt d'avoir un séparateur de lot? Quel est l'avantage de vous et pourquoi voudriez-vous utiliser?
Exemple: j'ai souvent vu qu'il est utilisé dans le code SQL comme suit et je ne vois pas pourquoi cela serait considéré comme une meilleure pratique. Aussi loin que je peux dire que le code serait le même sans tous les GO
états:
USE AdventureWorks2012;
GO
BEGIN TRANSACTION;
GO
IF @@TRANCOUNT = 0
BEGIN
SELECT FirstName, MiddleName
FROM Person.Person WHERE LastName = 'Adams';
ROLLBACK TRANSACTION;
PRINT N'Rolling back the transaction two times would cause an error.';
END;
ROLLBACK TRANSACTION;
PRINT N'Rolled back the transaction.';
GO
(source: la documentation technet):
- double possible de qu'est-Ce que l'utilisation de SQL Server Management Studio?
- non ce n'est pas la même (j'ai même lié à ce poste dans ma question). Ce poste dit essentiellement que le GO est un séparateur de lot, mais ma question est de demander à ce qu'un séparateur de lot qui est bon pour
- Regardez la réponse fournie par tvanfosson dans cette question (26 upvotes).
- merci de remarquer que la réponse. Il donne de bonnes informations de fond supplémentaires, mais ne répond pas à la racine de la question que j'ai eu (heck, une personne a même laissé un commentaire sur la question, en demandant à ce que le dosage des scripts est bon pour l')
- Certainement un duplicata de celui-ci... stackoverflow.com/questions/2668529/t-sql-go-statement/...
- La réponse est un peu confus mais. Il n'est pas nécessaire de séparer en différents lots afin d'obtenir de petites transactions.
- Il y a des cas où, si vous souhaitez que plusieurs états en un seul script, vous devez utiliser un séparateur de lot, comme ALLER. Voir ma réponse.
- Il n'existe pratiquement pas (le cas échéant) dans les cas où vous devez utiliser
GO
. Avez-vous des exemples où il ne peut pas être remplacé parEXEC
? - Lorsque la direction a dit: "Ne pas utiliser le SQL dynamique ici." 🙂 Mais sérieusement, non, SQL dynamique serait trop de travail, mais un séparateur de lot semble plus propre à moi.
- Complètement d'accord, il est souvent plus propre. La coloration syntaxique et l'intellisense sont évidemment complètement perdu quand
EXEC
-ing cordes. Juste le mot doit exagère les choses!
Vous devez vous connecter pour publier un commentaire.
Dans l'exemple, c'est de n'utiliser que ce soit.
Beaucoup de déclarations doivent être les seuls dans le lot, cependant.
Comme
CREATE PROCEDURE
.Aussi souvent après avoir fait des modifications de schéma (par exemple, l'ajout d'une nouvelle colonne à une table existante) états en utilisant le nouveau schéma doit être compilé séparément dans un autre lot.
Généralement une alternative à la soumission de lots séparés séparés par
GO
est d'exécuter l'instruction SQL dans un enfant lot à l'aide d'EXEC
CREATE TABLE T(X INT);SELECT * FROM T
fonctionne très bien que leSELECT
est soumise à un report de la compilation. Mais ensuite, après la création de la table desALTER TABLE T ADD Y INT;SELECT Y FROM T
échoue avec un nom de colonne non valide erreur comme une déclaration de ne pas obtenir de compilation différé.go
(raisons de vouloir l'utiliser), je peux voir dans les docs sont "Les déclarations du lot sont ensuite compilées dans un seul plan d'exécution", ou si vous voulez forcer les variables locales à être abandonnés à partir d'un cadre de travail. Cependant, le condition pour utilisergo
après des choses commealter
pour éviter les erreurs est inexplicable: je ne vois aucune raison d'exiger que d'un développeur. Docs disent aussi "les Utilisateurs doivent suivre les règles pour les lots". Il va sur le "par exemple" mais je ne peux pas trouver une description exacte de la "les règles".go
après chaque déclaration? Si oui, est-ce que vous ne pouvez pas utiliser des variables dans ODBC scripts, car ils seront implicitement compris hors de portée après chaque déclaration implicite dego
? Autant de questions. Ne trouvez pas de réponses.Comme TechNet dit,
GO
il signifie la fin d'un traitement SQL pour SQL services publics. Par exemple, lorsque SQL Server Management Studio rencontre le séparateur de lot, il sait tout le texte de la mesure est indépendante de la requête SQL.Nous utilisons une technique similaire dans notre logiciel. Nous gardons tous nos procs, le schéma, les scripts, les conversions de données, etc., dans les fichiers de script SQL (vérifié à la source de contrôle). Lors de notre installateur de lire un de ces fichiers de script, ALLEZ raconte notre analyseur ", vous pouvez exécuter le SQL que vous avez déjà lu".
La fonctionnalité intéressante sur un lot séparateur comme
GO
est que vous pouvez inclure deux requêtes SQL dans le même script, qui serait normalement entraîner une erreur. Par exemple, essayez de supprimer et de recréer la même procédure stockée dans le même fichier de script:Si vous exécutez le code ci-dessus, vous obtiendrez un message d'erreur:
Et SSMS va vous montrer l'erreur:
À l'aide d'un séparateur de lot peut vous aider à obtenir autour de cette erreur:
Ce qui est très pratique si, par exemple, vous voulez qu'un seul script SQL dans le contrôle de code source pour maintenir une procédure stockée ou une fonction. Nous utilisons ce modèle fréquemment.
Une autre chose intéressante que vous pouvez faire est de l'utiliser pour exécuter une requête plusieurs fois:
Comme les réponses à cette question DONC démontrer, vous pouvez également le configurer pour tout ce que vous voulez. Si vous voulez mess avec vos collègues, définissez le séparateur de lots à quelque chose comme "OÙ" au lieu de "ALLER". Amusant! 🙂
go 10
est, en fait, utile, mais non obligatoire, de la manièrego
est nécessaire dans votre exemple précédent.go
reposent sur la connaissance de la implications de dosage - principalement qu'un seul plan d'exécution est préparé à partir de la totalité du lot. J'ai donc finalement décidé d'apporter ma propre réponse à essayer de l'expliquer le "pourquoi" - voir ci-dessous, ici: stackoverflow.com/a/56370223/3714936Comme Martain dit, des états tels que la création de la PROCÉDURE doit être les seuls dans un lot.
Par exemple, j'utilise lot de séparateurs à chaque fois que je créer des procédures stockées et ajouter des autorisations à un utilisateur particulier.
Si j'ai laissé de côté le " go " puis je finirais avec une procédure stockée qui accorde des droits chaque fois qu'il exécute. De cette façon, je peux écrire en même temps et être sûr que je ne suis pas d'écrire des procédures stockées qui se brisent quand je les appelle. Par exemple
Avoir lu beaucoup de réponses, et a contribué à des commentaires, voici ce que je pense.
La vraie question est "Quel est l'intérêt d'avoir un lot?"
Il y a 2 implications de traitement par lots qui ont un sens, et il y a une autre utilisation de
go
qui peut être utile:1. Tous les énoncés dans un lot sont compilés dans un même plan d'exécution
Les répercussions sur vous, comme un SQL developer, je ne sais pas. Mais il est là. L'implication de ceci est que vous ne pouvez pas avoir certaines déclarations dans le même lot. Par exemple, vous ne pouvez pas
ALTER
une table pour ajouter une colonne, puisselect
cette colonne dans le lot - parce que lors de la compilation du plan d'exécution, que la colonne n'existe pas de sélection.Je pense qu'il y a une discussion ouverte, comme si SQL Server doit être en mesure de le détecter par lui-même sans obligeant les promoteurs à inclure
go
états dans leurs scripts. En outre, les docs disent les connexions ODBC ne peut jamais question ungo
de commande. Il n'est pas clair pour moi comment un script de s'exécuter via ODBC allait se comporter si elle comprenait laALTER
/SELECT
exemple qui vient d'être donné.2. Déclarés localement variables n'existent pas seulement dans le champ d'application du lot pour lequel ils ont été déclarés
Ces deux points conjugués genre de sucer. J'ai un script qui crée et modifie DB structures (tables, procédures, etc) et je tiens à déclarer les variables au début du script qui sera utilisé pour régir le comportement du script dans l'ensemble. Dès que j'ai besoin de mettre en place un traitement par lots (en raison, par exemple, un
ALTER
déclaration - voir mon point 1 ci-dessus), ces "config" variables tomber hors de portée et ne peut pas être utilisé plus bas sur le script. Ma solution est de créer une table, persistent les variables de configuration dans la table, puis lire à partir de cette table tout au long de mon script, puis chute de la table à la fin (dans le cas où quelqu'un d'autre est en face de cette).Cette deuxième implication peut effectivement être utilisé à son avantage - si votre script est de faire beaucoup de travail et tout simplement, vous voulez vous débarrasser de toutes vos variables locales, vous pouvez simplement inclure un
GO
déclaration puis déclarer de nouvelles variables (ie. et de ré-utiliser les mêmes noms, si c'est ce que vous voulez).3. ALLER a un paramètre optionnel (nommé "comte") qui indique au serveur de répéter les actions batch plusieurs fois
Cet usage semble être gentil fonctionnalités supplémentaires ajoutés à la
GO
déclaration. Je crois que la première ou la fonction principale deGO
qui a trait à la compilation d'un seul plan d'exécution, comme indiqué au point 1 - sinon, le mot peut aussi bien être quelque chose commeREPEAT 10
- mais répéter ce que? Le lot. SansGO
signifiant d'un lot, d'une répétition de la commande ne pourrait jamais répéter l'état de la simple déclaration. DoncGO
est une belle façon de répéter lots.Référence
Tout cela vient d'essayer de comprendre le MS documentation sur l'ALLER. De nombreuses autres réponses ici, et sur d'autres questions - choix des morceaux de la documentation, mais je pense que la documentation elle-même ne parvient pas à vraiment expliquer pourquoi il y a un avantage pour le traitement par lots, en premier lieu, d'où ma contribution à un déjà bien commenté question.
Additif
Après avoir écrit ce qui précède, je n'ai trouvé le Règles pour l'Utilisation des Lots mentionné par Microsoft dans le
GO
de la documentation. La page liée explique qu'un plan d'exécution se compose de plusieurs états. Il dit aussi que les instructions individuelles peuvent être re-compilé dans un nouveau plan d'exécution (c'est à dire par SQL Server, tandis que le traitement du lot, automatiquement). Ainsi, par exemple, à la suite d'une déclaration àCREATE TABLE
vous pourriez avoir uneINSERT
dans cette table. QueINSERT
déclaration sera recompilé après la table a été créée dans la déclaration antérieure.Cela renforce l'idée que SQL Server probablement pu détecter ces scénarios où un
ALTER
d'un tableau est suivi par unSELECT
et qu'il a besoin de re-compiler leSELECT
(voir mon point 1 ci-dessus), et éventuellement c'est exactement ce qui se passe si vous utilisez ODBC (voir le point 1 ci-dessus).Aucun de ces nouvelles informations modifie les 3 points ci-dessus. Le lien que j'ai juste donné contient des lectures complémentaires et se termine avec les "règles" qui sont ceux-ci:
CRÉER par DÉFAUT, CRÉER FONCTION de, CRÉER PROCÉDURE, CRÉER une RÈGLE, CRÉER un SCHÉMA, de CRÉER un DÉCLENCHEUR, et des instructions CREATE VIEW ne peut pas être combiné avec d'autres états dans un lot. L'instruction CREATE doit démarrer le traitement. Toutes les autres instructions qui suivent dans ce lot sera interprétée comme faisant partie de la définition de la première instruction de création.
Un tableau ne peut pas être modifié et le nouveau colonnes référencées dans le même lot.
Si une instruction EXECUTE est la première instruction d'un lot, le mot-clé d'EXÉCUTION n'est pas nécessaire. Le mot-clé d'EXÉCUTION est nécessaire si l'instruction EXECUTE n'est pas la première instruction dans le lot.