In einer anderen Frage, die ich gestellt habe, hat mir jemand gesagt, dass es einen Unterschied gibt zwischen:
@variable
und:
variable
in MySQL. Er erwähnte auch, wie MSSQL einen Batch-Bereich und MySQL einen Sitzungsbereich hat. Kann mir jemand das näher erläutern?
Antworten:
MySQL
hat das Konzept von benutzerdefinierten Variablen .Es handelt sich um lose typisierte Variablen, die möglicherweise irgendwo in einer Sitzung initialisiert werden und ihren Wert bis zum Ende der Sitzung beibehalten.
Ihnen ist ein
@
Schild wie folgt vorangestellt :@var
Sie können diese Variable mit einer
SET
Anweisung oder in einer Abfrage initialisieren :Wenn Sie eine gespeicherte Prozedur in entwickeln
MySQL
, können Sie die Eingabeparameter übergeben und die lokalen Variablen deklarieren:Diesen Variablen werden keine Präfixe vorangestellt.
Der Unterschied zwischen einer Prozedurvariablen und einer sitzungsspezifischen benutzerdefinierten Variablen besteht darin, dass die Prozedurvariable bei
NULL
jedem Aufruf der Prozedur neu initialisiert wird, während die sitzungsspezifische Variable nicht:Wie Sie sehen können, wird
var2
(Prozedurvariable) bei jedem Aufruf der Prozedur neu initialisiert, während dies bei@var2
(sitzungsspezifischer Variable) nicht der Fall ist.(Zusätzlich zu benutzerdefinierten Variablen verfügt MySQL auch über einige vordefinierte "Systemvariablen", bei denen es sich um "globale Variablen"
@@global.port
oder "Sitzungsvariablen" handeln kann@@session.sql_mode
. Diese "Sitzungsvariablen" stehen in keinem Zusammenhang mit sitzungsspezifischen benutzerdefinierten Variablen Variablen.)quelle
SELECT @@version;
zum Beispiel. Dies ist auch ein Grund, warum die VerwendungDELIMITER @@
keine wirklich gute Idee ist.@
vs nicht zu verwenden?:=
und=
, und zwar, dass er:=
überall als Operator für die Zuweisung von Variablen=
funktioniert , während er nur inSET
Anweisungen so funktioniert und überall ein Vergleichsoperator ist. SoSELECT @var = 1 + 1;
wird @var unverändert lassen und einen boolean zurückgeben (1 oder 0 auf dem aktuellen Wert von @var abhängig), währendSELECT @var := 1 + 1;
wird @var bis 2 ändern, und zurück 2.Gibt in MySQL
@variable
eine benutzerdefinierte Variable an . Sie können Ihre eigenen definieren.Außerhalb gespeicherter Programme ist a
variable
ohne@
eine Systemvariable , die Sie nicht selbst definieren können.Der Umfang dieser Variablen ist die gesamte Sitzung. Das heißt, während Ihre Verbindung mit der Datenbank besteht, kann die Variable weiterhin verwendet werden.
Dies steht im Gegensatz zu MSSQL, wo die Variable nur im aktuellen Stapel von Abfragen (gespeicherte Prozedur, Skript oder auf andere Weise) verfügbar ist. Es wird in derselben Sitzung nicht in einem anderen Stapel verfügbar sein.
quelle
SET @@a = 'test';
, vgl. dev.mysql.com/doc/refman/5.1/en/set-statement.html@@
. Zum Beispielset@@my_var=1
,set@@session.my_var=1
undset session my_var=1
arbeitet nicht , weil ichmy_var
nicht um eine Systemvariable, während wir tun könnenset@@big_tables=1
,set@@session.big_tables=1
undset session big_tables=1
dabig_tables
ist eine Systemvariable.var2
ist eine Variable ohne@
Präfix, aber keine Systemvariable: Es ist eine Prozedurvariable. Dies ist zulässig, da es sich um eine gespeicherte Prozedur (auch als gespeichertes Programm bezeichnet) handelt. Außerhalb gespeicherter Prozeduren ist eine Variable ohne@
eine Systemvariable.MSSQL erfordert, dass Variablen in Prozeduren DECLAREd sind und die Benutzer die @ Variable-Syntax verwenden (DECLARE @TEXT VARCHAR (25) = 'text'). Außerdem erlaubt MS Deklarationen innerhalb eines beliebigen Blocks in der Prozedur, im Gegensatz zu mySQL, für das alle DECLAREs oben erforderlich sind.
Obwohl ich gut in der Befehlszeile bin, halte ich die Verwendung von "set = @variable" in gespeicherten Prozeduren in mySQL für riskant. Es gibt keinen Bereich und Variablen leben über Bereichsgrenzen hinweg. Dies ähnelt Variablen, die in JavaScript ohne das Präfix "var" deklariert werden. Dies ist dann der globale Namespace und führt zu unerwarteten Kollisionen und Überschreibungen.
Ich hoffe, dass die guten Leute bei mySQL DECLARE @Variable auf verschiedenen Blockebenen innerhalb einer gespeicherten Prozedur zulassen. Beachten Sie das @ (am Zeichen). Das @ -Zeichenpräfix hilft dabei, Variablennamen von Tabellenspaltennamen zu trennen, da diese häufig identisch sind. Natürlich kann man immer ein "v" - oder "l_" -Präfix hinzufügen, aber das @ -Zeichen ist eine praktische und prägnante Möglichkeit, den Variablennamen mit der Spalte abzugleichen, aus der Sie möglicherweise die Daten extrahieren, ohne sie zu beschädigen.
MySQL ist neu in gespeicherten Prozeduren und sie haben für ihre erste Version gute Arbeit geleistet. Es wird ein Vergnügen sein zu sehen, wo sie hier Gestalt annehmen und die serverseitigen Aspekte der Sprache reifen zu sehen.
quelle
Im Prinzip verwende ich UserDefinedVariables (mit @ vorangestellt) in gespeicherten Prozeduren. Dies erleichtert das Leben, insbesondere wenn ich diese Variablen in zwei oder mehr gespeicherten Prozeduren benötige. Nur wenn ich eine Variable nur innerhalb EINER gespeicherten Prozedur benötige, verwende ich eine Systemvariable (ohne vorangestelltes @).
@Xybo: Ich verstehe nicht, warum die Verwendung von @variables in StoredProcedures riskant sein sollte. Könnten Sie bitte "Umfang" und "Grenzen" etwas einfacher erklären (für mich als Neuling)?
quelle
@@GLOBAL
Variablen noch "globaler" und heimtückischer. Sie kreuzen Sitzungen!@variables
haben "Sitzungsumfang", so dass sie zumindest auf diese Weise beschränkt bleiben. In jeder normalen Sprache wird dies jedoch als "globaler" Bereich bezeichnet (wenn sie Funktionen usw. kreuzen). Das MySQL-Konzept von "global" sollte vielleicht als "universell" bezeichnet werden, da es über die Grenzen des Prozesses hinausgeht, in dem es ausgeführt wird. Ein "globaler" Benutzer kann dies normalerweise nicht in einer Standardsprache tun, da Prozesse keinen gemeinsamen Speicherplatz nutzen. Dies ist auf die anhaltende (vs volatile) Tendenz von SQL zurückzuführen.