MySQL 5.0+ 支援預存程序,將複雜 SQL 邏輯封裝於資料庫層,C/C++ 僅需呼叫 CALL 語句並處理輸出參數,實現業務邏輯與資料存取分離,大幅降低客戶端代碼複雜度。
-- 1. 建表
CREATE TABLE student (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20),
age TINYINT,
remark VARCHAR(50)
);
-- 2. 插入測試資料
INSERT INTO student VALUES (1, 'zhouys', 90, '');
-- 3. 建立預存程序:依 id 查詢學生資訊
DELIMITER //
CREATE PROCEDURE querystudent(
IN in_id INT,
OUT out_ret INT,
OUT out_name VARCHAR(20),
OUT out_age INT
)
label_a: BEGIN
DECLARE v_name VARCHAR(20);
DECLARE v_age TINYINT;
IF in_id <= 0 THEN
SET out_ret = -1; LEAVE label_a;
END IF;
SELECT name, age INTO v_name, v_age FROM student WHERE id = in_id;
IF v_name IS NULL THEN
SET out_ret = -2; LEAVE label_a;
END IF;
SET out_ret = 0;
SET out_name = v_name;
SET out_age = v_age;
END //
DELIMITER ;
mysql_init(&mysql)mysql_real_connect(&mysql, "localhost", "root", "", "billingdb", 0, NULL, CLIENT_MULTI_STATEMENTS) — 必須啟用 CLIENT_MULTI_STATEMENTS 支援多語句。mysql_real_query(&mysql, "CALL querystudent(1, @ret, @out_name, @out_age)", ...)mysql_query(&mysql, "SELECT @ret, @out_name, @out_age") → mysql_store_result() 取得結果集。mysql_fetch_row() 逐行讀取 → mysql_free_result() → mysql_close()。// 3. 呼叫
strcpy(query, "CALL querystudent(1, @ret, @out_name, @out_age)");
ret = mysql_real_query(&mysql, query, (unsigned int)strlen(query));
// 4. 取得輸出參數
mysql_query(&mysql, "SELECT @ret, @out_name, @out_age");
results = mysql_store_result(&mysql);
// 5. 解析結果
while ((record = mysql_fetch_row(results))) {
printf("[%s]-[%s]-[%s]\n", record[0], record[1], record[2]);
}
mysql_free_result(results);
mysql_close(&mysql);
SELECT @param 二次查詢獲取。SELECT,需循環呼叫 mysql_next_result() 處理每個結果集。mysql_stmt_prepare 綁定 OUT 參數在某些版本會報錯 Error 1414,建議採用上述 CALL + SELECT @var 模式。mysql_set_character_set(&mysql, "utf8") 避免中文亂碼。