En vérifiant du code sur le Web et des scripts générés par SQL Server Management Studio, j'ai remarqué que certaines instructions se terminent par un point-virgule.
Alors, quand dois-je l'utiliser?
En vérifiant du code sur le Web et des scripts générés par SQL Server Management Studio, j'ai remarqué que certaines instructions se terminent par un point-virgule.
Alors, quand dois-je l'utiliser?
Réponses:
À partir d'un article SQLServerCentral.Com de Ken Powers:
Le point-virgule
Le caractère point-virgule est un terminateur d'instruction. Il fait partie de la norme ANSI SQL-92, mais n'a jamais été utilisé dans Transact-SQL. En effet, il a été possible de coder T-SQL pendant des années sans jamais rencontrer de point-virgule.
Usage
Il existe deux situations dans lesquelles vous devez utiliser le point-virgule. La première situation est celle où vous utilisez une expression de table commune (CTE), et le CTE n'est pas la première instruction du lot. La seconde est l'endroit où vous émettez une instruction Service Broker et l'instruction Service Broker n'est pas la première instruction du lot.
THROW
une déclaration Service Broker? Nous devons inclure un point-virgule avant un lancer dans cet exemple:BEGIN ;THROW @Error, 'Invalid FundingID', 2; RETURN END
MERGE
trop par exemple). Comme mentionné dans d'autres réponses, dans la norme ANSI, ils sont requis
Par défaut, les instructions SQL se terminent par des points-virgules. Vous utilisez un point-virgule pour terminer les instructions, sauf si vous avez (rarement) défini un nouveau terminateur d'instruction.
Si vous n'envoyez qu'une seule instruction, techniquement, vous pouvez vous passer du terminateur d'instruction; dans un script, comme vous envoyez plusieurs déclarations, vous en avez besoin.
En pratique, incluez toujours le terminateur même si vous n'envoyez qu'une seule instruction à la base de données.
Edit: en réponse à ceux qui disent que les terminateurs d'instructions ne sont pas requis par [SGBDR particulier], bien que cela puisse être vrai, ils sont requis par la norme SQL ANSI. Dans toute programmation, si nous pouvons adhérer à une norme sans perte de fonctionnalité, nous devrions le faire, car alors ni notre code ni nos habitudes ne sont liés à un seul fournisseur propriétaire.
Avec certains compilateurs C, il est possible d'avoir void de retour principal, même si le standard exige que main retourne int. Mais cela rend notre code et nous-mêmes moins portables.
La plus grande difficulté de la programmation efficace n'est pas d'apprendre de nouvelles choses, c'est de désapprendre de mauvaises habitudes. Dans la mesure où nous pouvons éviter d'acquérir de mauvaises habitudes en premier lieu, c'est une victoire pour nous, pour notre code et pour quiconque lit ou utilise notre code.
Dans SQL2008 BOL, ils disent que dans les prochaines versions, des points-virgules seront nécessaires. Par conséquent, utilisez-le toujours.
Référence:
Vous devez l' utiliser.
La pratique consistant à utiliser un point-virgule pour terminer des instructions est standard et est en fait une exigence dans plusieurs autres plates-formes de base de données. SQL Server requiert le point-virgule uniquement dans des cas particuliers, mais dans les cas où un point-virgule n'est pas requis, son utilisation ne pose pas de problème. Je vous recommande vivement d'adopter la pratique de terminer toutes les instructions par un point-virgule. Non seulement cela améliorera la lisibilité de votre code, mais dans certains cas, cela peut vous éviter des ennuis. (Lorsqu'un point-virgule est requis et n'est pas spécifié, le message d'erreur généré par SQL Server n'est pas toujours très clair.)
Et le plus important:
La documentation de SQL Server indique que la non-terminaison des instructions T-SQL par un point-virgule est une fonctionnalité obsolète. Cela signifie que l'objectif à long terme est d'imposer l'utilisation du point-virgule dans une future version du produit. C'est une raison de plus pour prendre l'habitude de mettre fin à toutes vos déclarations, même là où elles ne sont actuellement pas requises.
Source: Microsoft SQL Server 2012 T-SQL Fundamentals par Itzik Ben-Gan.
Un exemple de pourquoi vous devez toujours utiliser ;
sont les deux requêtes suivantes (copiées à partir de ce message ):
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
THROW
END CATCH
BEGIN TRY
BEGIN TRAN
SELECT 1/0 AS CauseAnException;
COMMIT
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE();
THROW
END CATCH
not using them
technique incontournable et déconseillée, vous devez les utiliser. Sinon, il y a un risque de souffrir à l'avenir. Si vous ne prévoyez pas de mettre à niveau / changer de travail et que vous allez toujours travailler avec SQL Server 2000, vous êtes en sécurité :-)
Incorrect syntax near 'THROW'.
SQL Server 2008 (10.0.6241.0), qui est la version que je dois gérer au travail. Cela fonctionne comme indiqué en 2012. J'ai été convaincu de commencer à utiliser des points-virgules à cause de la dépréciation. Je ne pense pas que ce serait un problème en 2008 la plupart du temps.
Si je lis correctement, il sera nécessaire d'utiliser des points-virgules pour terminer les instructions TSQL. http://msdn.microsoft.com/en-us/library/ms143729%28v=sql.120%29.aspx
EDIT: J'ai trouvé un plug-in pour SSMS 2008R2 qui formatera votre script et ajoutera les points-virgules. Je pense que c'est toujours en version bêta ...
http://www.tsqltidy.com/tsqltidySSMSAddin.aspx
EDIT: J'ai trouvé un outil / plugin gratuit encore meilleur appelé ApexSQL ... http://www.apexsql.com/
Opinion personnelle: utilisez-les uniquement là où elles sont nécessaires. (Voir la réponse de TheTXI ci-dessus pour la liste requise.)
Comme le compilateur n'en a pas besoin, vous pouvez mettre partout, mais pourquoi? Le compilateur ne vous dira pas où vous en avez oublié un, vous vous retrouverez donc avec une utilisation incohérente.
[Cette opinion est spécifique à SQL Server. D'autres bases de données peuvent avoir des exigences plus strictes. Si vous écrivez SQL pour qu'il s'exécute sur plusieurs bases de données, vos besoins peuvent varier.]
tpdi a déclaré ci-dessus, "dans un script, comme vous envoyez plusieurs déclarations, vous en avez besoin." Ce n'est en fait pas correct. Vous n'en avez pas besoin.
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional'
PRINT 'Semicolons are optional';
PRINT 'Semicolons are optional';
Production:
Semicolons are optional
Semicolons are optional
Semicolons are optional
Semicolons are optional
J'ai encore beaucoup à apprendre sur T-SQL, mais en travaillant sur du code pour une transaction (et en basant le code sur des exemples de stackoverflow et d'autres sites), j'ai trouvé un cas où il semble qu'un point-virgule soit requis et s'il est manquant, l'instruction ne semble pas du tout s'exécuter et aucune erreur n'est générée. Cela ne semble être couvert dans aucune des réponses ci-dessus. (Il s'agissait de MS SQL Server 2012.)
Une fois que la transaction a fonctionné comme je le souhaitais, j'ai décidé de faire un essai sur elle, donc s'il y a des erreurs, elle est annulée. Ce n'est qu'après cela que la transaction n'a pas été validée (SSMS le confirme en essayant de fermer la fenêtre avec un joli message vous alertant du fait qu'il y a une transaction non validée.
Donc ça
COMMIT TRANSACTION
en dehors d'un bloc BEGIN TRY / END TRY a bien fonctionné pour valider la transaction, mais à l'intérieur du bloc, il devait être
COMMIT TRANSACTION;
Notez qu'aucune erreur ou avertissement n'est fourni et aucune indication que la transaction n'est toujours pas validée jusqu'à ce que vous tentiez de fermer l'onglet de requête.
Heureusement, cela cause un problème si énorme qu'il est immédiatement évident qu'il y a un problème. Malheureusement, aucune erreur (syntaxe ou autre) n'ayant été signalée, le problème n'était pas immédiatement évident.
Au contraire, ROLLBACK TRANSACTION semble fonctionner aussi bien dans le bloc BEGIN CATCH avec ou sans point-virgule.
Il peut y avoir une certaine logique à cela, mais cela semble arbitraire et Alice-au-Pays des Merveilles.
COMMIT TRANSACTION
accepte un nom de point de transaction / sauvegarde facultatif (qu'il ignorera). Sans point-virgule de fin, COMMIT TRANSACTION
peut manger le symbole suivant s'il est analysé comme identifiant, ce qui peut changer radicalement la sémantique du code. Si cela entraîne une erreur, le CATCH
peut se déclencher sans COMMIT
jamais avoir été exécuté. Inversement, tout en ROLLBACK TRANSACTION
acceptant également un identifiant facultatif comme celui-ci, une erreur d'analyse est susceptible d'entraîner l'annulation de la transaction de toute façon.
Il semble que des points - virgules ne doivent pas être utilisés conjointement avec des opérations de curseur: OPEN
, FETCH
, CLOSE
etDEALLOCATE
. Je viens de perdre quelques heures avec ça. J'ai examiné de près le BOL et j'ai remarqué que [;] n'est pas affiché dans la syntaxe de ces instructions de curseur !!
J'ai donc eu:
OPEN mycursor;
et cela m'a donné l'erreur 16916.
Mais:
OPEN mycursor
travaillé.
Selon les conventions de syntaxe Transact-SQL (Transact-SQL) (MSDN)
Terminateur d'instruction Transact-SQL. Bien que le point-virgule ne soit pas requis pour la plupart des instructions dans cette version de SQL Server, il le sera dans une future version.
(voir aussi le commentaire de @gerryLowry)
Lorsque vous utilisez une instruction DISABLE ou ENABLE TRIGGER dans un lot qui contient d'autres instructions, l'instruction juste avant de se terminer par un point-virgule. Sinon, vous obtiendrez une erreur de syntaxe. J'ai arraché mes cheveux avec celui-ci ... Et après, je suis tombé sur cet article MS Connect à propos de la même chose. Il est fermé car il ne sera pas réparé.
voir ici
Remarque: cela répond à la question telle qu'elle est écrite, mais pas au problème comme indiqué. L'ajouter ici, car les gens le chercheront
Le point-virgule est également utilisé auparavant WITH
dans les instructions CTE récursives:
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
Cette requête va générer un CTE appelé Numbers qui se compose d'entiers [1..10]. Pour ce faire, créez une table avec la valeur 1 uniquement, puis récursive jusqu'à ce que vous atteigniez 10.
Si vous aimez obtenir des erreurs de délai d'attente de commande aléatoires dans SQLServer, laissez le point-virgule à la fin de vos chaînes CommandText.
Je ne sais pas si cela est documenté n'importe où ou s'il s'agit d'un bug, mais cela se produit et je l'ai appris d'une expérience amère.
J'ai des exemples vérifiables et reproductibles utilisant SQLServer 2008.
aka -> En pratique, incluez toujours le terminateur même si vous n'envoyez qu'une seule instruction à la base de données.
Les points-virgules ne fonctionnent pas toujours dans les instructions SELECT composées.
Comparez ces deux versions différentes d'une instruction SELECT composée triviale.
Le code
DECLARE @Test varchar(35);
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.';);););
SELECT @Test Test;
Retour
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near ';'.
Cependant, le code
DECLARE @Test varchar(35)
SELECT @Test=
(SELECT
(SELECT
(SELECT 'Semicolons do not always work fine.')))
SELECT @Test Test
Retour
Test
-----------------------------------
Semicolons do not always work fine.
(1 row(s) affected)