C中Mysql的基本api接口

    • 一、初始化
      • 參數
      • 返回值
    • 二、鏈接服務器
    • 三、執行SQL語句
      • 注意事項
    • 四、獲取結果集
      • 4.1mysql_affected_rows和mysql_num_rows
      • 4.2mysql_store_result與mysql_free_result
      • 注意事項
      • 注意事項
        • 整體的工作流程
      • 4.3mysql_use_result()
      • 4.4mysql_field_count()
    • 五、關閉MySQL
      • 使用和區別
    • 六、錯誤處理
      • mysql_errno()` 和 `mysql_error()

一、初始化

創建MYSQL* 對象,使用mysql_init函數

MYSQL * mysql;
mysql_init(mysql);

參數

  • mysql:指向一個 MYSQL 結構的指針。通常傳遞 NULL,系統將自動為您分配和初始化一個新的 MYSQL 對象。

返回值

  • 成功:返回一個指向 MYSQL 結構的指針。
  • 失敗:返回 NULL

二、鏈接服務器

使用函數mysql_real_connect();

MYSQL *mysql_real_connect(MYSQL *mysql,           // mysql_init() 函數的返回值const char *host,       // mysql服務器的主機地址, 寫IP地址即可// localhost, null -> 代表本地連接const char *user,       // 連接mysql服務器的用戶名, 默認: root const char *passwd,     // 連接mysql服務器用戶對應的密碼, root用戶的密碼const char *db,         // 要使用的數據庫的名字unsigned int port,      // 連接的mysql服務器監聽的端口// 如果==0, 使用mysql的默認端口3306, !=0, 使用指定的這個端口const char *unix_socket,// 本地套接字, 通常在 Windows 上使用命名管道,而在 Unix/Linux 系統上使用 Unix 套接字。如果不使用這類連接方式,此參數應設為 NULL。unsigned long client_flag); //連接時使用的特定客戶端標志 通常指定為0
)

返回值:

  • 成功:返回一個指向 MYSQL 結構的指針(通常是傳入的那個指針)。
  • 失敗:返回 NULL,并且可以通過 mysql_error 函數來獲取錯誤信息。

三、執行SQL語句

// 執行一個sql語句, 添刪查改的sql語句都可以
int mysql_query(MYSQL *mysql, const char *query);
參數:- mysql: mysql_real_connect() 的返回值- query: 一個可以執行的sql語句, 結尾的位置不需要加 ;
返回值: - 如果查詢成功,返回0。如果是查詢, 結果集在mysql 對象中- 如果出現錯誤,返回非0值。 

注意事項

  1. 資源管理:使用 mysql_query 后,如果查詢是 SELECT 類型的,你通常需要調用 mysql_store_resultmysql_use_result 來處理返回的數據。記得在不需要結果集時使用 mysql_free_result 來釋放內存。
  2. 錯誤處理:在生產環境中,每次調用 mysql_query 后都應檢查返回值,并適當處理錯誤。這樣可以避免程序在錯誤狀態下繼續執行,導致更復雜的問題。
  3. 安全性:避免將未經驗證的用戶輸入直接用于 SQL 語句,以防止 SQL 注入攻擊。考慮使用預處理語句和參數化查詢來提高安全性。

這些基本的使用方式和注意事項可以幫助你有效地使用 mysql_query 來執行數據庫操作。

值得注意的是在 MySQL 中,SQL 語句的關鍵字(如 SELECT, INSERT, UPDATE, DELETE 等)通常是不區分大小寫的,這意味著 “select” 和 “SELECT” 在 MySQL 解釋器看來是相同的。然而,數據庫名稱、表名、列名的大小寫敏感性則取決于操作系統的文件系統和 MySQL 的配置。在 Unix、Linux 系統中,它們默認是大小寫敏感的,而在 Windows 系統中默認是不敏感的。

