531 votes

MySQL : @variable vs. variable. Quelle est la différence ?

Dans une autre question que j'ai postée, quelqu'un m'a dit qu'il y a une différence entre :

@variable

et :

variable

dans MySQL. Il a également mentionné comment MSSQL a une portée de lot et MySQL a une portée de session. Quelqu'un peut-il me donner des précisions à ce sujet ?

1 votes

Je suis familier avec MsSQL et l'idée de poser une telle question ne m'a jamais effleuré. Les réponses fournies ici m'ont éclairé sur quelque chose dont je n'avais aucune idée ! Merci.

651voto

Quassnoi Points 191041

MySQL a un concept de variables définies par l'utilisateur .

Ce sont des variables faiblement typées qui peuvent être initialisées quelque part dans une session et conserver leur valeur jusqu'à la fin de la session.

Ils sont précédés d'un @ signe, comme ceci : @var

Vous pouvez initialiser cette variable avec un SET ou dans une requête :

SET @var = 1

SELECT @var2 := 2

Lorsque vous développez une procédure stockée dans MySQL, vous pouvez passer les paramètres d'entrée et déclarer les variables locales :

DELIMITER //

CREATE PROCEDURE prc_test (var INT)
BEGIN
    DECLARE  var2 INT;
    SET var2 = 1;
    SELECT  var2;
END;
//

DELIMITER ;

Ces variables ne sont pas précédées d'un préfixe.

La différence entre une variable de procédure et une variable définie par l'utilisateur spécifique à la session est qu'une variable de procédure est réinitialisée pour NULL à chaque fois que la procédure est appelée, alors que la variable spécifique à la session ne l'est pas :

CREATE PROCEDURE prc_test ()
BEGIN
    DECLARE var2 INT DEFAULT 1;
    SET var2 = var2 + 1;
    SET @var2 = @var2 + 1;
    SELECT  var2, @var2;
END;

SET @var2 = 1;

CALL prc_test();

var2  @var2
---   ---
2     2

CALL prc_test();

var2  @var2
---   ---
2     3

CALL prc_test();

var2  @var2
---   ---
2     4

Comme vous pouvez le voir, var2 (variable de procédure) est réinitialisée à chaque fois que la procédure est appelée, alors que @var2 (variable spécifique à la session) ne l'est pas.

