MySQL:@変数と変数。違いは何ですか? (パート2)
-
06-07-2019 - |
質問
さて、最後に尋ねた質問に基づいて、 Mysqlは次のコードのwhere文をどのように処理しますか:
DELIMITER ;//
DROP PROCEDURE IF EXISTS `test`;//
CREATE PROCEDURE `test`
(
id INT
)
BEGIN
SELECT *
FROM some_table
WHERE id = id;
END;//
この場合、MySQLは何をしますか? where句を
として扱いますかsome_table.id = id
またはそれを次のように扱います
some_table.id = some_table.id
今、私は次のようなことをしています
WHERE id = @id
MySQLにセッション変数が存在することを知らず、文句を言わなかったため、「この列がこの変数に等しい」という明示的な言い方だと思いました。
「duh ..」と言う人もいるかもしれませんが、もちろんcolumn = variableとして扱います。しかし、「変数=列」の場所を簡単に言うことができました。それでは、これをどのように処理しますか?
解決
MySQLの変数命名スキーマは、最初に調べたときに少し奇妙です。通常、MySQLは3種類の変数を区別します。
- システム変数( global または< a href = "http://dev.mysql.com/doc/refman/5.0/en/server-session-variables.html" rel = "noreferrer">セッションスコープ):
@@ varname
- ユーザー定義変数(セッションスコープ):
@varname
- local のストアド変数プログラム:
varname
したがって、前述の名前付けの競合は、保存されたプログラム内でのみ発生します。したがって、最初に明確なパラメーター名を割り当てることにより、これらの名前の競合を避けるようにしてください。 pId
などの p
でパラメーターを事前調整します。 MySQLがあいまいさを検出すると、参照を変数の名前として解釈します(こちらをご覧ください):
[...]ローカル変数名は 列名と同じである。 SQLの場合
SELECT ... INTO
などのステートメント ステートメント、への参照を含む 列と宣言されたローカル変数 現在、同じ名前の MySQL 参照を名前として解釈します 変数の。 [...]
現在という文言は、何らかの形でこの動作が将来のバージョンで変更される可能性があるという印象を与えます。
他のヒント
@は、テーブルの列を参照するのではなく、プロシージャ内の変数であることを示していると確信しています。 id
という名前のテーブル列は1つしかないため、この場合は明確です。結合を行う場合は、接頭辞を付ける必要があります:
select *
from table1, table2
where table1.id = @id
and table2.some_field = table1.id
場所は関係ありません。このクエリのように、変数には常に@プレフィックスが必要です。
select id, @id
from table1
最初のIDは明確なテーブル列table1.idであり、@ idはストアドプロシージャ変数を参照します。