mysql_query 實質上是在客戶端和 MySQL 服務器之間進行網絡通信的一個接口。在使用 TCP/IP 協議的情況下,客戶端通過網絡向服務器發送請求,并接收服務器的響應。這個過程涉及到網絡數據的發送和接收,是基于客戶端-服務器模型的典型應用。

要注意的是標準 SQL 查詢:如果你的查詢是簡單的文本,不包含二進制數據,且不需要在 SQL 語句中嵌入 null 字符,使用 mysql_query 就足夠了。

而當數據中有二進制數據就需要使用mysql_real_query

int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length);
  • 靈活性:可以執行包含 null 字符的查詢,因為它要求用戶明確提供查詢的長度。
  • 手動指定長度:用戶必須指定查詢字符串的長度,這允許函數處理二進制數據或包含 null 字符的數據。
  • 適用場景:非常適合執行包含 BLOB 類型數據的 SQL 語句。

四、獲取結果集

4.1mysql_affected_rows和mysql_num_rows

uint64_t mysql_affected_rows(MYSQL *mysql)

mysql_affected_rows() 可能是 在使用 mysql_real_query() 或 mysql_query() 執行語句后立即調用。它返回 上一個更改、刪除或插入的行數 語句(如果是 UPDATE、DELETE 或 INSERT)。對于 SELECT 語mysql_affected_rows() 有效 像 mysql_num_rows()。

對于 UPDATE 語句, 默認情況下,affected-rows 值是實際的行數 改變。如果在以下情況下指定 mysql_real_connect() 的標志 連接到 mysqld,受影響的行 value 是“找到”的行數;那是 與子句匹配。CLIENT_FOUND_ROWSWHERE

對于 REPLACE 語句, 如果新行替換了舊行,則 affected-rows 值為 2, 因為在這種情況下,在重復項之后插入了一行 已刪除。

uint64_t mysql_num_rows(MYSQL_RES *result)

返回結果集中的行數。

4.2mysql_store_result與mysql_free_result

MYSQL_RES *mysql_store_result(MYSQL *mysql);
參數說明
mysql: 指向 MYSQL 結構的指針,該結構體應已通過 mysql_real_connect 函數建立了與 MySQL 服務器的連接,并已成功執行了一個查詢(如通過 mysql_query)。
返回值
成功: 返回一個指向 MYSQL_RES 結構的指針,這個結構包含了從服務器返回的所有結果數據。
失敗 或 查詢沒有產生結果集(例如執行的是 UPDATE 或 DELETE 語句): 返回 NULL。
如何將行和列的數據從結果集中取出, 需要使用其他函數

注:mysql_store_result 函數只會返回與最近一次通過 mysql_query (或其他發送 SQL 語句的函數)執行的查詢相關的結果。它不會存儲或回溯到之前的查詢結果,而是專注于最后執行的查詢。

注意事項

  1. 內存管理:使用 mysql_store_result 后,必須在不再需要結果集時調用 mysql_free_result 來釋放內存。
  2. 性能考量:由于 mysql_store_result 會將所有結果數據存儲在客戶端內存中,對于返回大量數據的查詢,這可能會消耗大量內存和網絡資源。如果處理大型數據集,可能需要考慮使用 mysql_use_result,該函數允許逐行檢索數據,從而減少內存占用。
  3. 錯誤處理:始終檢查 mysql_store_result 的返回值,并使用 mysql_error 函數來診斷錯誤。

通過 mysql_store_result,你可以方便地在客戶端處理來自 MySQL 服務器的數據,但務必注意資源管理和錯誤處理,以確保應用程序的穩定性和效率。

void mysql_free_result(MYSQL_RES *result);
參數說明
result: 指向 MYSQL_RES 結構的指針,該結構包含了之前查詢的結果集。

mysql_free_result 函數是 MySQL C API 中用來釋放由 mysql_store_resultmysql_use_result 函數分配的結果集內存的函數。這是清理和資源管理的重要一步,確保在查詢處理完成后不會造成內存泄漏。