(En plus des variables définies par l'utilisateur, MySQL également possède certaines "variables système" prédéfinies, qui peuvent être des "variables globales" telles que @@global.port ou des "variables de session" telles que @@session.sql_mode ; ces "variables de session" n'ont aucun rapport avec les variables définies par l'utilisateur spécifiques à la session).

49 votes

Notez également que des variables globales sont disponibles : Voir SELECT @@version; par exemple. C'est également la raison pour laquelle l'utilisation de DELIMITER @@ n'est pas vraiment une bonne idée.

16 votes

Cela fait de nouvelles questions pour les nouveaux venus... y a-t-il une différence entre "var = var" et "var := var" comme dans votre exemple ?

12 votes

Une autre question pour un nouvel arrivant. Quand est-il recommandé d'utiliser @ ou non ?

76voto

molf Points 34978

Dans MySQL, @variable indique un variable définie par l'utilisateur . Vous pouvez définir les vôtres.

SET @a = 'test';
SELECT @a;

En dehors des programmes enregistrés, une variable sans @ est un variable du système que vous ne pouvez pas définir vous-même.

La portée de cette variable est l'ensemble de la session. Cela signifie que tant que votre connexion avec la base de données existe, la variable peut toujours être utilisée.

Ceci est en contraste avec MSSQL, où la variable ne sera disponible que dans le lot actuel de requêtes (procédure stockée, script, ou autre). Elle ne sera pas disponible dans un lot différent dans la même session.

2 votes

À ne pas confondre avec les variables de session, qui ont pour code d'abréviation SET @@a = 'test'; , cf. dev.mysql.com/doc/refman/5.1/fr/set-statement.html

0 votes

@RobM, Ils s'appellent système et non des variables de session.

1 votes

@Pacerier : Est-ce que je lis mal la documentation ? """Pour indiquer explicitement qu'une variable est une variable de session, faites précéder son nom de SESSION, @@session., ou @@."""

11voto

Xybo Points 53

MSSQL exige que les variables à l'intérieur des procédures soient DECLAREd et que les personnes utilisent l'attribut @Variable syntaxe ( DECLARE @TEXT VARCHAR(25) = 'text' ). De plus, MS permet les déclarations dans n'importe quel bloc de la procédure, contrairement à MySQL qui exige toutes les DECLARE en haut.

Bien qu'il soit bon en ligne de commande, je pense que l'utilisation de l'option set = @variable dans les procédures stockées de MySQL est risqué. Il n'y a pas de portée et les variables vivent au-delà des limites de la portée. Ceci est similaire aux variables en JavaScript qui sont déclarées sans l'attribut var qui sont alors l'espace de nom global et créent des collisions et des écrasements inattendus.

J'espère que les bonnes gens de MySQL vont autoriser DECLARE @Variable à différents niveaux de bloc dans une procédure stockée. Remarquez les @ (au panneau). Le site @ Le préfixe du signe permet de séparer les noms de variables des noms de colonnes de tables, car ils sont souvent identiques. Bien sûr, il est toujours possible d'ajouter un préfixe "v" ou "l_", mais l'option @ est un moyen pratique et succinct de faire correspondre le nom de la variable à la colonne dont vous pourriez extraire les données, sans pour autant l'alourdir.

MySQL est un nouveau venu dans le domaine des procédures stockées et ils ont fait du bon travail pour leur première version. Ce sera un plaisir de voir où ils vont aller à partir de là et de voir les aspects côté serveur du langage mûrir.

4voto

Peter Points 43

En principe, j'utilise les UserDefinedVariables (précédées de @) dans les procédures stockées. Cela me facilite la vie, surtout lorsque j'ai besoin de ces variables dans deux ou plusieurs procédures stockées. Lorsque je n'ai besoin d'une variable que dans une seule procédure stockée, j'utilise une variable système (sans le préfixe @).

@Xybo : Je ne comprends pas pourquoi utiliser des @variables dans des StoredProcedures devrait être risqué. Pourriez-vous expliquer "scope" et "boundaries" un peu plus facilement (pour moi qui suis novice) ?

5 votes

Cela viole les principes de base de l'ingénierie logicielle. S'il vous plaît, n'écrivez pas une autre ligne de code avant de savoir exactement ce qu'est la portée, et pourquoi l'utilisation de variables globales est généralement une idée terrible. Lorsque j'ai suivi les cours de programmation 101, si je me souviens bien, l'utilisation d'une variable globale pour à peu près tout se traduisait par un "F" automatique. Il y a des exceptions spéciales, mais en règle générale - ne le faites pas !

0 votes

Pourquoi ? - Les @Variables sont absolument courantes dans tous les livres MySQL.

0 votes

Bien sûr, dans un script "plat" sans appels de fonction, procédures, triggers, etc. et si vous allez juste exécuter ce simple script, ou un ensemble limité de commandes et ensuite terminer la session (détruisant ainsi vos globaux). Dans ce cas, allez-y et utilisez-les si vous voulez. Mais NE les utilisez PAS à l'intérieur d'une fonction ! Si vous tapez simplement "variables globales" ou "portée" sur Google, vous trouverez instantanément un vaste soutien à l'idée qu'elles sont universellement désapprouvées. Voici un point de départ : wiki.c2.com/?GlobalVariablesAreBad ou pour une explication plus générale : fr.wikipedia.org/wiki/Global_variable

0voto

@variable est très utile si l'on appelle procédures stockées à partir d'une application écrite en Java, Python, etc. Il arrive que les valeurs des variables soient créées lors du premier appel et qu'elles soient nécessaires aux fonctions des appels suivants.

Note complémentaire sur PL/SQL (Oracle)

L'avantage est visible dans Oracle PL/SQL où ces variables ont 3 portées différentes :

  • Variable de fonction dont la portée se termine à la sortie de la fonction.
  • Variables du corps du paquet défini au sommet du paquet et en dehors de toutes les fonctions dont la portée est la session et la visibilité est le paquet.
  • Variable du paquet dont la variable est la session et la visibilité est globale.

Mon expérience en PL/SQL

J'ai développé une architecture dans laquelle le code complet est écrit en PL/SQL. Ceux-ci sont appelés à partir d'un middle-ware écrit en Java. Il y a deux types de middle-ware. L'un pour répondre aux appels d'un client qui est également écrit en Java. L'autre pour répondre aux appels provenant d'un navigateur. Le dispositif client est implémenté à 100 % en JavaScript. Un jeu de commandes est utilisé au lieu de HTML et JavaScript pour écrire une application en PL/SQL.

J'ai cherché la même facilité pour porter les codes écrits en PL/SQL vers une autre base de données. La solution la plus proche que j'ai trouvée est Postgres . Mais toutes les variables ont une portée de fonction.

Opinion à l'égard de @ dans MySQL

Je suis heureux de voir qu'au moins cette @ est disponible dans MySQL. Je ne pense pas qu'Oracle construira la même facilité disponible dans PL/SQL pour les procédures stockées de MySQL car cela pourrait affecter les ventes de la base de données Oracle.

1 votes

PLSQL (Oracle) en panne de question. Pourriez-vous vous concentrer davantage sur la question et donner des précisions ? @variable dans le contexte de MS-SQL ou MySQL s'il vous plaît !

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