web-dev-qa-db-ja.com

MySQL:@変数対変数。違うは何ですか?

私が投稿した別の質問では、次のような違いがあることを誰かが教えてくれました。

@variable

そして:

variable

mySQLでは。彼はまた、MSSQLがどのようにバッチスコープを持ち、MySQLがセッションスコープを持つかについても述べました。誰かが私のためにこれについて詳しく述べることができますか?

480
DJTripleThreat

MySQLの概念はユーザー定義変数です。

これらは、セッション内のどこかで初期化され、セッションが終了するまで値を保持する、緩やかに型指定された変数です。

次のように、@記号が先頭に追加されます:@var

この変数は、SETステートメントまたはクエリ内で初期化できます。

SET @var = 1

SELECT @var2 := 2

MySQLでストアドプロシージャを開発すると、入力パラメーターを渡してローカル変数を宣言できます。

DELIMITER //

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

DELIMITER ;

これらの変数には、プレフィックスが付加されません。

プロシージャ変数とセッション固有のユーザー定義変数の違いは、プロシージャ変数はプロシージャが呼び出されるたびにNULLに再初期化されますが、セッション固有の変数はそうではないことです。

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

ご覧のとおり、var2(プロシージャ変数)はプロシージャが呼び出されるたびに再初期化されますが、@var2(セッション固有の変数)は再初期化されません。

(ユーザー定義変数に加えて、MySQLalsoには事前定義済みの「システム変数」があります。これは@@global.portや「session」などの「グローバル変数」 @@session.sql_modeなどの変数」;これらの「セッション変数」は、セッション固有のユーザー定義変数とは無関係です。

608
Quassnoi

MySQLでは、@variableユーザー定義変数 を示します。あなたはあなた自身を定義することができます。

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

@のないvariableは、ストアドプログラムの外では システム変数 です。これは自分で定義することはできません。

この変数の範囲はセッション全体です。つまり、データベースとの接続が確立されていても、変数はまだ使用できるということです。

これはMSSQLとは対照的です。MSSQLでは、変数は現在のクエリのバッチ(ストアドプロシージャ、スクリプトなど)でのみ使用できます。同じセッションの異なるバッチでは利用できません。

69
molf

MSSQLでは、プロシージャ内の変数をDECLAREする必要があり、ユーザーは@Variable構文を使用する必要があります(DECLARE @TEXT VARCHAR(25)= 'text')。また、MSでは、先頭にすべてのDECLAREが必要なmySQLとは異なり、プロシージャ内の任意のブロック内で宣言することができます。

コマンドラインには適していますが、mySQLのストアドプロシージャ内で "set = @variable"を使用するのは危険です。スコープはなく、変数はスコープの境界を越えて存在します。これはJavaScriptの変数が "var"接頭辞なしで宣言されているのと似ています。これはグローバル名前空間であり、予期しない衝突や上書きを引き起こします。

私はmySQLの優秀な人々がストアドプロシージャ内のさまざまなブロックレベルでDECLARE @変数を許可することを願っています。 @(アットマーク)に注意してください。 @記号の接頭辞は、変数とテーブルの列名を区別するのに役立ちます。もちろん、 "v"または "l_"の接頭辞をつけることもできますが、@記号は、変数名をデータを抽出する元の列と一致させるのに便利で簡潔な方法です。

MySQLはストアドプロシージャに不慣れで、彼らは彼らの最初のバージョンのために良い仕事をしました。ここで彼らがそれを形成する場所を見て、そして言語のサーバー側の側面が成熟していくのを見ることは喜びです。

10
Xybo

原則として、私はストアドプロシージャ内でUserDefinedVariables(@を先頭に追加)を使用します。これにより、特にこれらの変数が2つ以上のストアドプロシージャで必要になったときに、作業が楽になります。 1つのストアドプロシージャ内でのみ変数が必要な場合は、システム変数を使用します(先頭に@は付きません)。

@ Xybo:StoredProceduresで@variablesを使用するのが危険な理由はわかりません。 「範囲」と「境界」についてもう少し簡単に説明してください(私にとっては初心者として)。

3
Peter