當使用 mysql_store_resultmysql_use_result 從 MySQL 服務器獲取查詢結果后,相關的數據會被存儲在 MYSQL_RES 結構中。這個結構占用一定的內存空間,當數據處理完畢后,應該使用 mysql_free_result 來釋放這些內存。如果不這樣做,每次查詢后未釋放的內存會累積,最終可能導致內存不足或程序崩潰。

實際使用

#include <mysql.h>
#include <iostream>int main() {MYSQL *conn;MYSQL_RES *res;MYSQL_ROW row;conn = mysql_init(NULL);if (!conn) {std::cerr << "MySQL initialization failed." << std::endl;return 1;}if (!mysql_real_connect(conn, "localhost", "user", "password", "database", 0, NULL, 0)) {std::cerr << "Failed to connect to database: " << mysql_error(conn) << std::endl;mysql_close(conn);return 1;}if (mysql_query(conn, "SELECT id, name FROM users")) {std::cerr << "Query failed: " << mysql_error(conn) << std::endl;mysql_close(conn);return 1;}res = mysql_store_result(conn);if (!res) {std::cerr << "Failed to retrieve result set: " << mysql_error(conn) << std::endl;mysql_close(conn);return 1;}while ((row = mysql_fetch_row(res))) {std::cout << "ID: " << row[0] << ", Name: " << row[1] << std::endl;}// After processing the results, free the memory.mysql_free_result(res);mysql_close(conn);return 0;
}

注意事項

  1. 只釋放一次:確保對每個 MYSQL_RES 結構只調用一次 mysql_free_result。重復釋放可能會導致未定義行為或程序崩潰。
  2. 適時釋放:盡可能在數據處理完畢后立即釋放結果集,特別是在處理多個查詢的情況下,避免不必要的內存占用。
  3. 檢查 NULL:如果 mysql_store_resultmysql_use_result 返回 NULL,表明沒有結果集需要處理,因此不應該調用 mysql_free_result
整體的工作流程
  1. 執行查詢:首先使用 mysql_query 執行一個 SQL 查詢。
  2. 檢索結果:使用 mysql_store_result 檢索查詢結果并存儲在 MYSQL_RES * 結構中。
  3. 處理數據:通過循環等方式處理這些結果。
  4. 釋放資源:使用 mysql_free_result 釋放 MYSQL_RES * 結構占用的內存。
  5. 重復操作:如果需要再次查詢,回到第一步,執行新的 mysql_query,然后使用 mysql_store_result 檢索新的結果。

值得注意的是如果你在調用 mysql_store_result 之后沒有使用 mysql_free_result 來釋放結果集的內存,然后再次進行查詢并調用 mysql_store_result,這將導致內存泄漏。這是因為每次調用 mysql_store_result 都會從 MySQL 服務器獲取新的結果數據,并在客戶端為這些數據分配新的內存。如果舊的結果集沒有被適當釋放,那么這部分內存仍然被占用,盡管你已經無法再訪問到這部分數據。

4.3mysql_use_result()

MYSQL_RES *mysql_use_result(MYSQL *mysql)
參數說明
mysql: 指向 MYSQL 結構的指針,該結構表示一個已連接的 MySQL 數據庫。
返回值
成功:返回一個指向 MYSQL_RES 結構的指針,該結構代表結果集。
失敗:返回 NULL,并且可以通過 mysql_error 函數獲取錯誤信息。
while ((row = mysql_fetch_row(res))) {std::cout << "ID: " << row[0] << ", Name: " << row[1] << std::endl;
}
  1. 逐行處理mysql_use_result 逐行讀取結果集,這意味著你不能在獲取完整結果集之前執行其他查詢,否則會導致未定義行為。
  2. 資源釋放:使用 mysql_use_result 后,一定要調用 mysql_free_result 釋放結果集,確保內存資源被適當管理。
  3. 網絡延遲:因為 mysql_use_result 逐行讀取數據,受網絡延遲的影響可能會比 mysql_store_result 慢,但對于大結果集它能顯著降低內存占用。

