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_param() 使用 MYSQL_BIND 結構來定義查詢的屬性。(在以下討論中,將任何提及預處理語句的語句參數都視為也適用於查詢屬性。)

    • 對於輸出,請搭配 mysql_stmt_bind_result() 使用 MYSQL_BIND 結構,將緩衝區繫結至結果集資料行,以用於使用 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,以表示對應的資料值是否分別為 NULLNOT NULL

      對於輸出,當您擷取一列時,MySQL 會根據從語句傳回的結果集欄位值是否為 NULL,將 is_null 指向的值設定為 true 或 false。

    • bool is_unsigned

      此成員適用於具有可以是 unsigned 的資料類型(charshort intintlong long int)的 C 變數。如果 buffer 指向的變數為 unsigned,則將 is_unsigned 設定為 true,否則設定為 false。例如,如果您將 signed char 變數綁定到 buffer,請指定 MYSQL_TYPE_TINY 的類型代碼,並將 is_unsigned 設定為 false。如果您改為綁定 unsigned char,類型代碼相同,但 is_unsigned 應為 true。(對於 char,未定義它是帶正負號還是不帶正負號,因此最好使用 signed charunsigned char 來明確指出帶正負號與否。)

      is_unsigned 僅適用於用戶端上的 C 語言變數。它並未指出伺服器端對應 SQL 值的帶正負號與否。例如,如果您使用 int 變數為 BIGINT UNSIGNED 欄位提供值,則 is_unsigned 應為 false,因為 int 是帶正負號的類型。如果您使用 unsigned int 變數為 BIGINT 欄位提供值,則 is_unsigned 應為 true,因為 unsigned int 是不帶正負號的類型。MySQL 會在兩個方向上執行帶正負號和不帶正負號值之間的正確轉換,但如果發生截斷,則會發出警告。

    • bool *error

      對於輸出,將此成員設定為指向一個 bool 變數,以便在擷取列操作後將參數的截斷資訊儲存在該處。當啟用截斷報告時,mysql_stmt_fetch() 會傳回 MYSQL_DATA_TRUNCATED,且在發生截斷的參數的 MYSQL_BIND 結構中,*error 為 true。截斷表示遺失正負號或有效位數,或字串太長而無法放入欄位中。預設情況下會啟用截斷報告,但可以透過使用 MYSQL_REPORT_DATA_TRUNCATION 選項呼叫 mysql_options() 來控制。

  • MYSQL_TIME

    此結構用於直接與伺服器傳送和接收 DATETIMEDATETIMETIMESTAMP 資料。將 buffer 成員設定為指向 MYSQL_TIME 結構,並將 MYSQL_BIND 結構的 buffer_type 成員設定為其中一個時間類型(MYSQL_TYPE_TIMEMYSQL_TYPE_DATEMYSQL_TYPE_DATETIMEMYSQL_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 結構的那些部分。yearmonthday 元素用於 DATEDATETIMETIMESTAMP 值。hourminutesecond 元素用於 TIMEDATETIMETIMESTAMP 值。請參閱 第 3.6.4 節,「預先準備語句的日期和時間值處理」