數據庫,DataBase,學C語言的是否是想說,很想愛她卻並不容易呢?不用着急,C語言也能夠操做數據庫的,既使你不會Windows API,只要參照本文的方法,寫數據庫應用程序,你也行。本文以MySql和Access數據庫爲基礎,簡要介紹C語言如何操做數據庫,本文部分知識點也適用於linux下面編程使用MySql數據庫。javascript
1、若是你只會一點C語言,那麼還有哪些知識須要你本身去補充呢?html
(1)瞭解一下數據庫的基本狀況,發展史,頗有必要,選用一種數據庫,數據庫有不少,開源數據庫聽說多達35個,經常使用的數據庫也有以下幾個:MySQL、 PostgreSQL、MaxDB、Ingres、SQLite。這些大部分都是免費開源的數據庫,都須要你去下載安裝的,微軟還有收費的MSSQL,Access數據庫可使用,固然,對於大多數中國用戶來講,MSSQL, Access無償使用,本文以MySql和Access數據庫爲例,示例C語言如何操做數據庫。關於Access數據庫,安裝過office的基本上都有,若是不會使用它建立mdb數據庫的話,請到http://www.bccn.net/Article/sjk/access/Index.html 本站的技術文檔中學習一下。前端
(2)瞭解SQL基本語法,所謂的SQL,就是指結構化查詢語言,數據庫操做的基本語言,至少有四個語句須要你學習和掌握,它們就是Select查詢語句,Update更新語句,Insert插入語句和Delete刪除語句,其它的還有建表,建庫,建關係等等。。能夠參考偶上傳的資料《mysql中文參考手冊》,有不少的SQL語言學習書,想要深刻學習的還能夠看老外的《SQL語言藝術》這本。java
資料下載:http://115.com/file/be42nia8mysql
文件:mysql5.1中文手冊.rarlinux
(3)瞭解C語言與數據庫互動的方式,其實只有兩種,一種是經過win32 API接口,一種就是直接經過數據庫提供的C頭文件和DLL庫直接操做數據庫。mySQL同時提供兩種接口方式,SQLite提供直接訪問的C語言頭文件和DLL庫,SQLite還能夠把代碼直接編譯進程序當中,使數據庫訪問更加快徢。Windows經常使用數據庫接口是odbc接口,另外還有ADO, OLE DB接口,固然,和odbc相比,它們的學習基本上是一通百通的,數據庫互動,基本上成了一個定式,建立數據庫鏈結->建立語句對象->執行SQL命令->訪問執行結果集->關閉鏈結,不管是java語言仍是C#,仍是VB,javascript語言,都是相同或是類似的,因此學習也是一通百通,由於重點並不在這裏,而是在SQL自己的掌握上,請將重點移到SQL語言自己,數據庫設計原則,存儲過程上面。web
(4)數據源DSN,關於如何建立數據庫的鏈結數據源DSN,這個是基礎知識,在控制面板/管理工具/數據源(odbc)中,若是不會玩的話,仍是在網上去搜索一下圖文教程,學習一下,本文就不重複了。sql
2、準備本示例所須要的數據庫。數據庫
(1)下載並安裝:mySQL的官網:http://www.mysql.com/downloads/,目前最新版本爲5.5.18,雖然已被人收購,但並不影響咱們學習SQL,版本分爲企業版和公衆版,公衆版對於學習的我的是免費的,並且也是足夠了,因此咱們下載上面的MySQL Community Server版,另外一個須要下載的是Connector/ODBC,這個是ODBC驅動,可選下載爲MySQL Workbench (GUI Tool),這個是用於Gui前端管理軟件,就是命令行的可視版,說白了就是一個窗口界面,你能夠經過界面操做mySql數據庫,會命令行的都習慣於使用命令行操做,若是你想成爲它的專家,使用命令行吧。不懂英文頁面?不要緊,下載最簡單的方式就是在上點那個最大的圖,mysql installer for windows,上面所說的三個部件包括使用文檔資料都放在一個安裝包裏了,209MB。測試了一下,從National Sun Yat-Sen University, Taiwan 臺灣站http下載比較快。安裝額外需求,.NET4運行庫。補充說明一下,MySQL Workbench的安裝須要VC++ 2010運行庫和.net4運行庫,數據庫系統MySQL Community Server版和Odbc驅動的安裝無任何附加安裝需求,因此能夠單獨下載所需部件進行安裝,不用註冊我的資料也能夠直接下載。編程
安裝過程當中若是有須要,能夠選擇Developer Componets下面的C include files/Lib files這個,是用來直接和數據庫相鏈的C語言頭文件和庫文件。安裝完成後,在彈出的配置MySql對話框,選擇standard Confiuration,下一步,勾選include Bin Director in Windows Path這項,下一步後,在Modify Securiti Settings那裏填寫新的登陸安全密碼,下一步Execute執行既可完成。
資料下載:上次提供的5.1.3版客戶端中文顯示有問題,5.1.0版雖然中文顯示沒有問題,但在建立表約束那裏有問題。最新的版本通過測試沒有這個二個問題。
http://115.com/file/an4yzdwc#
mysql-5.5.18-win32.rar (mysql 5.5.18官方版,31MB,)
http://115.com/file/c2bpnc9g
mysql-connector-odbc-5.1.9-win32.rar (mysql odbc 驅動32位 2.5MB)
(2)數據庫示例:以簡單的通信錄爲例。
數據庫:PersonAL
表1:Users(本表存放用戶信息)
字段(共3個):uid (自動數字),name(char, 10)--姓名,pass(char, 15)--密碼
表2:PersonInfo(本表存放聯繫人信息)
字段(共10個):pid (自動數字), name(char, 10) --姓名,gender(char, 2)--性別, birthday(date)--生日
city(char, 10)--所在城市, telphone(char, 20)--聯繫電話, qq(char, 15) -- QQ號,
web(char 30)--微博, gid(int)--所屬組id,uid(int)--所屬用戶id
表3:GroupInfo(本表存放聯繫人分組信息)
字段(共2個):gid(自動數字), name(char, 20) --組名
(2.1)Access數據庫建立:
請參照Access軟件使用建立PersonAL.mdb數據庫,並建立這三張對應的表,若是不會,請趕快學習,不重複了。同時這裏也提供建立好的數據庫。
建好的數據庫:http://115.com/file/an4ntb4n#
PersonAL.rar
(2.2)MySql數據庫建立:你能夠先把上面的<mysql中文手冊>第三節教程,打開學習一下,這裏要提醒的是每一個SQL語句都以分號爲結束,和C語言同樣,不要忘記打了, 微軟的SQL Server中不須要這個分號。若是SQL命令輸錯了,請\c,而後回車返回。
(2.3)mySql的中文問題,默認的語言不符合要求,咱們須要修改mysql目錄下面的my.ini中的編碼語言,這裏一共有兩地方須要修改,一個是[client]客戶端那裏,把裏面的default-character-set=xxxx 改爲 default-character-set=gbk或是gb2312(中文編碼),可以使mysql.exe客戶端在查詢的時候顯示中文數據,另外一個服務器端,修改爲default-character-set=utf8,這樣能夠保證和網頁的經常使用編碼一致,保存配置,打開控制面板中的服務,重啓mysql服務器,從開始菜單中到mysql程序組啓動mysql命令行客戶端,輸入安裝時設置的密碼,進入到mysql命令行狀態:
mysql->
在裏面輸入以下命令建立數據庫,每一個分行是一條。PersonAL.sql:
固然,若是你不想輸入這麼多的東西,告訴你一個小巧門,直接複製語句到mysql命令窗口中,粘帖上去,而後回車,就OK了,可是咱們仍是須要隨着學習的深刻,瞭解並掌握SQL腳本的書寫,通常作法是用一個文本文件來書寫這些SQL語句,以備在不一樣的機器上使用或是恢復數據庫用。微軟的SQL Server通常把這些命令腳本存放在.sql文件中,能夠直接導入導出。mysql也有數據庫導入導出的功能,怎麼使用這個問題做業就交給你了,學會上網搜索,這就是學習方法,別人告訴你有這麼一回事存在,你就要本身去找,不要總等着別人來餵你。當你在這個命令行中再輸入select * from groupinfo;後,顯示5條中文的數據,就表示數據庫建立成功。以下圖所示。輸入quit能夠退出mysql命令行。更多SQL語法詳解請參見手冊第13章那裏。
上面的腳本語言要說明的是註釋行用--,這個和SQL Server的註釋語法相同,不一樣的是mysql裏--後面要加一個空格。沒有添加其它表約束,留個做業給你,請查詢手冊,爲PersonInfo添加數據約束,如性別只能輸入男或是女,QQ號必須是數字,web必須符合網址要求,同時爲groupInfo表添加組名的維一性約束,既不能輸入相同的組名字。若是建立完數據庫,發現最後幾條中文數據插不進去,輸入show create database personal;後顯示數據庫編碼爲非utf8的其它值,就是數據庫編碼的問題了,解決辦法見上面所述,須要退出命令行,修改配置文件,而後重啓服務器。若是發現你本身的數據插入不進PersonInfo表中,那是主外健約束引發的,在主表播入的數據,在子表中必須存在,因此若是你不明白這裏所述的,說明你還不瞭解數據庫,既使學會程序操做,也沒有意義,靜下心來認真拿本SQL書學習一下爲上策。
3、SQLExt.h頭文件與odbc32.lib庫。
(1)瞭解ODBC接口以及爲何使用ODBC接口。
ODBC API 接口是(Open Database Connectivity)開放式數據庫接口,它創建了一組規範,並提供了一組對數據庫訪問的標準API,這些API利用SQL來完成其大部分任務。ODBC自己也提供了對SQL語言的支持,用戶能夠直接將SQL語句送給ODBC。個基於ODBC的應用程序對數據庫的操做不依賴任何DBMS,不直接與DBMS打交道,全部的數據庫操做由對應的DBMS的ODBC驅動程序完成。也就是說,不管是FoxPro、Access仍是Oracle數據庫,都可用ODBC API進行訪問。因而可知,ODBC的最大優勢是能以統一的方式處理全部的數據庫。至於爲何使用它,而不使用DAO接口,微軟的網頁是這麼解釋的:從 Visual C++ .NET 起,Visual C++ 環境和嚮導再也不支持 DAO(不過提供了 DAO 類,仍可供您使用)。Microsoft 建議對新項目使用 OLE DB 模板或 ODBC。
(2)因爲操做ODBC 須要win32 API接口,因此編程環境確定就不能用tc2.0之類的老C語言編譯系統了,這裏推薦使用VC6.0以上的版本,或是使用MinGW(gcc)作爲編譯器的IDE:c-free, devcpp,codelite/codeblocks等編程環境,若是你想跟着本文練習,那麼趕快下載裝上嘍。odbc 3.X版操做使用的頭文件主要是SQLExt.h,全部的宏,數據類型,及接口均在這裏定義,你能夠打開瀏覽一下,odbc所需鏈結庫爲odbc32.lib,在Mingw裏是libodbc32.a這個文件,因此須要在鏈結中添加這個庫,不然將出現函數找不到的鏈結錯誤。
(3)ODBC的九類接口函數:也能夠參見(手冊26章1.16節詳細)
I. 鏈接資料來源(Connecting to a Data Source)
1. SQLAllocEnv.
2. SQLAllocConnect.
3. SQLConnect.
4. SQLPriverConnect.
5. SQLBrowseConnect.
II. 取得驅動程序及資料來源的相關訊息
1. SQLDataSource.
2. SQLGetInfo.
3. SQLGetFunctions.
4. SQLGetTypeInfo.
III. 設定及取得驅動程序的選項
1. SQLSetConnectOption.
2. SQLGetConnectOption.
3. SQLSetStmtOption.
4. SQLGetStmtOption.
IV. 準備SQL指令之需求
1. SQLAllocStmt.
2. SQLPrepare.
3. SQLSetParam.
4. SQLParamOptions.
5. SQLGetCursorName.
6.SQLSetCursorName.
7. SQLSetScrollOptions.
V. 傳送及執行需求
1. SQLExecute.
2. SQLExecDirect.
3. SQLNativeSql.
4. SQLDescribeParanl.
5. SQLNumParams.
6.SQLParamData.
7. SQLPutData.
VI. 取得執行結果及有關結果的訊息
1. SQLRowCount.
2. SQLNumResultCols.
3. SQLDescribeCol.
4. SQLColAttributes.
5. SQLBindCol.
6.SQLFetch.
7. SQLExtendedFetch.
8. SQLGetData.
9. SQLSetDos.
10. SQLMoreResults.
11. SQLError.
VII. 取得有關資料來源系統回錄(System tables or Catalog)的訊息
1. SQLColumnPrivileges.
2. SQLColumns.
3. SQLForeignkeys.
4. SQLPrimaryKeys.
5.SQLProcedureColumns.
6. SQLProcedures.
7. SQLSpecialColumns.
8. SQLStatistics.
9. SQLTablePrivileges.
10. SQLTables.
VIII. 結束 SQL 指令需求
1. SQLFreeStmt.
2. SQLCancel.
3. SQLTransact.
IX. 結束與資料來源的鏈接
1. SQLDisconnect.
2. SQLFreeConnect.
3. SQLFreeEnv.
API學習的方法,和咱們學習C語言的庫函數沒什麼兩樣,準備好msdn,或是經過網絡搜索功能,你能夠查找到每一個Api函數的使用,同時也能夠學習msdn上面微軟寫的示例代碼。這些API都是以SQL打頭的函數,規範的函數命名也值得你我學習,看着不少,但本文不打算所有都用上,只用其中不多量的函數,因此不要懼怕,須要其它功能的時候,有這個表格,也能夠方便你查找函數使用。
4、SQL數據類型和C語言數據類型。
SQL_C_CHAR 是默認的 ODBC 傳輸類型,其它數據類型請參見手冊中的ODBC數據類型(26章1.17節那裏),不重述了。這一章裏面還有關於Access數據庫與Mysql數據庫數據導入方法,用SELECT LAST_INSERT_ID();取得auto_increment值,以及ODBC應用基本步驟、API引用,及調用錯誤代碼含義,初學時能夠翻翻這些地方,說不定你的問題就在上面就解決了。
5、操做過程。
ODBC操做步子以下:
· 配置MyODBC DSN。(這一步不是必須的,能夠直接鏈接)
· 鏈接到MySQL服務器或是Access數據庫。
· 初始化操做。
· 執行SQL語句。
· 檢索結果。(Select語句返回結果集,update/delete/insert返回受影響的行數)
· 執行事務。
· 斷開與服務器的鏈接。
圖解見手冊26.1.15節。這個操做步子在Java橋連裏是同樣的,使用的是jdbc:odbc:數據源名,JavaScript也是一樣的步子,偶之前寫過網頁JavaScript操做access數據庫,因此一通百通。爲了更好的理解數據庫操做,咱們採用傳統的控制檯界面來示例,其實作windows界面版的,基本數據庫操做和這個控制檯的同樣,沒什麼兩樣,拋開界面,更有利於咱們看到問題的實質。
C示例代碼,操做PersonAL.mdb庫。
程序編譯說明,vc6下面,odbc32.lib默認是鏈接庫,因此上述程序直接編譯鏈接經過,生成執行文件。數據庫放在工程項目中,既可顯示正確的數據,若是是在debug/Release目錄下執行,把數據庫拷到當前exe目錄下執行既可。若是是使用的codeblocks,請在菜單project(工程)/Build Option(生成選項)中,在Linker Setting(鏈結設置)點add(添加),輸入odbc32,肯定,既可以使程序鏈結上odbc32運行庫。在codeblocks中,用debug方式生成的exe,35KB左右,若是你選擇Release方式生成可執行文件,才9.5KB,是否是很小很爽呢?有下圖爲證:(若是你不會使用codeblocks,可參考偶寫的另外一帖:http://bbs.bccn.net/thread-345867-1-1.html)
-------------- Build: Release in dbtest ---------------
Compiling: main.c
Linking console executable: bin\Release\dbtest.exe
Output size is 9.50 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings
要鏈接使用MySQL,怎麼作呢?將程序裏面的SQLCHAR connstr[] 鏈拉字符串這裏,改爲SQLCHAR connstr[] = "DRIVER={MySQL ODBC 5.1 Driver};SERVER=localhost;UID=root;PWD=sa;DATABASE=personal;CharSet=gb2312;";程序其它部分不變,既可以使用MySQL裏咱們建立的數據庫,或是你也能夠本身改動一下,將查詢語句改爲"Select * from GroupInfo",而後就能夠看到從組表中查詢出來的數據,比Access那個數據庫多一條數據(偶故意的),因此證實你連結的是MySQL數據庫,不是Access數據庫,至於爲何是DRIVER={MySQL ODBC 5.1 Driver};,只要你打開控制面板中的odbc數據源,對比一下多個數據源驅動名,你就明白爲何這麼寫字符串。由此也能夠看出,除了使用odbc接口程序的通用性,除了鏈結字符串的不一樣外,其它都是相同的,因此不少人把鏈結字符串寫進一個文本文件中,作爲數據庫應用的配置文件,只要改動這個文件,就能夠實現鏈接不一樣的數據庫。
6、本身動手封裝odbc操做接口,方便使用。
爲何要封裝?固然是爲了咱們方便使用,觀察上面的程序,
//分配環境
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,&henv);
//設置環境屬性
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
//分配鏈結
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
這些對應的API調用,基本上是一個固定的格式,全部的參數,一些宏啊什麼的,又長又難記,咱們學習的時候,若是太久了,回頭讓你重寫這些代碼,一定你是記不住這麼多的,因此既然當前你在學習數據庫,因此把這些代碼封裝起來更好,例如寫一個ODBC_GetConnection(char * string)函數用於獲取數據庫鏈結,用ODBC_CreateStatement(char * sql)來建立SQL語句,用ODBC_ExecuteCommand(),ODBC_ExecuteQuery(),分別用於執行增,刪,改,查命令,具體代碼就交給你本身寫了,若是你不知道怎麼用函數來封裝這些東西,只能說你最基本的C語言都沒有掌握,看本文也就毫無心義了。理解了這些API的調用後,實際上對於你理解MFC中的CDataBase類,CRecordSet類的使用和內部工做原理了解也是大有幫助。
7、鏈表與結果集
還記得偶的上一篇文章,關於鏈表的進一步深刻學習麼?鏈表的應用在本文中又一次發揮了重要的做用。觀察上面的程序,在SQL語句執行後,實際上結果集中的數據在系統那裏,咱們只是經過SQLGetData從裏面抓出數據而矣,而後通常狀況下,操做完成就會關閉數據庫,系統的結果集就消失了(固然,你可使用連接池)因此,咱們可使用一個鏈表將裏面的數據裝出來,在關閉數據庫後,咱們也能夠對結果集中的數據作進一步處理,這個時候,可能咱們會查詢多個表,獲得多個結果集,因此在C中使用通用鏈表,將使咱們的操做更加方便。C++中有STL的List類,更容易保存數據到類對象中。若是你還學習過C#,還能夠發現一個更有趣的封裝實例DataSet結果集類,能夠直接從DataRow,產生新的結果集,這種封裝應該說把數據的抽象提升到一個新的高度。另外要提提醒新手的是,若是使用鏈表作爲數據結果集保存對象,請不要使用Select * from語句將數據庫中的數據所有提取出來,若是是這樣的話,表中有1000萬行記錄的時候,將讓你的程序佔用大量的內存,正確的方法是使用Sql分頁語法,例如一次只取出10行記錄,靈活使用SQL語句,將讓你的程序運行更快,更有效,若是你不知道SQL分頁,請搜索相關的知識或是看SQL書。
8、在其它機器上運行你的數據庫應用程序。
一種辦法是將你的程序和數據庫一塊兒打包進行安裝,對於Access這樣的數據庫來講很方便的,直接把程序和數據庫拷在一塊兒發佈給對方就好了,對於象MySQL這樣的程序來講,讓別人的機器上也安裝MySQL是一個辦法,而後經過程序或是mysql的客戶端執行SQL腳本建立數據庫。大多數時候,都是經過網絡來鏈結MySQL的,也就是說鏈接字符串SERVER=這裏改爲對方的IP地址,xxxx.xxxx.xxx.xx,既可經過IP地址連上MySQL服務器,事實上,BBS論壇,網站,微博,這些都是以數據庫爲基礎開發的,採用的依然是這種服務器和客戶端方式。
總結:
C語言和數據庫怎麼操做?看到N多的人在問這個問題,但實際上,問的人自己是否瞭解數據庫?瞭解C語言?瞭解API?仍是僅僅感興趣而矣?不用懷疑,寫本文的時候,偶對MySQL並不瞭解,邊看手冊邊寫的,但之前學過SQL,所以同樣能夠寫出來,因此學程序的不要侷限於一種語言,有機會你多嘗試一種新的語言,你會發現它們學習的共性,若是本文帶給你一些學習的新思路和深思,本人將不勝榮幸,若是哪一個地方寫得有問題,請留言。
附:JavaScript腳本操做Access操做數據庫代碼,對比一下C代碼,本質上不變。
。。。。。。。(全文完...)