Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  PREPARE Statement

15.5.1 准备语句

PREPARE stmt_name FROM preparable_stmt

PREPARE 语句将 SQL 语句准备好,并将其命名为 stmt_name,以便后续引用该语句。准备好的语句可以使用 EXECUTE 执行,并使用 DEALLOCATE PREPARE 释放。例如,请参见 第15.5章,“Prepared Statements”

语句名称不区分大小写。preparable_stmt 是字符串字面量或用户变量,包含 SQL 语句的文本。文本必须表示单个语句,而不是多个语句。语句中可以使用 ? 字符作为参数标记符,以指示将要在执行语句时将数据值绑定到查询中。这些字符不应该被包含在引号中,即使你打算将其绑定到字符串值。参数标记符只能在数据值应该出现的地方使用,而不是在 SQL 关键字、标识符等处使用。

如果已经存在具有给定名称的准备语句,它将被隐式释放,然后准备新的语句。如果新的语句包含错误且不能被准备,错误将被返回,并且没有具有给定名称的语句存在。

准备语句的作用域是创建它的会话,这意味着:

  • 准备语句在一个会话中创建后,不可在其他会话中访问。

  • 当会话结束时,无论是正常还是异常,准备语句将不再存在。如果启用自动重连,客户端将不会收到连接丢失的通知。因此,客户端可能想要禁用自动重连。请参见 Automatic Reconnection Control

  • 在存储程序中准备的语句将继续存在,直到程序完成执行,并且可以在后续执行。

  • 在存储程序上下文中准备的语句不能引用存储程序或函数参数或本地变量,因为它们在程序结束时将不可用。解决方案是引用用户定义变量,这些变量具有会话作用域;请参见 第11.4章,“User-Defined Variables”

准备语句中的参数类型在语句首次准备时确定,并且在执行语句时保持不变(除非语句被重新准备,如本节后续部分所述)。参数类型确定规则如下:

  • 参数是二进制算术操作符的操作数,它的数据类型与其他操作数相同。

  • 如果二进制算术操作符的两个操作数都是参数,参数的类型将根据操作符的上下文确定。

  • 如果参数是单目算术操作符的操作数,那么参数的类型由操作符的上下文决定。

  • 如果算术操作符没有确定类型的上下文,那么参与操作的所有参数的派生类型为DOUBLE PRECISION。这可能发生在参数是SELECT语句的顶级节点或是比较操作符的一部分时。

  • 如果参数是字符字符串操作符的操作数,那么该参数的派生类型与其他操作数的聚合类型相同。如果所有操作数都是参数,那么派生类型为VARCHAR,其排序规则由collation_connection的值确定。

  • 如果参数是时间操作符的操作数,那么该参数的类型为DATETIME,如果操作符返回DATETIME,为TIME,如果操作符返回DATE,那么该参数的类型为DATE

  • 如果参数是二元比较操作符的操作数,那么该参数的派生类型与比较操作符的其他操作数相同。

  • 如果参数是三元比较操作符,如BETWEEN,那么该参数的派生类型与其他操作数的聚合类型相同。

  • 如果所有操作数都是参数,那么每个操作数的派生类型为VARCHAR,其排序规则由collation_connection的值确定。

  • 如果参数是输出操作符的操作数,如CASECOALESCEIFIFNULLNULLIF,那么该参数的派生类型与操作符的其他输出操作数相同。

  • 如果任何CASECOALESCEIFIFNULLNULLIF的输出操作数都是参数,那么参数的类型由操作符的上下文决定。

  • 如果参数是CASECOALESCE()IFIFNULL的操作数,并且没有确定类型的上下文,那么每个参数的派生类型都是VARCHAR,并且其排序规则由collation_connection的值确定。

  • 如果参数是CAST()的操作数,那么该参数的类型与指定的CAST()相同。

  • 如果参数是SELECT列表的直接成员,但不是INSERT语句的一部分,那么该参数的派生类型是VARCHAR,并且其排序规则由collation_connection的值确定。

  • 如果参数是SELECT列表的直接成员,但是一部分INSERT语句,那么该参数的派生类型是该参数将被插入的列的类型。

  • 如果参数是UPDATE语句的SET子句或INSERT语句的ON DUPLICATE KEY UPDATE子句的源,那么该参数的派生类型是该参数将被更新的列的类型。

  • 如果参数是函数的参数,那么该参数的派生类型取决于函数的返回类型。

在某些实际类型和派生类型组合中,自动重新准备语句以确保与之前版本的MySQL更好地兼容。重新准备不发生在以下任何情况下:

  • NULL被用作实际参数值。

  • 参数是一个CAST()的操作数。 (实际上,尝试将参数转换为派生类型,如果转换失败,则抛出异常。)

  • 参数是一个字符串。 (在这种情况下,对参数进行隐式转换为派生类型,例如CAST(? AS derived_type)。)

  • 参数的派生类型和实际类型都是INTEGER,并且具有相同的符号。

  • 参数的派生类型是DECIMAL,实际类型是INTEGERDECIMAL

  • 派生类型是DOUBLE,实际类型是任何数字类型。

  • 派生类型和实际类型都是字符串类型。

  • 如果派生类型是时间类型,实际类型也是时间类型。 异常:派生类型是TIME,实际类型不是TIME;派生类型是DATE,实际类型不是DATE

  • 派生类型是时间类型,实际类型是数字类型。

对于上述以外的案例,语句将被重新准备,实际参数类型将被用于代替派生参数类型。

这些规则也适用于在预备语句中引用用户变量。

在预备语句中使用不同数据类型的给定参数或用户变量将导致语句被重新准备。这可能会导致结果不一致,建议在重新执行预备语句时使用相同的数据类型。