MySQL 9.0 C API 开发人员指南  /  C API 预处理语句接口  /  C API 预处理语句数据结构

6.2 C API 预处理语句数据结构

预处理语句使用多个数据结构

  • 要获得语句句柄,将 MYSQL 连接句柄传递给 mysql_stmt_init(),它将返回指向 MYSQL_STMT 数据结构的指针。此结构用于语句的后续操作。要指定要准备的语句,将 MYSQL_STMT 指针和语句字符串传递给 mysql_stmt_prepare().

  • 要为预处理语句提供输入参数,请设置 MYSQL_BIND 结构并将其传递给 mysql_stmt_bind_param()mysql_stmt_bind_named_param()。要接收输出列值,请设置 MYSQL_BIND 结构并将其传递给 mysql_stmt_bind_result().

    MYSQL_BIND 结构也与 mysql_bind_param() 一起使用,它允许定义应用于发送到服务器的下一个查询的属性。

  • MYSQL_TIME 结构用于双向传输时间数据。

以下讨论详细描述了预处理语句数据类型。有关显示如何使用它们的示例,请参阅 第 6.4.11 节,“mysql_stmt_execute()”第 6.4.12 节,“mysql_stmt_fetch()”.

  • MYSQL_STMT

    此结构是预处理语句的句柄。句柄是通过调用 mysql_stmt_init() 创建的,它将返回指向 MYSQL_STMT 的指针。句柄用于语句的所有后续操作,直到您使用 mysql_stmt_close() 关闭它,此时句柄将变为无效,不再应该使用。

    MYSQL_STMT 结构没有供应用程序使用的成员。应用程序不应尝试复制 MYSQL_STMT 结构。无法保证此类副本可用。

    多个语句句柄可以与单个连接相关联。句柄数量限制取决于可用的系统资源。

  • MYSQL_BIND

    此结构用于语句输入(发送到服务器的数据值)和输出(从服务器返回的结果值)

    • 对于输入,请将 MYSQL_BIND 结构与 mysql_bind_param() 一起使用来定义查询的属性。(在以下讨论中,将所有提及预处理语句的语句参数视为也适用于查询属性。)

    • 对于输出,请将 MYSQL_BIND 结构与 mysql_stmt_bind_result() 一起使用来将缓冲区绑定到结果集列,以便在使用 mysql_stmt_fetch() 获取行时使用。

    要使用 MYSQL_BIND 结构,请将其内容清零以初始化它,然后适当地设置其成员。例如,要声明和初始化三个 MYSQL_BIND 结构的数组,请使用以下代码

    MYSQL_BIND bind[3];
    memset(bind, 0, sizeof(bind));

    MYSQL_BIND 结构包含以下供应用程序使用的成员。对于几个成员,使用方式取决于结构是用于输入还是输出。

    • enum enum_field_types buffer_type

      缓冲区的类型。此成员指示绑定到语句参数或结果集列的 C 语言变量的数据类型。对于输入,buffer_type 指示包含要发送到服务器的值的变量的类型。对于输出,它指示应该将从服务器接收的值存储在其中的变量的类型。有关允许的 buffer_type 值,请参阅 第 6.2.1 节,“C API 预处理语句类型代码”.

    • void *buffer

      指向用于数据传输的缓冲区的指针。这是 C 语言变量的地址。

      对于输入,buffer 是指向存储语句参数数据值的变量的指针。当您调用 mysql_stmt_execute() 时,MySQL 将使用存储在变量中的值来代替语句中相应的参数标记(在语句字符串中使用 ? 指定)。

      对于输出,buffer 是指向要返回结果集列值的变量的指针。当您调用 mysql_stmt_fetch() 时,MySQL 将结果集当前行中的一个列值存储在此变量中。您可以在调用返回后访问该值。

      为了最大限度地减少 MySQL 需要在客户端的 C 语言值和服务器端的 SQL 值之间执行类型转换,请使用类型类似于相应 SQL 值的 C 变量

      • 对于数值数据类型,buffer 应该指向正确数值 C 类型的变量。对于整型变量(可以是 char 用于单字节值或整型用于较大值),您还应该通过设置稍后描述的 is_unsigned 成员来指示该变量是否具有 unsigned 属性。

      • 对于字符(非二进制)和二进制字符串数据类型,buffer 应该指向字符缓冲区。

      • 对于日期和时间数据类型,buffer 应该指向 MYSQL_TIME 结构。

      有关 C 类型和 SQL 类型之间映射的指南以及有关类型转换的说明,请参阅 第 6.2.1 节,“C API 预处理语句类型代码”第 6.2.2 节,“C API 预处理语句类型转换”.

    • unsigned long buffer_length

      *buffer 的实际大小(以字节为单位)。这表示可以存储在缓冲区中的最大数据量。对于字符和二进制 C 数据,buffer_length 值在与 mysql_stmt_bind_param()mysql_stmt_bind_named_param() 一起使用以指定输入值时指定 *buffer 的长度,或者在与 mysql_stmt_bind_result() 一起使用时可以获取到缓冲区的最大输出数据字节数。

    • unsigned long *length

      指向 unsigned long 变量的指针,该变量指示存储在 *buffer 中的实际数据字节数。length 用于字符或二进制 C 数据。

      对于输入参数数据绑定,请设置 *length 以指示存储在 *buffer 中的参数值的实际长度。这由 mysql_stmt_execute() 使用。

      对于输出值绑定,当您调用 mysql_stmt_fetch() 时,MySQL 将设置 *lengthmysql_stmt_fetch() 的返回值决定如何解释长度

      • 如果返回值为 0,则 *length 指示参数值的实际长度。

      • 如果返回值为 MYSQL_DATA_TRUNCATED,则 *length 指示参数值的非截断长度。在这种情况下,*lengthbuffer_length 中较小的一个表示值的实际长度。

      length 对于数值和时间数据类型被忽略,因为 buffer_type 值确定数据值的长度。

      如果必须在获取返回值之前确定其长度,请参阅 第 6.4.12 节,“mysql_stmt_fetch()”,了解一些策略。

    • bool *is_null

      此成员指向一个 bool 变量,如果值是 NULL 则为 true,如果不是 NULL 则为 false。对于输入,请将 *is_null 设置为 true 以指示您正在传递 NULL 值作为语句参数。

      is_null 是指向布尔标量的 指针,而不是布尔标量,以提供指定 NULL 值的灵活性

      • 如果您的数据值始终为 NULL,则在绑定列时使用 MYSQL_TYPE_NULL 作为 buffer_type 值。其他 MYSQL_BIND 成员(包括 is_null)并不重要。

      • 如果您的数据值始终为 NOT NULL,请设置 is_null = (bool*) 0,并为要绑定的变量设置其他成员。

      • 在所有其他情况下,请相应地设置其他成员,并将 is_null 设置为 bool 变量的地址。在执行之间适当地设置该变量的值为 true 或 false,以分别指示相应的数据值是 NULL 还是 NOT NULL

      对于输出,当您获取一行时,MySQL 会根据从语句返回的结果集列值是否为 NULLis_null 指向的值设置为 true 或 false。

    • bool is_unsigned

      此成员适用于数据类型可以为 unsigned 的 C 变量 (char, short int, int, long long int)。如果 buffer 指向的变量是 unsigned,则将 is_unsigned 设置为 true,否则设置为 false。例如,如果您将 signed char 变量绑定到 buffer,请指定 MYSQL_TYPE_TINY 的类型代码,并将 is_unsigned 设置为 false。如果您改为绑定 unsigned char,则类型代码相同,但 is_unsigned 应该为 true。(对于 char,它没有定义是 signed 还是 unsigned,因此最好通过使用 signed charunsigned char 明确说明 signedness。)

      is_unsigned 仅适用于客户端的 C 语言变量。它不指示服务器端对应 SQL 值的 signedness。例如,如果您使用 int 变量为 BIGINT UNSIGNED 列提供值,则 is_unsigned 应为 false,因为 int 是 signed 类型。如果您使用 unsigned int 变量为 BIGINT 列提供值,则 is_unsigned 应为 true,因为 unsigned int 是 unsigned 类型。MySQL 会在两个方向上执行 signed 和 unsigned 值之间的正确转换,尽管如果发生截断会发出警告。

    • bool *error

      对于输出,将此成员设置为指向 bool 变量,以在执行完行获取操作后存储该参数的截断信息。当启用截断报告时,mysql_stmt_fetch() 返回 MYSQL_DATA_TRUNCATED,并且 *error 在发生截断的参数的 MYSQL_BIND 结构中为 true。截断表示符号或有效数字的丢失,或者字符串太长而无法放入列中。默认情况下启用截断报告,但可以通过使用 MYSQL_REPORT_DATA_TRUNCATION 选项调用 mysql_options() 来控制。

  • MYSQL_TIME

    此结构用于直接将 DATETIMEDATETIMETIMESTAMP 数据发送到服务器和从服务器接收。将 buffer 成员设置为指向 MYSQL_TIME 结构,并将 MYSQL_BIND 结构的 buffer_type 成员设置为其中一个时间类型 (MYSQL_TYPE_TIME, MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIMESTAMP)。

    MYSQL_TIME 结构包含下表列出的成员。

    成员 描述
    unsigned int year 年份
    unsigned int month 月份
    unsigned int day 日期
    unsigned int hour 小时
    unsigned int minute 分钟
    unsigned int second
    bool neg 一个布尔标志,指示时间是否为负
    unsigned long second_part 秒的小数部分(以微秒为单位)

    仅使用 MYSQL_TIME 结构中适用于给定时间类型的值的部分。 year, monthday 元素用于 DATEDATETIMETIMESTAMP 值。 hour, minutesecond 元素用于 TIMEDATETIMETIMESTAMP 值。请参阅 第 3.6.4 节,“预处理语句处理日期和时间值”