SQL Server: à quoi servent les instructions de traitement par lots (c'est-à-dire en utilisant "GO")?
Je le sais dans SQL Server GO
est considéré comme un séparateur de lots .
Ma question Est: Quel est le point d'avoir un séparateur de lot? Quel est l'avantage de vous et pourquoi voudriez-vous utiliser?
Exemple: Je l'ai souvent vu utilisé dans le code SQL comme suit et je ne vois pas pourquoi il serait considéré comme une meilleure pratique. Pour autant que je sache, le code serait le même sans toutes les instructions GO
:
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: technet la documentation):
3 réponses
Dans l'exemple, il n'est d'aucune utilité.
Beaucoup d'instructions doivent être les seules dans le lot cependant.
Comme CREATE PROCEDURE
.
Souvent, après avoir apporté des modifications au schéma (par exemple en ajoutant une nouvelle colonne à une table existante), les instructions utilisant le nouveau schéma doivent être compilées séparément dans un lot différent.
Généralement, une alternative à la soumission de lots séparés séparés par {[1] } consiste à exécuter le SQL dans un lot enfant en utilisant EXEC
Comme le dit TechNet, GO
cela signifie la fin D'un lot SQL aux utilitaires SQL. Par exemple, lorsque SQL Server Management Studio rencontre le séparateur de lots, il sait que tout le texte jusqu'à présent est une requête SQL indépendante.
, Nous utilisons une technique similaire dans notre logiciel. Nous conservons tous nos procs, scripts de schéma, conversions de données, etc., dans les fichiers de script SQL (vérifié dans le contrôle de source). Lorsque notre programme d'installation lit l'un de ces fichiers de script, GO indique à notre analyseur " vous pouvez exécuter le SQL que vous avez déjà lu".
La fonctionnalité intéressante d'un séparateur de lots comme GO
est que vous pouvez inclure deux requêtes SQL ensemble dans le même script qui provoquerait normalement 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:
if exists (select * from sys.procedures where name = 'sp_test')
drop procedure sp_test
create procedure sp_test as
begin
select 1
end
Si vous exécutez le code ci-dessus, vous obtiendrez une erreur:
Msg 156, Niveau 15, État 1, Procédure sp_test, ligne 5 syntaxe incorrecte près du mot clé 'commencer'.
Et SSMS vous montrera l'erreur:
Syntaxe incorrecte. 'CREATE PROCEDURE' doit être la seule instruction d'un lot.
L'utilisation d'un séparateur de lots peut vous aider à contourner cette erreur:
if exists (select * from sys.procedures where name = 'sp_test')
drop procedure sp_test
GO
create procedure sp_test as
begin
select 1
end
C'est très pratique si, par exemple, vous voulez qu'un seul script SQL dans le contrôle de source maintienne une procédure ou une fonction stockée. 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 de plusieurs temps:
INSERT INTO MyTable (...) ...
GO 10 -- run all the above 10 times!
Commeles réponses à cette question SO le démontrent, vous pouvez également le configurer à ce que vous voulez. Si vous voulez jouer avec vos collègues, définissez le séparateur de lots sur quelque chose comme "WHERE" au lieu de"GO". Amusant! :)
Comme l'a dit Martain, les instructions telles que CREATE PROCEDURE doivent être les seules dans un lot.
Par exemple, j'utilise des séparateurs de lots chaque fois que je crée des procédures stockées et ajoute des autorisations à un certain utilisateur. Si j'avais laissé de côté le "go", je me retrouverais avec une procédure stockée qui accorde des droits chaque fois qu'elle s'exécute. De cette façon, je peux les écrire en même temps et être sûr que je n'écris pas de procédures stockées qui se cassent quand je les appelle. Par exemple
create procedure [procedurename]
(parameters)
as begin
select prefname, lastname from people
end
go
grant execute on [procedurename] to [username]