12.9.3. 信息函数

  • BENCHMARK(count,expr)

BENCHMARK() 函数重复count 次执行表达式 expr 。 它可以被用于计算  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(),并解释与服务器机器负荷程度有关的结果。

·         CHARSET(str)

返回字符串自变量的字符集。

mysql> SELECT CHARSET('abc');
        -> 'latin1'
mysql> SELECT CHARSET(CONVERT('abc' USING utf8));
        -> 'utf8'
mysql> SELECT CHARSET(USER());
        -> 'utf8'

·         COERCIBILITY(str)

返回字符串自变量的整序可压缩性值。

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或一个表达式

 

 

下方值得优先级较高。

  • COLLATION(str)

返回惠字符串参数的排序方式。

mysql> SELECT COLLATION('abc');

        -> 'latin1_swedish_ci'

mysql> SELECT COLLATION(_utf8'abc');

        -> 'utf8_general_ci'

  • CONNECTION_ID()

返回对于连接的连接ID (线程ID)。每个连接都有各自的唯一 ID

mysql> SELECT CONNECTION_ID();

        -> 23786

  • CURRENT_USER, CURRENT_USER()

返回当前话路被验证的用户名和主机名组合。这个值符合确定你的存取权限的MySQL 账户。在被指定SQL SECURITY DEFINER特征的存储程序内, CURRENT_USER() 返回程序的创建者。

 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()值得空用户名部分 )。这种情况发生的一个原因是 One 在向 davida的授权列表中没有足够的账户。 

 CURRENT_USER() 返回的字符串使用 utf8字符集。

  • DATABASE()

返回使用 utf8 字符集的默认(当前)数据库名。在存储程序里,默认数据库是同该程序向关联的数据库,但并不一定与调用语境的默认数据库相同。 

mysql> SELECT DATABASE();

        -> 'test'

若没有默认数据库, DATABASE()返回 NULL

  • FOUND_ROWS()

A 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();

第二个 SELECT返回一个数字,指示了在没有LIMIT子句的情况下,第一个SELECT返回了多少行 (若上述的 SELECT语句不包括 SQL_CALC_FOUND_ROWS 选项,则使用LIMIT 和不使用时,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() 在当你希望限制一个问询返回的行数时很有用,同时还能不需要再次运行问询而确定全部结果集合中的行数。一个例子就是提供页式显示的Web脚本,该显示包含显示搜索结果其它部分的页的连接。使用FOUND_ROWS() 使你确定剩下的结果需要多少其它的页。 

SQL_CALC_FOUND_ROWS FOUND_ROWS() 的应用对于UNION 问询比对于简单SELECT 语句更为复杂,原因是在UNION 中,LIMIT 可能会出现在多个位置。它可能适用于UNION中的个人 SELECT语句,或是总体上  UNION 结果的全程。

SQL_CALC_FOUND_ROWS对于 UNION的意向是它应该不需要全程LIMIT而返回应返回的行数。SQL_CALC_FOUND_ROWS UNION 一同使用的条件是:

    •  SQL_CALC_FOUND_ROWS 关键词必须出现在UNION的第一个 SELECT中。
    •  FOUND_ROWS()的值只有在使用 UNION ALL时才是精确的。若使用不带ALLUNION,则会发生两次删除, 而  FOUND_ROWS() 的指只需近似的。
    • 假若UNION 中没有出现  LIMIT ,则SQL_CALC_FOUND_ROWS 被忽略,返回临时表中的创建的用来处理UNION的行数。
  • LAST_INSERT_ID() LAST_INSERT_ID(expr)

自动返回最后一个INSERT UPDATE 问询为 AUTO_INCREMENT列设置的第一个 发生的值。

mysql> SELECT LAST_INSERT_ID();

        -> 195

产生的ID 每次连接后保存在服务器中。这意味着函数向一个给定客户端返回的值是该客户端产生对影响AUTO_INCREMENT列的最新语句第一个 AUTO_INCREMENT值的。这个值不能被其它客户端影响,即使它们产生它们自己的 AUTO_INCREMENT值。这个行为保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁或处理。

假如你使用一个非“magic”值来更新某一行的AUTO_INCREMENT 列,则LAST_INSERT_ID() 的值不会变化(换言之, 一个不是 NULL也不是 0的值)

重点: 假如你使用单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)

