BENCHMARK()
関数は、式
expr
を
count
の回数だけ繰り返し実行します。MySQL
がどれだけ素早く式を処理するかをこれで計ることも可能です。この結果値は常に
0
になります。この使用目的は、クエリの実行時間を報告する
mysql クライアント内からです :
mysql> SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE('hello','goodbye')) |
+----------------------------------------------+
| 0 |
+----------------------------------------------+
1 row in set (4.74 sec)
報告された時間は、クライアント側の経過時間であり、サーバ側の
CPU
時間ではありません。BENCHMARK()
を複数回実行し、サーバ
コンピュータにどれだけ負担がかかっているかについて、結果を解釈することをお薦めします。
ストリング引数の文字セットを戻します。
mysql>SELECT CHARSET('abc');
-> 'latin1' mysql>SELECT CHARSET(CONVERT('abc' USING utf8));
-> 'utf8' mysql>SELECT CHARSET(USER());
-> 'utf8'
ストリング引数の照合型変換値を戻します。
mysql>SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
-> 0 mysql>SELECT COERCIBILITY(USER());
-> 3 mysql>SELECT COERCIBILITY('abc');
-> 4
戻り値は下の表にあるような意味を持ちます。値が低いほど、優先順位は高くなります。
型変換属性 | 意味 | 例 |
0 |
明示的な照合 |
COLLATE 句との値 |
1 |
照合なし | 異なる照合とのストリングの結合 |
2 |
暗示的な照合 | カラム値、ストアド ルーチン パラメータ、またはローカル変数 |
3 |
系統定数 |
USER() 戻り値 |
4 |
型変換可能 | リテラル ストリング |
5 |
無視可能 |
NULL または NULL
から引き出された式 |
ストリング引数の照合を戻します。
mysql>SELECT COLLATION('abc');
-> 'latin1_swedish_ci' mysql>SELECT COLLATION(_utf8'abc');
-> 'utf8_general_ci'
接続のコネクション ID ( スレッド ID ) を戻します。すべての接続は、接続しているクライアントのセットの中で一意となる ID を持っています。
mysql> SELECT CONNECTION_ID();
-> 23786
現在のクライアントの認証にサーバが使用した
MySQL
アカウントの、ユーザ名とホスト名のコンビネーションを戻します。このアカウントは、開発者のアクセス特権を確認します。SQL
SECURITY DEFINER
特徴で定義されたストアド
ルーチン内で、CURRENT_USER()
はルーチンのクリエイターを戻します。戻り値は
utf8
文字セット内のストリングです。
CURRENT_USER()
の値は、USER()
の値によって異なる場合があります。
mysql>SELECT USER();
-> 'davida@localhost' mysql>SELECT * FROM mysql.user;
ERROR 1044: Access denied for user ''@'localhost' to database 'mysql' mysql>SELECT CURRENT_USER();
-> '@localhost'
この例は、クライアントが
davida
のユーザ名を指定 (
USER()
の値で示されるように )
した場合でも、サーバは匿名のユーザ
アカウント ( CURRENT_USER()
値の空のユーザ名部分に見られるように )
を使用してクライアントを認証するということを示しています。これが起こるひとつの原因として、davida
の権限テーブルにアカウント
リストがないことが挙げられます。
デフォルト ( 現行の )
データベース名を、utf8
文字セット内のストリングとして戻します。デフォルトのデータベースがない場合は、DATABASE()
は NULL
を戻します。ストアド
ルーチン内で、デフォルトのデータベースはルーチンが関連するデータベースですが、コーリング
コンテキストのデフォルトのデータベースと同様である必要はありません。
mysql> SELECT DATABASE();
-> 'test'
デフォルトのデータベースがない場合は、DATABASE()
は NULL
を戻します。
SELECT
文は、サーバがクライアントに戻す行の数を制限するために、LIMIT
句を含んでいる場合があります。場合によっては、LIMIT
なしでステートメントが返す行の数を知ることが望ましいですが、ステートメントを再度実行しないでください。この行のカウントを得るには、SELECT
文に SQL_CALC_FOUND_ROWS
オプションを含み、その後に
FOUND_ROWS()
を実行します :
mysql>SELECT SQL_CALC_FOUND_ROWS * FROM
->tbl_name
WHERE id > 100 LIMIT 10;
mysql>SELECT FOUND_ROWS();
2 番目の SELECT
は、最初の
SELECT
が返した、LIMIT
句なしで書かれた行数を示す数字を戻します。
最も最近の SELECT
文に
SQL_CALC_FOUND_ROWS
オプションがない場合、FOUND_ROWS()
はその文によって戻された結果セットの行の数を戻します。
FOUND_ROWS()
によって得られる行数は一過性のもので、SELECT
SQL_CALC_FOUND_ROWS
文に続くステートメントを過ぎると取得できなくなるようになっています。この値を後で参照する必要がある場合は保存してください
:
mysql>SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
mysql>SET @rows = FOUND_ROWS();
SELECT SQL_CALC_FOUND_ROWS
を使用している場合、MySQL
は完全な結果セットにいくつ行があるか計算する必要があります。しかし、結果セットをクライアントに送る必要がないため、LIMIT
なしでクエリを再度実行するより速く行えます。
SQL_CALC_FOUND_ROWS
および
FOUND_ROWS()
は、クエリが戻す行の数を制限する際に便利ですが、クエリを再度実行することなく完全な結果セットの行の数を決定するためにも利用できます。検索結果の他のセクションを表示するページへのリンクを含む、ページ表示を提示するウェブ
スクリプトが例に挙げられます。FOUND_ROWS()
を使用することで、残りの結果がさらに何ページを必要とするかを決定することができます。
SQL_CALC_FOUND_ROWS
および
FOUND_ROWS()
の使用は、UNION
の複数箇所で
LIMIT
が起こる場合があるため、簡単な
SELECT
文よりも、UNION
文に対してのほうがより複雑になります。これは、UNION
の個々の SELECT
文に用いられるか、または
UNION
結果全体にグローバルに適用されます。
UNION
に対する
SQL_CALC_FOUND_ROWS
の目的は、グローバルな LIMIT
なしで返される行数を戻すことです。UNION
との SQL_CALC_FOUND_ROWS
の使用の条件は以下 :
SQL_CALC_FOUND_ROWS
キーワードが、UNION
の最初の SELECT
に表示されている。
UNION ALL
が使用されている場合のみ、FOUND_ROWS()
の値は正確。ALL
なしで
UNION
が使用される場合は、複製が除去され、FOUND_ROWS()
の値は近似のみになる。
UNION
で LIMIT
が提示されない場合、SQL_CALC_FOUND_ROWS
は無視され、UNION
を処理するために作成された一時テーブルの行の数を戻す。
LAST_INSERT_ID()
,
LAST_INSERT_ID(
expr
)
MySQL 5.1.12
以降では、LAST_INSERT_ID()
(
引数なし ) は、最も最近に実行された
INSERT
文の結果として
AUTO_INCREMENT
カラムに正常に
インサートされた、自動的に生成された最初の値を戻します。LAST_INSERT_ID()
の値は、正常にインサートされた行がない場合は、未変更のままになります。
例えば、AUTO_INCREMENT
値を生成する行をインサートした後は、次のようにして値を得ることができます
:
mysql> SELECT LAST_INSERT_ID();
-> 195
MySQL 5.1.11
以前では、LAST_INSERT_ID()
(
引数なし )
は、行が正常にインサート、または更新された場合、自動低に生成された最初の値を戻します。つまり、戻された値は、テーブルに正常にインサートされなかった値である可能性があります。正常にインサートされた行がなければ、LAST_INSERT_ID()
は 0 を戻します。
LAST_INSERT_ID()
の値は、INSERT
または
UPDATE
文のすべての行が正常である場合、全バージョンにわたって一貫するでしょう。
実行中のステートメントが、LAST_INSERT_ID()
の値に影響をおよぼすことはありません。ひとつのステートメントで
AUTO_INCREMENT
値を生成し、その後、独自の
AUTO_INCREMENT
カラムで行をテーブルにインサートする複数行の
INSERT
文で、LAST_INSERT_ID()
を照会すると仮定します。LAST_INSERT_ID()
の値は 2
番目のステートメントに安定したまま残ります。2
番目以降の行でのその値は、以前の行の挿入に影響されません。(
しかし、LAST_INSERT_ID()
と
LAST_INSERT_ID(
への参照を混ぜると、その効果は未定義になります
) 。
expr
)
以前のステートメントがエラーを戻した場合、LAST_INSERT_ID()
は未定義になります。トランザクション
テーブルでは、ステートメントがエラーによってロールバックされる場合、LAST_INSERT_ID()
は未定義のまま残されます。手動の
ROLLBACK
では、LAST_INSERT_ID()
の値はトランザクションの前に復元されず、ROLLBACK
時点と同じまま残ります。
ストアド ルーチン (
プロシージャまたは関数 )
もしくはトリガのボディ内で、LAST_INSERT_ID()
の値は、これらの種類のオブジェクトの外で実行されたステートメントと同様に変化します。後に続くステートメントに参照される
LAST_INSERT_ID()
の値に基づくストアド
ルーチンもしくはトリガの効果は、ルーチンの種類によって異なります
:
ストアド プロシージャが
LAST_INSERT_ID()
の値を変えるステートメントを実行する場合、変更された値はプロシージャ呼び出しに従うステートメントによって参照されます。
値を変更するストアド ファンクションやトリガでは、値は関数やトリガが終了した時に復元され、続くステートメントは変更された値を参照しません。
生成された ID
は、接続ベースで
サーバ内で保持されます。つまり、関数によって指定のクライアントに戻された値は、そのクライアントによって
AUTO_INCREMENT
カラムに影響を及ぼす最も最近のステートメントのために生成された、最初の
AUTO_INCREMENT
値です。この値は、他のクライアントが独自の
AUTO_INCREMENT
値を生成した場合でも、他のクライアントによって影響を受けることはありません。この動作は、各クライアントが他のクライアントの動向を気にせず、ロックやトランザクションなしで、独自の
ID を呼び出せるようにします。
行の AUTO_INCREMENT
カラムを 非
「magic」 値 ( NULL
でも
0
でもない値 )
に設定する場合、LAST_INSERT_ID()
の値は変更されません。
重要点 : 単一の
INSERT
文を使用して複数の行をインサートする場合、LAST_INSERT_ID()
は、最初の
インサートされた行のみに対して生成された値を戻します。これは、他のサーバに対して同じ
INSERT
文を簡単に再現できるようにするためです。
例 :
mysql>USE test;
Database changed mysql>CREATE TABLE t (
->id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
->name VARCHAR(10) NOT NULL
->);
Query OK, 0 rows affected (0.09 sec) mysql>INSERT INTO t VALUES (NULL, 'Bob');
Query OK, 1 row affected (0.01 sec) mysql>SELECT * FROM t;
+----+------+ | id | name | +----+------+ | 1 | Bob | +----+------+ 1 row in set (0.01 sec) mysql>SELECT LAST_INSERT_ID();
+------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ 1 row in set (0.00 sec) mysql>INSERT INTO t VALUES
->(NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM t; +----+------+ | id | name | +----+------+ | 1 | Bob | | 2 | Mary | | 3 | Jane | | 4 | Lisa | +----+------+ 4 rows in set (0.01 sec) mysql>SELECT LAST_INSERT_ID();
+------------------+ | LAST_INSERT_ID() | +------------------+ | 2 | +------------------+ 1 row in set (0.00 sec)
2 番目の INSERT
文が 3
つの新しい行を t
にインサートしても、これらの行の 1
番目に生成された ID は 2
であり、次の SELECT
文に対して
LAST_INSERT_ID()
が返す値も同じです。
INSERT IGNORE
を使用して行を無視する場合は、AUTO_INCREMENT
カウンタは増分されず、行がインサートされなかったことを反映して、LAST_INSERT_ID()
は 0
を戻します。
expr
が
LAST_INSERT_ID()
への引数として与えられる場合、その引数の値は関数によって戻され、LAST_INSERT_ID()
によって戻される次の値として記憶されます。これによってシークエンスのシミュレーションをすることも可能です
:
テーブルを作成してシークエンス カウンタを保留にし、初期化 :
mysql>CREATE TABLE sequence (id INT NOT NULL);
mysql>INSERT INTO sequence VALUES (0);
テーブルを使用して、次のようにシークエンス番号を生成 :
mysql>UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql>SELECT LAST_INSERT_ID();
UPDATE
文はシークエンス
カウンタを増分し、LAST_INSERT_ID()
への次の呼び出しが更新された値を戻すようにします。SELECT
文はその値を引き出します。mysql_insert_id()
C API
関数は、値の入手に使用することもできます。詳細は
項23.2.3.37. 「mysql_insert_id()
」
を参照してください。
LAST_INSERT_ID()
を呼び出さずにシークエンスを生成することはできますが、このように関数を使用することの利点は、ID
値が自動的に生成された最後の値として保持されることです。独自のシークエンス値を生成する他のクライアントと互いに影響しあうことなく、複数のクライアントが
UPDATE
文を発行し、UPDATE
文 ( または
mysql_insert_id()
)
でそれぞれのシークエンス値を取得することができるため、マルチユーザでも安全です。
mysql_insert_id()
は
INSERT
および
UPDATE
文の後にのみ更新され、SELECT
もしくは SET
のような他の SQL
文を実行した後に、C API 関数を使用して
LAST_INSERT_ID(
の値を引き出すことはできないのでご注意ください。
expr
)
ROW_COUNT()
は、先行するステートメントによって更新、インサート、または削除された行の数を戻します。これは
mysql
クライアントが表示する行のカウントおよび、mysql_affected_rows()
C API 関数からの値と同じです。
mysql>INSERT INTO t VALUES(1),(2),(3);
Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql>SELECT ROW_COUNT();
+-------------+ | ROW_COUNT() | +-------------+ | 3 | +-------------+ 1 row in set (0.00 sec) mysql>DELETE FROM t WHERE i IN(1,2);
Query OK, 2 rows affected (0.00 sec) mysql>SELECT ROW_COUNT();
+-------------+ | ROW_COUNT() | +-------------+ | 2 | +-------------+ 1 row in set (0.00 sec)
この関数は DATABASE()
のシノニムです。
SESSION_USER()
は
USER()
のシノニムです。
SYSTEM_USER()
は
USER()
のシノニムです。
現行の MySQL
ユーザ名とホスト名を、utf8
文字セット内のストリングとして戻します。
mysql> SELECT USER();
-> 'davida@localhost'
その値はサーバへの接続時に指定したユーザ名と、接続したホストからのクライアントを示します。値は
CURRENT_USER()
によって異なる場合があります。
次のように、ユーザ名の部分だけを摘出することができます :
mysql> SELECT SUBSTRING_INDEX(USER(),'@',1);
-> 'davida'
MySQL
サーバのバージョンを示すストリングを戻します。そのストリングは、utf8
文字セットを使用します。
mysql> SELECT VERSION();
-> '5.1.15-beta-standard'
-log
で終わるバージョン
ストリングは、ロギングが有効になっていることを表しています。