mysql_use_resultmysql_store_result 都是用來處理查詢結果集的函數,但它們在處理方式上有以下區別:

  • mysql_store_result:一次性將整個結果集從服務器讀取到客戶端內存中,適用于結果集較小的情況,因為它會在客戶端占用較多內存。
  • mysql_use_result:逐行從服務器讀取結果集,適用于結果集較大的情況,因為它不會將整個結果集一次性加載到內存中,節省了內存占用。

4.4mysql_field_count()

在第三部分我們看到mysql_query不僅可以使用SELECT SQL語句還可以使用INSERT語句,我們對于查詢語句的列數和是否是查詢語句是有一定的判斷需求的

unsigned int mysql_field_count(MYSQL *mysql)
  • 返回一個 unsigned int 值,表示最近執行的查詢返回的列數。如果沒有活動的查詢或查詢沒有返回任何結果,則返回 0。

注意事項

  1. 正確的上下文mysql_field_count 應該在成功執行查詢之后調用,以確保它返回正確的列數。如果在沒有活動查詢的情況下調用它,返回值將是 0。
  2. 結果集處理:當你使用 mysql_store_resultmysql_use_result 來獲取結果集時,使用 mysql_field_count 可以幫助你動態地處理結果集中的數據。
  3. 查詢類型:對于不返回結果集的查詢(如 INSERTUPDATEDELETE),mysql_field_count 返回 0。

五、關閉MySQL

void mysql_close(MYSQL *mysql)

當你完成了數據庫操作并不再需要與數據庫的連接時,應該調用 mysql_close 來關閉連接。這個調用確保所有的客戶端資源被適當清理,包括內部緩沖區和連接句柄。如果不關閉連接,可能會導致資源泄漏。

void mysql_library_end(void);

在所有數據庫連接都已通過 mysql_close 關閉后,應調用 mysql_library_end 來清理 MySQL 客戶端庫使用的所有資源。這個函數主要用于多線程環境中,在所有線程都完成數據庫操作并關閉連接后,由主線程調用以確保所有的客戶端庫資源被正確釋放。

使用和區別

使用場景mysql_close 用于關閉單個數據庫連接;mysql_library_end 用于在程序結束前清理客戶端庫。

調用時機

mysql_close:每個數據庫連接在不再需要時應該被關閉。

mysql_library_end:在程序結束,所有數據庫連接都已關閉后調用。

值得注意的是即使在單線程應用程序中,依然推薦在程序結束時調用 mysql_library_end。這個函數的作用不僅限于多線程環境,它負責清理 MySQL 客戶端庫使用的全局資源,確保所有初始化時分配的資源被適當釋放,這包括內部數據結構、緩沖區等。

六、錯誤處理

mysql_errno()mysql_error()

mysql_errno() 返回最近一次 MySQL 函數調用所產生的錯誤代碼。這個錯誤代碼是一個整數值,表示特定類型的錯誤。

unsigned int mysql_errno(MYSQL *mysql);
返回一個 `unsigned int` 類型的錯誤代碼。如果沒有錯誤發生,返回值為 `0`。

mysql_error() 返回最近一次 MySQL 函數調用所產生的錯誤信息字符串。這個字符串描述了具體的錯誤情況,通常比錯誤代碼更易讀和理解。

const char *mysql_error(MYSQL *mysql);
返回一個指向描述錯誤的字符串的指針。如果沒有錯誤發生,返回一個空字符串。

通過使用 mysql_errno()mysql_error(),你可以更詳細地了解數據庫操作中的錯誤,幫助調試和改進程序的錯誤處理能力。這兩個函數在處理復雜數據庫交互時尤為重要,因為它們可以提供具體的錯誤信息和錯誤代碼,有助于定位和解決問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13072.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13072.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13072.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

001 側邊欄 地址增刪改查 默認地址代碼沒完善

文章目錄 user_index.htmlmyaccount_style.cssmyaccount_scripts.jsaddress_edit.htmlReceiverAddressReceiverAddressControllerReceiverAddressServiceImplIReceiverAddressServiceRFshopAppApplicationServletInitializerpom.xmlReceiverAddressMapper.xmlReceiverAddressMa…