虽然第二个问询将3 个新行插入 t, 对这些行的第一行产生的 ID 2, 这也是 LAST_INSERT_ID()返回的值。

假如你使用 INSERT IGNORE而记录被忽略,则AUTO_INCREMENT 计数器不会增量,而 LAST_INSERT_ID() 返回0, 这反映出没有插入任何记录。

若给出作为到LAST_INSERT_ID()的参数expr ,则参数的值被函数返回,并作为被LAST_INSERT_ID()返回的下一个值而被记忆。这可用于模拟序列:

    • 创建一个表,用来控制顺序计数器并使其初始化:

o                     mysql> CREATE TABLE sequence (id INT NOT NULL);

o                     mysql> INSERT INTO sequence VALUES (0);

    • 使用该表产生这样的序列数 :

o                     mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);

o                     mysql> SELECT LAST_INSERT_ID();

UPDATE 语句会增加顺序计数器并引发向LAST_INSERT_ID()  的下一次调用,用来返回升级后的值。 SELECT 语句会检索这个值。  mysql_insert_id() C API函数也可用于获取这个值。 见25.2.3.36节,“mysql_insert_id()”.

你可以不用调用LAST_INSERT_ID()而产生序列,但这样使用这个函数的效用在于 ID值被保存在服务器中,作为自动产生的值。它适用于多个用户,原因是多个用户均可使用 UPDATE语句并用SELECT语句(mysql_insert_id()),得到他们自己的序列值,而不会影响其它产生他们自己的序列值的客户端或被其它产生他们自己的序列值的客户端所影响。

注意, mysql_insert_id() 仅会在INSERT UPDATE语句后面被升级, 因此你不能在执行了其它诸如SELECT SET 这样的SQL语句后使用 C API 函数来找回 LAST_INSERT_ID(expr) 对应的值。

  • ROW_COUNT()

ROW_COUNT()返回被前面语句升级的、插入的或删除的行数。 这个行数和 mysql 客户端显示的行数及 mysql_affected_rows() C API 函数返回的值相同。

mysql> INSERT INTO t VALUES(1),(2),(3);

问询完成, 表中有3 (0.00)

记录: 3 重复: 0 警告: 0

 

mysql> SELECT ROW_COUNT();

+-------------+

| ROW_COUNT() |

+-------------+

|           3 |

+-------------+

表中有1 (0.00 )

 

mysql> DELETE FROM t WHERE i IN(1,2);

问询完成, 找到2 (0.00 )

 

mysql> SELECT ROW_COUNT();

+-------------+

| ROW_COUNT() |

+-------------+

|           2 |

+-------------+

表中有1 (0.00 )

  • SCHEMA()

这个函数和 DATABASE()具有相同的意义。

  • SESSION_USER()

SESSION_USER() USER()具有相同的意义。

  • SYSTEM_USER()

SYSTEM_USER() USER()具有相同的意义。

  • USER()

返回当前 MySQL用户名和机主名/

mysql> SELECT USER();

        -> 'davida@localhost'

这个值指示了你指定的连接服务器时的用户名,及你所连接的客户主机。这个值可以和CURRENT_USER() 的值不同。

你可以这样提取用户名部分:

mysql> SELECT SUBSTRING_INDEX(USER(),'@',1);

        -> 'davida'

由于 USER() 返回一个utf8 字符集中的值,你也应确保'@' 字符串文字在该字符集中得到解释:

mysql> SELECT SUBSTRING_INDEX(USER(),_utf8'@',1);

        -> 'davida'

  • VERSION()

返回指示 MySQL 服务器版本的字符串。这个字符串使用 utf8 字符集。

mysql> SELECT VERSION();

        -> '5.1.2-alpha-standard'

注意,假如你的版本字符串以-log结尾,这说明登录已被激活。 

关注编程学问公众号