6.2.2 C API 准备语句类型转换

准备好的语句在客户端使用 C 语言变量在客户端和服务器之间传输数据,这些变量对应于服务器端的 SQL 值。如果客户端的 C 变量类型与服务器端相应的 SQL 值类型不匹配,则 MySQL 会在两个方向上执行隐式类型转换。

MySQL 知道服务器端 SQL 值的类型代码。结构中的buffer_typeMYSQL_BIND指示在客户端保存值的 C 变量的类型代码。这两个代码一起告诉 MySQL 必须执行什么转换,如果有的话。这里有些例子:

  • 如果使用MYSQL_TYPE_LONGwith int变量将整数值传递给要存储到 FLOAT列中的服务器,MySQL 会在存储之前将该值转换为浮点格式。

  • 如果您获取一个 SQLMEDIUMINT 列值,但指定一个buffer_typeMYSQL_TYPE_LONGLONG并使用类型的 C 变量long long int作为目标缓冲区,MySQL 会将 MEDIUMINT存储的值(需要少于 8 个字节)转换为 long long int(一个 8 字节变量)。

  • 如果将值为 255 的数字列提取到 char[4]字符数组中并指定 buffer_type值为 MYSQL_TYPE_STRING,则数组中的结果值为 4 字节字符串'255\0'

  • MySQL 将DECIMAL值作为原始服务器端值的字符串表示形式返回,这就是对应的 C 类型为 char[]. 例如, 12.345作为 返回给客户端 '12.345'。如果指定 MYSQL_TYPE_NEWDECIMAL字符串缓冲区并将其绑定到MYSQL_BIND结构, mysql_stmt_fetch()则将缓冲区中的值作为字符串存储而不进行转换。相反,如果您指定数字变量和类型代码, mysql_stmt_fetch()则将字符串格式DECIMAL 值转换为数字形式。

  • 对于MYSQL_TYPE_BIT类型代码, BIT值被返回到一个字符串缓冲区中,这就是为什么对应的 C 类型是 char[]. 该值表示需要在客户端进行解释的位串。要将值作为更易于处理的类型返回,您可以使用以下任一类型的表达式将值强制转换为整数:

    SELECT bit_col + 0 FROM t
    SELECT CAST(bit_col AS UNSIGNED) FROM t

    要检索该值,请绑定一个足够大的整数变量来保存该值并指定适当的对应整数类型代码。

在将变量绑定到MYSQL_BIND 用于获取列值的结构之前,您可以检查结果集中每一列的类型代码。如果您想确定最好使用哪些变量类型来避免类型转换,这可能是可取的。要获取类型代码,请 mysql_stmt_result_metadata() 在执行带有 的语句后 调用mysql_stmt_execute()。元数据提供对结果集类型代码的访问,如第 6.4.23 节“mysql_stmt_result_metadata()”第 5.2 节“C API 基本数据结构”中所述。

要确定从服务器返回的结果集中的输出字符串值是否包含二进制或非二进制数据,请检查charsetnr结果集元数据的值是否为 63(请参阅第 5.2 节,“C API 基本数据结构”)。如果是,则字符集为binary,表示二进制数据而非非二进制数据。这使您能够区分BINARYfrom CHARVARBINARYfrom VARCHAR以及 BLOB类型与 TEXT类型。

如果导致设置列元数据结构的max_length成员 MYSQL_FIELD(通过调用 mysql_stmt_attr_set()),请注意max_length结果集的值表示结果值的最长字符串表示形式的长度,而不是二进制表示形式的长度。也就是说,max_length不一定对应于使用用于准备语句的二进制协议获取值所需的缓冲区大小。根据获取值的变量类型选择缓冲区的大小。例如, TINYINT包含值 -128 的列的值可能max_length为 4。但是任何TINYINTvalue 只需要 1 个字节用于存储,因此您可以提供一个 signed char变量来存储该值并设置is_unsigned为指示值已签名。

检测到准备好的语句引用的表或视图的元数据更改,并在下次执行语句时自动重新准备语句。有关详细信息,请参阅 准备好的语句和存储程序的缓存