27.7.8.2 C API 准备的语句类型转换
准备好的语句使用 Client 端的 C 语言变量在 Client 端和服务器之间传输数据,这些变量对应于服务器端的 SQL 值。如果 Client 端的 C 变量类型与服务器端的对应 SQL 值类型不匹配,则 MySQL 会在两个方向上执行隐式类型转换。
MySQL 在服务器端知道 SQL 值的类型代码。 MYSQL_BIND
结构中的buffer_type
值 table 示在 Client 端保存该值的 C 变量的类型代码。这两个代码一起告诉 MySQL 必须执行什么转换。这里有些例子:
-
如果将
MYSQL_TYPE_LONG
与int
变量一起使用,以将整数值传递到要存储在FLOAT列中的服务器,则 MySQL 在存储该值之前会将其转换为浮点格式。 -
如果获取 SQL MEDIUMINT列值,但将
buffer_type
值指定为MYSQL_TYPE_LONGLONG
并使用long long int
类型的 C 变量作为目标缓冲区,则 MySQL 会将MEDIUMINT值(需要少于 8 个字节)存储为long long int
(8 -byte 变量)。 -
如果将值 255 的数字列提取到
char[4]
字符数组中,并将buffer_type
值指定为MYSQL_TYPE_STRING
,则数组中的结果值为 4 字节字符串'255\0'
。 -
MySQL 返回DECIMAL值作为原始服务器端值的字符串 table 示形式,这就是为什么相应的 C 类型为
char[]
的原因。例如,12.345
作为'12.345'
返回给 Client 端。如果指定MYSQL_TYPE_NEWDECIMAL
并将字符串缓冲区绑定到MYSQL_BIND
结构,则mysql_stmt_fetch()会将值作为字符串存储在缓冲区中,而无需进行转换。如果改为指定数字变量并键入代码,则mysql_stmt_fetch()会将字符串格式DECIMAL值转换为数字形式。 -
对于
MYSQL_TYPE_BIT
类型代码,将BIT值返回到字符串缓冲区,这就是为什么相应的 C 类型为char[]
的原因。该值 table 示需要在 Client 端进行解释的位字符串。要将值返回为更易于处理的类型,可以使用以下两种 table 达式之一将值强制转换为整数:
SELECT bit_col + 0 FROM t
SELECT CAST(bit_col AS UNSIGNED) FROM t
要检索该值,请绑定足够大的整数变量以容纳该值,并指定适当的相应整数类型代码。
在将变量绑定到将用于获取列值的MYSQL_BIND
结构之前,可以检查结果集每一列的类型代码。如果您想确定哪种变量类型最适合用于避免类型转换,则可能需要这样做。要获取类型代码,请在使用mysql_stmt_execute()执行准备好的语句后调用mysql_stmt_result_metadata()。元数据提供对第 27.7.10.23 节,“ mysql_stmt_result_metadata()”和第 27.7.4 节“ C API 数据结构”中所述的结果集类型代码的访问。
要确定从服务器返回的结果集中的输出字符串值是包含二进制数据还是非二进制数据,请检查结果集元数据的charsetnr
值是否为 63(请参见第 27.7.4 节“ C API 数据结构”)。如果是这样,则字符集是binary
,它 table 示二进制而不是非二进制数据。这使您能够区分BINARY和CHAR,VARBINARY和VARCHAR以及BLOB和TEXT类型。
如果导致设置了MYSQL_FIELD
列元数据结构的max_length
成员(通过调用mysql_stmt_attr_set()),请注意结果集的max_length
值指示结果值的最长字符串 table 示形式的长度,而不是二进制值的长度 table 示。也就是说,max_length
不一定对应于使用用于预准备语句的二进制协议来获取值所需的缓冲区大小。根据要获取值的变量的类型来选择缓冲区的大小。例如,包含值-128 的TINYINT
列的max_length
值可能为 4.但是任何TINYINT
值的二进制 table 示形式只需要 1 个字节即可存储,因此您可以提供signed char
变量来存储值并设置is_unsigned
table 示值已签名。
检测到已准备好的语句所引用的 table 或视图的元数据更改,并在下一次执行该语句时导致该语句的自动重新准备。有关更多信息,请参见第 8.10.4 节“准备好的语句和存储程序的缓存”。