表 14.20 信息函数
| Name | Description |
|---|---|
BENCHMARK() |
重复执行一个表达式 |
CHARSET() |
返回参数的字符集 |
COERCIBILITY() |
返回字符串参数的协调性值 |
COLLATION() |
返回字符串参数的排序规则 |
CONNECTION_ID() |
返回连接 ID(线程 ID) |
CURRENT_ROLE() |
返回当前活动角色 |
CURRENT_USER(), CURRENT_USER |
认证用户名称和主机名称 |
DATABASE() |
返回默认(当前)数据库名称 |
FOUND_ROWS() |
对于带有 LIMIT 子句的 SELECT,返回没有 LIMIT 子句时的行数 |
ICU_VERSION() |
ICU 库版本 |
LAST_INSERT_ID() |
最后插入的 AUTOINCREMENT 列的值 |
ROLES_GRAPHML() |
返回表示内存角色子图的 GraphML 文档 |
ROW_COUNT() |
更新的行数 |
SCHEMA() |
DATABASE() 的同义词 |
SESSION_USER() |
USER() 的同义词 |
SYSTEM_USER() |
USER() 的同义词 |
USER() |
客户端提供的用户名和主机名 |
VERSION() |
返回 MySQL 服务器版本字符串 |
-
The
BENCHMARK()函数重复执行表达式exprcount次。它可以用来测量 MySQL 处理表达式的速度。结果值为0,或为不适当的参数(例如 NULL 或负数重复计数)返回 NULL。其预期用途是在 mysql 客户端中,该客户端报告查询执行时间:
mysql> SELECT BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye')); +---------------------------------------------------+ | BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye')) | +---------------------------------------------------+ | 0 | +---------------------------------------------------+ 1 row in set (4.74 sec)报告的时间是客户端端的经过时间,而不是服务器端的 CPU 时间。建议多次执行
BENCHMARK(),并根据服务器机器的负载情况解释结果。BENCHMARK()旨在测量标量表达式的运行时性能,这对使用它和解释结果有重要的影响:-
只能使用标量表达式。虽然表达式可以是一个子查询,但它必须返回单个列和最多一行。例如,
BENCHMARK(10, (SELECT * FROM t))如果表t有多于一列或多于一行则失败。 -
执行
SELECT语句exprN次与执行SELECT BENCHMARK(在开销方面有所不同。两者具有非常不同的执行配置文件,您不应该期望它们花费相同的时间。前者涉及解析器、优化器、表锁定和运行时评估N,expr)N次每个。后者仅涉及运行时评估N次,而其他组件仅一次。已经分配的内存结构将被重用,并且运行时优化,如聚合函数的结果缓存,可能会改变结果。因此,使用BENCHMARK()测量运行组件的性能,给予该组件更多的权重,并删除了网络、解析器、优化器等引入的“噪音”。
-
-
返回字符串参数的字符集,或者如果参数为
NULL则返回NULL。mysql> SELECT CHARSET('abc'); -> 'utf8mb3' mysql> SELECT CHARSET(CONVERT('abc' USING latin1)); -> 'latin1' mysql> SELECT CHARSET(USER()); -> 'utf8mb3' -
返回字符串参数的协调性值。
mysql> SELECT COERCIBILITY('abc' COLLATE utf8mb4_swedish_ci); -> 0 mysql> SELECT COERCIBILITY(USER()); -> 3 mysql> SELECT COERCIBILITY('abc'); -> 4 mysql> SELECT COERCIBILITY(1000); -> 5返回值的含义如下表所示。较低的值具有较高的优先级。
Coercibility Meaning Example 0显式排序 带 COLLATE子句的值1无排序 具有不同排序的字符串连接 2隐式排序 列值、存储过程参数或局部变量 3系统常量 USER()返回值4可强制 文字字符串 5数字 数字或时间值 6可忽略 NULL或从NULL派生的表达式有关更多信息,请参阅 第 12.8.4 节,“表达式中的排序协调性”。
-
返回字符串参数的排序。
mysql> SELECT COLLATION('abc'); -> 'utf8mb4_0900_ai_ci' mysql> SELECT COLLATION(_utf8mb4'abc'); -> 'utf8mb4_0900_ai_ci' mysql> SELECT COLLATION(_latin1'abc'); -> 'latin1_swedish_ci' -
返回连接 ID(线程 ID),该 ID 在当前连接的客户端集中是唯一的。
由
CONNECTION_ID()返回的值与 Information SchemaPROCESSLIST表的ID列、SHOW PROCESSLIST输出的Id列和 Performance Schemathreads表的PROCESSLIST_ID列相同。mysql> SELECT CONNECTION_ID(); -> 23786Warning更改会话值的
pseudo_thread_id系统变量将更改CONNECTION_ID()函数返回的值。 -
返回一个
utf8mb3字符串,包含当前会话的活动角色,逗号分隔,或者如果没有则返回NONE。该值反映了sql_quote_show_create系统变量的设置。假设账户被授予角色如下:
GRANT 'r1', 'r2' TO 'u1'@'localhost'; SET DEFAULT ROLE ALL TO 'u1'@'localhost';在
u1的会话中,初始CURRENT_ROLE()值命名默认账户角色。使用SET ROLE更改该值:mysql> SELECT CURRENT_ROLE(); +-------------------+ | CURRENT_ROLE() | +-------------------+ | `r1`@`%`,`r2`@`%` | +-------------------+ mysql> SET ROLE 'r1'; SELECT CURRENT_ROLE(); +----------------+ | CURRENT_ROLE() | +----------------+ | `r1`@`%` | +----------------+ -
返回当前客户端使用的 MySQL 帐户的用户名和主机名组合,该帐户确定您的访问权限。返回值是一个
utf8mb3字符集的字符串。值
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帐户。在存储程序或视图中,
CURRENT_USER()返回定义对象的用户帐户(如其DEFINER值所示),除非定义了SQL SECURITY INVOKER特征。在后一种情况下,CURRENT_USER()返回对象的调用者。触发器和事件没有定义
SQL SECURITY特征的选项,因此对于这些对象,CURRENT_USER()返回定义对象的用户帐户。要返回调用者,请使用USER()或SESSION_USER()。以下语句支持使用
CURRENT_USER()函数来代替受影响的用户或定义者的名称(和主机);在这种情况下,CURRENT_USER()将在需要时扩展:有关
CURRENT_USER()扩展对复制的影响,请参阅 第 19.5.1.8 节,“复制 CURRENT_USER()”。该函数可以用作
VARCHAR或TEXT列的默认值,如下面的CREATE TABLE语句所示:CREATE TABLE t (c VARCHAR(288) DEFAULT (CURRENT_USER())); -
返回当前(默认)数据库名称作为字符串,以
utf8mb3字符集表示。如果没有默认数据库,DATABASE()返回NULL。在存储过程中,默认数据库是该过程关联的数据库,而不是调用上下文中的默认数据库。mysql> SELECT DATABASE(); -> 'test'如果没有默认数据库,
DATABASE()返回NULL。 -
Note
查询修饰符
SQL_CALC_FOUND_ROWS和伴随的FOUND_ROWS()函数已弃用;预计它们将在未来版本的 MySQL 中被删除。执行查询时使用LIMIT,然后执行第二个查询,使用COUNT(*)且不使用LIMIT,以确定是否有其他行。例如, instead of 这些查询:SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10; SELECT FOUND_ROWS();使用这些查询 instead:
SELECT * FROM tbl_name WHERE id > 100 LIMIT 10; SELECT COUNT(*) FROM tbl_name WHERE id > 100;COUNT(*)受某些优化的影响。SQL_CALC_FOUND_ROWS会禁用某些优化。一个
SELECT语句可能包括一个LIMIT子句,以限制服务器返回给客户端的行数。在某些情况下,需要知道语句没有LIMIT时将返回多少行,但不需要重新运行语句。要获取该行计数,包括SQL_CALC_FOUND_ROWS选项在SELECT语句中,然后调用FOUND_ROWS():mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name -> WHERE id > 100 LIMIT 10; mysql> SELECT FOUND_ROWS();第二个
SELECT返回一个数字,指示第一个SELECT如果没有LIMIT子句将返回多少行。在最近一个成功的
SELECT语句中没有SQL_CALC_FOUND_ROWS选项的情况下,FOUND_ROWS()返回结果集中的行数。如果语句包括LIMIT子句,FOUND_ROWS()返回限制的行数。例如,FOUND_ROWS()返回 10 或 60,分别对应语句包括LIMIT 10或LIMIT 50, 10。通过
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语句更复杂,因为LIMIT可能出现在UNION中的多个地方。它可能应用于单个SELECT语句中,也可以应用于整个UNION结果。使用
SQL_CALC_FOUND_ROWS的意图是,它应该返回没有全局LIMIT的行计数。使用SQL_CALC_FOUND_ROWS与UNION的条件是:-
只有在使用
UNION ALL时,FOUND_ROWS()的值才是精确的。如果使用UNION而不带ALL,则会发生重复删除,FOUND_ROWS()的值只是近似的。 -
如果
UNION中没有LIMIT,则SQL_CALC_FOUND_ROWS将被忽略,并返回用于处理UNION的临时表中的行数。
除了这里描述的情况外,
FOUND_ROWS()的行为是未定义的(例如,在SELECT语句失败时的值)。ImportantFOUND_ROWS()不可靠地使用基于语句的复制。这函数自动使用基于行的复制。 -
用于支持正则表达式操作的 International Components for Unicode (ICU) 库的版本(见 第 14.8.2 节,“正则表达式”)。这个函数主要用于测试用例。
-
LAST_INSERT_ID(),LAST_INSERT_ID(expr)不带参数时,
LAST_INSERT_ID()返回一个BIGINT UNSIGNED(64 位)值,表示最近执行的INSERT语句中成功插入的第一个自动生成的值。如果没有行被成功插入,则LAST_INSERT_ID()的值保持不变。带参数时,
LAST_INSERT_ID()返回一个无符号整数,或者如果参数为NULL则返回NULL。例如,在插入生成自动增长值的行后,可以这样获取该值:
mysql> SELECT LAST_INSERT_ID(); -> 195当前执行的语句不影响
LAST_INSERT_ID()的值。假设您使用一个语句生成了一个AUTO_INCREMENT值,然后在多行INSERT语句中引用LAST_INSERT_ID(),该语句将行插入到具有其自己的AUTO_INCREMENT列的表中。LAST_INSERT_ID()的值在第二个语句中保持稳定;其值对于第二行和后续行不受早期行插入的影响。(您应该注意,如果您混合引用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()的值,那么随后的语句将看到改变后的值。 -
对于存储函数和触发器,改变
LAST_INSERT_ID()的值,当函数或触发器结束时,值将恢复,后续语句将不看到改变后的值。
生成的ID在服务器上以每个连接基础维护。这意味着函数返回给客户端的值是最近一个语句生成的
AUTO_INCREMENT值由该客户端。该值不能被其他客户端影响,即使它们生成自己的AUTO_INCREMENT值。这种行为确保每个客户端可以检索自己的ID,而不需要锁定或事务。如果您将
AUTO_INCREMENT列的行设置为非“magic”值(即不是NULL也不是0),LAST_INSERT_ID()的值将不变。Important如果您使用单个
INSERT语句插入多行,LAST_INSERT_ID()将返回第一个插入行生成的值仅。这是为了使得可以轻松地在其他服务器上重复相同的INSERT语句。例如:
mysql> USE test; mysql> CREATE TABLE t ( id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, name VARCHAR(10) NOT NULL ); mysql> INSERT INTO t VALUES (NULL, 'Bob'); mysql> SELECT * FROM t; +----+------+ | id | name | +----+------+ | 1 | Bob | +----+------+ mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ mysql> INSERT INTO t VALUES (NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa'); mysql> SELECT * FROM t; +----+------+ | id | name | +----+------+ | 1 | Bob | | 2 | Mary | | 3 | Jane | | 4 | Lisa | +----+------+ mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 2 | +------------------+尽管第二个
INSERT语句将三个新行插入到t中,但生成的ID为2,这是LAST_INSERT_ID()返回的值,用于后续的SELECT语句。如果您使用
INSERT IGNORE并且该行被忽略,则LAST_INSERT_ID()保持不变,从当前值(或如果连接尚未执行成功的INSERT则返回 0),对于非事务表,AUTO_INCREMENT计数器不会递增。对于InnoDB表,如果innodb_autoinc_lock_mode设置为1或2,则AUTO_INCREMENT计数器将递增,如下面的示例所示:mysql> USE test; mysql> SELECT @@innodb_autoinc_lock_mode; +----------------------------+ | @@innodb_autoinc_lock_mode | +----------------------------+ | 1 | +----------------------------+ mysql> CREATE TABLE `t` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `val` INT(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=InnoDB; # Insert two rows mysql> INSERT INTO t (val) VALUES (1),(2); # With auto_increment_offset=1, the inserted rows # result in an AUTO_INCREMENT value of 3 mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `val` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci # LAST_INSERT_ID() returns the first automatically generated # value that is successfully inserted for the AUTO_INCREMENT column mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ # The attempted insertion of duplicate rows fail but errors are ignored mysql> INSERT IGNORE INTO t (val) VALUES (1),(2); Query OK, 0 rows affected (0.00 sec) Records: 2 Duplicates: 2 Warnings: 0 # With innodb_autoinc_lock_mode=1, the AUTO_INCREMENT counter # is incremented for the ignored rows mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `val` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci # The LAST_INSERT_ID is unchanged because the previous insert was unsuccessful mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+有关更多信息,请参阅 第 17.6.1.6 节,“AUTO_INCREMENT 处理 in InnoDB”。
如果
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 函数也可以用来获取该值。请参阅 mysql_insert_id()。
您可以生成序列而不调用
LAST_INSERT_ID(),但使用该函数的实用性在于 ID 值在服务器中维护为最后一个自动生成的值。这是多用户安全的,因为多个客户端可以发出UPDATE语句并获取自己的序列值,以SELECT语句(或mysql_insert_id()),而不影响或被其他客户端生成序列值所影响。请注意,
mysql_insert_id()只在INSERT和UPDATE语句后更新,因此您不能使用 C API 函数来检索LAST_INSERT_ID(的值在执行其他 SQL 语句后,如expr)SELECT或SET。 -
-
返回一个包含 GraphML 文档的
utf8mb3字符串,表示内存角色子图。需要ROLE_ADMIN权限(或已弃用的SUPER权限)以查看<graphml>元素中的内容。否则,结果将显示一个空元素:mysql> SELECT ROLES_GRAPHML(); +---------------------------------------------------+ | ROLES_GRAPHML() | +---------------------------------------------------+ | <?xml version="1.0" encoding="UTF-8"?><graphml /> | +---------------------------------------------------+ -
ROW_COUNT()返回一个值,如下所示:-
DDL 语句:0。这适用于语句,如
CREATE TABLE或DROP TABLE。 -
DML 语句(除
SELECT外):受影响的行数。这适用于语句,如UPDATE、INSERT或DELETE(如前所述),现在也适用于语句,如ALTER TABLE和LOAD DATA。 -
SELECT:-1 如果语句返回结果集,或者如果不返回结果集,则为受影响的行数。例如,对于SELECT * FROM t1,ROW_COUNT()返回 -1。对于SELECT * FROM t1 INTO OUTFILE ',file_name'ROW_COUNT()返回写入文件的行数。 -
SIGNAL语句:0。
对于
UPDATE语句,默认情况下,受影响的行数是实际更改的行数。如果您在连接到 mysqld 时指定了CLIENT_FOUND_ROWS标志到mysql_real_connect(),则受影响的行数是匹配WHERE子句的行数。对于
REPLACE语句,受影响的行数是 2,因为在这种情况下,一个新行替换了一个旧行。对于
INSERT ... ON DUPLICATE KEY UPDATE语句,每行的受影响的行数是 1 如果该行被插入为新行,2 如果现有行被更新,0 如果现有行被设置为其当前值。如果您指定了CLIENT_FOUND_ROWS标志,则受影响的行数是 1(不是 0),如果现有行被设置为其当前值。该
ROW_COUNT()值类似于mysql_affected_rows()C API 函数和 mysql 客户端在语句执行后显示的行计数。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)ImportantROW_COUNT()不可靠地使用基于语句的复制。这函数自动使用基于行的复制。 -
-
该函数是
DATABASE()的同义词。 -
SESSION_USER()是USER()的同义词。像
USER()一样,该函数可以用于VARCHAR或TEXT列的默认值,如下所示的CREATE TABLE语句:CREATE TABLE t (c VARCHAR(288) DEFAULT (SESSION_USER())); -
SYSTEM_USER()是USER()的同义词。Note该
SYSTEM_USER()函数与SYSTEM_USER权限不同。前者返回当前 MySQL 账户名称。后者区分系统用户和常规用户账户类别(见 第 8.2.11 节,“账户类别”)。像
USER()一样,该函数可以用于VARCHAR或TEXT列的默认值,如下所示的CREATE TABLE语句:CREATE TABLE t (c VARCHAR(288) DEFAULT (SYSTEM_USER())); -
返回当前 MySQL 用户名和主机名作为一个字符串,以
utf8mb3字符集表示。mysql> SELECT USER(); -> 'davida@localhost'该值表示您在连接到服务器时指定的用户名和客户端主机,从中连接的客户端主机。该值可能与
CURRENT_USER()的值不同。该函数可以用于
VARCHAR或TEXT列的默认值,如下所示的CREATE TABLE语句:CREATE TABLE t (c VARCHAR(288) DEFAULT (USER())); -
返回一个字符串,指示 MySQL 服务器版本。该字符串使用
utf8mb3字符集。该值可能还有版本号以外的后缀。见 第 7.1.8 节,“服务器系统变量” 中的version系统变量的描述。该函数对于基于语句的复制是不安全的。如果您在
binlog_format设置为STATEMENT时使用该函数,将记录警告。mysql> SELECT VERSION(); -> '8.3.0-standard'