文件存儲解決方案-阿里云OSS

文章目錄 1.菜單分級顯示問題1.問題引出1.蘋果燈&#xff0c;放到節能燈下面也就是id大于1272.查看菜單&#xff0c;并沒有出現蘋果燈3.放到燈具下面id42&#xff0c;就可以顯示 2.問題分析和解決1.判斷可能出現問題的位置2.找到遞歸返回樹形菜單數據的位置3.這里出現問題的原因…

Golang 的 unmarshal 踩坑指南

文章目錄 1. 寫在最前面2. 字段區分出空字段還是未設置字段2.1 問題描述2.2 解決 3. 字段支持多種類型 & 按需做不同類型處理3.1 問題描述3.2 解決 4. 碎碎念5. 參考資料 1. 寫在最前面 筆者最近在實現將內部通知系統的數據定義轉化為產品定義的對外提供的數據結構。 舉例…

算法學習筆記(5.0)-基于比較的高效排序算法-歸并排序

##時間復雜度O(nlogn) 目錄 ##時間復雜度O(nlogn) ##遞歸實現歸并排序 ##原理 ##圖例 ##代碼實現 ##非遞歸實現歸并排序 ##釋 #代碼實現 ##遞歸實現歸并排序 ##原理 是一種基于分治策略的基礎排序算法。 1.劃分階段&#xff1a;通過不斷遞歸地將數組從中點處分開&…

Java 開發 框架安全:Spring 命令執行漏洞.(CVE-2022-22965)

什么叫 Spring 框架. Spring 框架是一個用于構建企業級應用程序的開源框架。它提供了一種全面的編程和配置模型&#xff0c;可以簡化應用程序的開發過程。Spring 框架的核心特性包括依賴注入&#xff08;Dependency Injection&#xff09;、面向切面編程&#xff08;Aspect-Or…

【SpringBoot筆記43】SpringBoot應用程序集成spring-boot-admin監控工具

這篇文章,主要介紹SpringBoot應用程序如何集成spring-boot-admin監控工具。 目錄 一、spring-boot-admin監控工具 1.1、創建admin-client客戶端 (1)引入依賴

DeepSpeed

文章目錄 一、關于 DeepSpeed1、DeepSpeed 是什么2、深度學習訓練和推理的極致速度和規模3、DeepSpeed 的四大創新支柱1&#xff09;DeepSpeed 訓練2&#xff09;DeepSpeed 推理3&#xff09;DeepSpeed 壓縮4&#xff09;DeepSpeed4Science 4、DeepSpeed 軟件套件DeepSpeed 庫推…

React 第二十七章 Hook useCallback

useCallback 是 React 提供的一個 Hook 函數&#xff0c;用于優化性能。它的作用是返回一個記憶化的函數&#xff0c;當依賴發生變化時&#xff0c;才會重新創建并返回新的函數。 在 React 中&#xff0c;當一個組件重新渲染時&#xff0c;所有的函數都會被重新創建。這可能會…

青少年軟件編程(Python)等級考試試卷(五級)2024年3月

2024.03 電子學會 青少年軟件編程&#xff08;Python&#xff09;等級考試試卷&#xff08;五級&#xff09; 一、單選題 1.以下代碼的輸出結果是? ) nums list(range(100, 201)) print(nums[::10]) A.[100,110,120,130,140,150,160,170,180,190,200] B.[100,101,1…

QML筆記八

QML與C交互 QML中調用C功能、使用QML或者Quick中的C接口、使用C實現自定義的QML對象 注&#xff1a; 只有QObject的派生類才能與QML交互 QML引擎集成Qt元對象系統&#xff0c;QObject的派生子類的屬性、方法、信號都可以在QML中訪問 C類可以被注冊為一個QML實例 C類可以被注冊為…

【Web后端】請求頭

1、簡介 請求頭&#xff08;Request Headers&#xff09;是在HTTP協議中&#xff0c;客戶端&#xff08;如瀏覽器或應用程序&#xff09;向服務器發送請求時附帶的元數據。包含了關于請求的額外信息&#xff0c;有助于客戶端與服務器之間的有效通信。請求頭中的信息可以讓服務…

.[sqlback@memeware.net].2700勒索病毒數據怎么處理|數據解密恢復

導言&#xff1a; 隨著信息技術的飛速發展&#xff0c;網絡安全問題愈發嚴峻&#xff0c;其中勒索病毒成為了企業和個人用戶面臨的重要威脅之一。.[sqlbackmemeware.net].2700勒索病毒作為其中的佼佼者&#xff0c;以其獨特的攻擊方式和強大的破壞力&#xff0c;引起了廣泛關注…

【Go語言入門學習筆記】Part1.夢開始的地方

一、前言 經過一系列的學習&#xff0c;終于有時間來學習一些新的語言&#xff0c;Go語言在現在還是比較時髦的&#xff0c;多一個技能總比不多的好&#xff0c;故有時間來學一下。 二、配置環境 按照網絡中已有的配置方法配置好&#xff0c;本人采用了Jetbrain的Goland&#…

DTC 2024回顧丨zData X 多元數據庫一體機:開創多元數據庫時代部署新范式

導語 在2024“數據技術嘉年華”上&#xff0c;云和恩墨數據庫一體機產品總經理劉宇在“數據庫極致特性”專題論壇發表了題為《打造多元數據庫部署新范式&#xff0c;引領一體化資源池創新之路》的演講。他深入分析了國產數據庫面臨的挑戰&#xff0c;并詳細介紹了云和恩墨如何利…

5.10.1 Pre-Trained Image Processing Transformer

研究了低級計算機視覺任務&#xff08;例如去噪、超分辨率和去雨&#xff09;并開發了一種新的預訓練模型&#xff0c;即圖像處理變壓器&#xff08;IPT&#xff09;。利用著名的 ImageNet 基準來生成大量損壞的圖像對。 IPT 模型是在這些具有多頭和多尾的圖像上進行訓練的。此…

Megatron-lm、DeepSpeed

1、為了訓練更多的數據、更大的模型&#xff0c;提出了并行訓練框架。 2、并行的方式&#xff1a;數據并行、模型并行&#xff08;張量并行、流水線并行&#xff09;。 3、Megatron-LM 綜合應用了數據并行&#xff08;Data Parallelism&#xff09;&#xff0c;張量并行&…

內網安全工具之ADExplorer的使用

ADExplorer是域內一款信息查詢工具&#xff0c;它是獨立的可執行文件&#xff0c;無需安裝。它能夠列出域組織架構、用戶賬號、計算機賬號登&#xff0c;可以幫助尋找特權用戶和數據庫服務器等敏感目標。 下載地址&#xff1a;http://live.sysinternals.com/ 連接 下載了ADE…

第十四屆藍橋杯大賽軟件賽國賽C/C++ 大學 B 組 拼數字

//bfs只能過40%。 #include<bits/stdc.h> using namespace std; #define int long long int a,b,c,dp[2028]; struct s {int x,y,z;string m; }; map<vector<int>,int>k; signed main() {ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>a…

Java入門基礎學習筆記24——While循環和do-while循環

1、While循環&#xff1a; 例1&#xff1a; package cn.ensource.loop;public class WhileDemo3 {public static void main(String[] args) {// 目標&#xff1a;掌握while循環的書寫格式&#xff0c;以及理解其執行流程// 需求&#xff1a;打印多行Hello Worldint i 0;while…

EFCore_創建項目

添加依賴 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.Tools(Migration工具) 根據使用的DB添加對應依賴&#xff1a; SQL Server&#xff1a;Microsoft.EntityFrameworkCore.SqlServer 添加該依賴時可不添加Microsoft.EntityFrameworkCore&#xff0c;該依…