08.13 freetds簡介、安裝、配置及使用介紹

什麼是FreeTDS

簡單的說FreeTDS是一個程序庫,可以實現在Linux系統下訪問微軟的SQL數據庫! FreeTDS 是一個開源(如果你喜歡可以稱為自由)的程序庫,是TDS(表列數據流 )協議的再次實現。它可以被用在Sybase的db-lib或者ct-lib庫。它也包含一個ODBC的庫。允許許多開源的應用軟件比如Perl和PHP(或者你自己的c或C++程序)去連接到Sybase或 Microsoft SQL服務器。FreeTDS 以源碼的形式被髮布,幾乎可以在任何操作系統上編譯。意味著Unix和類Unix系統(包括著名的分支如Interix和QNX),還有Win32,VMS,和OSX。

FreeTDS的安裝

1.下載freetds,點此下載 http://www.jb51.net/database/201983.html

2.將其解壓到任意目錄,進入到解壓後的文件夾裡。

3.切換到root,配置: ./configure –prefix=/usr/local –with-tdsver=7.1 –enable-msdblib 解釋:–prefix為設置FreeTDS的安裝目錄,–with-tdsver是設置TDS版本, –enable-msdblib為是否允許Microsoft數據庫函數庫

4.make & make install

FreeTDS測試:

FreeTDS安裝好了,接下來就可以查看下FreeTDS狀態了;

運行./tsql -C ,在安裝目錄的bin目錄下可以找到tsql ,查看終端打印出來信息,這個-with-tdsver=7.1:

關於安裝參考

http://linux.chinaunix.net/techdoc/database/2008/10/31/1042291.shtml 或者:http://www.linuxdiyf.com/viewarticle.php?id=109086

FreeTDS的配置

freeTDS 的配置文件,FreeTDS也支持一箇舊的配置文件interfaces,但請使用freetds.conf 除非你的環境必須使用interfaces。FreeTDS首先找freetds.conf文件如果沒有找到才去找 interfaces文件。 freetds.conf文件默認在/usr/local/freetds/etc目錄下,但是可以在configure時配置 sysconfdir選項,這個選項就是freetds.conf文件所存在的目錄。freetds.conf配置文件分為兩部分:一是[global]部分,另外一個是[dataserver]部分,其中 [dataserver]對應一個數據庫。在golbal中的設置是對全部數據庫起作用的,但在dataserver 部分的設置只對自己的數據庫起作用,並且可以覆蓋全局的設置。

例如: freetds.conf文件:

1 [global]

2 tds version = 4.2

3 [myserver]

4 host = ntbox.mydomain.com

5 port = 1433

6 [myserver2]

7 host = unixbox.mydomain.com

8 port = 4000

9 tds version = 5.0

這個文件中global設置所有數據庫使用tds版本為4.2,但在myserver2中使用的版本卻是5.0, 如果myserver2中沒有這一項,那就是用4.2版本的如myserver。

其配置項解釋如下:

ltds version : 指明tds協議的版本,連接數據庫時使用,如果在環境變量中沒有設置 此項,則由此配置決定,協議版本可取4.2,5.0,7.0,8.0。

lhost : 數據庫服務器的主機名或者ip地址。

lport : 數據庫服務器的監聽端口,可以取任何有效的端口值,一般而言Sybase SQL10以前為 1433,10以上用5000,而Sybase SQLAnywhere 7是2638,Microsoft SQL server則用 1433。此配置可以被環境變量中的TDSPORT改寫。

linitial block size : 此值只能取512的倍數,默認為512,指定了協議塊的最大值, 一般不要改變此默認 配置。

ldump file : 任何有效的文件名,指明瞭轉儲文件的路徑並且會打開日誌記錄。

ldump file append: yes或者no,決定是否追加保存到dump file文件中。

ltimeout :設置處理的最大等待時間。

lconnect timeout: 設置連接的最大等待時間。

lemulate little endian: yes或者no,是否強制大端機使用小端方式與MS Server通信。

lclient charset : 任何有效的iconv字符集。默認值為ISO-8859-1,使FreeTDS使用 iconv在數據庫服務器和用戶程序之間轉換。

FreeTDS函數

1. Dbcmd和dbfcmd

函數原形: Dbcmd(DBPROCESS *proc,char * sql);

     Dbcmd(DBPROCESS *proc, char * format,char *args);

功 能:該函數主要是構造sql語句,一個是帶參數的,一個不帶參數。

2. Dbsqlexec

函數原形:Dbsqlexec(DBPROCESS *proc);

功 能:該函數負責執行你所構造的sql語句。

3. Dbresults

函數原形:Dbrerults(DBPROCESS *proc);

功 能:得到sql語句的執行結果。返回值如果為NO_MORE_RESULTS=0,表明sql查詢為空值(就是沒有一條滿足條件的結果),如果為(FAIL)=-1,表明查詢出錯,如果為(SUCCESS)=1,表明有結果且不為空。

4. DBROWS(全大寫)

函數原形:DBROWS(DBPROCESS *proc);

功 能:取出一行記錄的信息。

5. Dbbind

函數原形:Dbbind(DBPROCESS *proc,int colmn,

功 能:將sql查詢出來的結果綁定到一個變量。第一個參數為從數據庫那裡拿的句柄,第二個參數是對應你的select語句中查詢需要的字段(注:必須是按照select順序綁定的,例如select user,password from hist1 ,如果值為1,就是綁定的user),第三個參數是綁定字段的類型,最後一個參數是綁定的變量。

6. Dbnextrow

函數原形:Dbnextrow(DBPROCESS *proc);

功 能:該函數將取出滿足sql語句的每一行,返回值為0,代表處理結束,返回值為-1出錯。

7. Dbcancel

函數原形:Dbcancel(DBPROCESS *proc);

功 能:清空上次查詢得到的數據集,如果是一個句柄的話,每次重新執行select語句之前都要調用它清空結果,不然數據庫會報錯的。

8. Dbclose

函數原形:Dbclose(DBPROCESS *proc);

功 能:關閉句柄。當不再使用時必須關閉句柄。

9. Dbinit

函數原形:Dbinit()

功 能:初識化數據庫連接。返回值為-1出錯。

10. Dblogin

函數原形:LOGINREC *Dblogin();

DBSETLUSER(login,SOFT); //set the database user

DBSETLPWD(login,SOFTPASS);//set password

功 能:根據用戶名和密碼連接數據庫。

11.Dbcount

函數原形:Dbcount(DBPROCESS *proc);

功 能:該函數將得到sql結果集被處理的行數,可以用它來判斷你的select語句是否得到正確的處理。

12.Dbopen

函數原形:DBPROCESS * Dbopen(LOGINREC *login,NULL);

功 能:返回一個操作數據庫的句柄。

另外再介紹兩個關於數據庫的出錯信息的函數:

dberrhandle(int *err);

dbmsghandle(int* err);

實例代碼

1 #include <stdio.h>

2 #include <stdlib.h>

3 #include <string.h>

4 #include <unistd.h>

5 #include <sqlfront.h> /* sqlfront.h always comes first *//<sqlfront.h>

6 #include <sybdb.h> /* sybdb.h is the only other file you need *//<sybdb.h>

7 #define SQLDBIP " " //SQL數據庫服務器IP

8 #define SQLDBPORT " " //SQL數據庫服務器端口

9 #define SQLDBNAME " " //SQL數據庫服務器數據庫名

10 #define SQLDBUSER " " //SQL數據庫服務器數據庫用戶名

11 #define SQLDBPASSWD " " //SQL數據庫服務器用戶密碼

12 #define SQLDBSERVER SQLDBIP":"SQLDBPORT

13 #define DBSQLCMD "select * from yancao"

14 int main(int argc, char *argv[])

15 {

16 int i, ch;

17 LOGINREC *login; //描述客戶端的結構體,在連接時被傳遞到服務器.

18 DBPROCESS *dbproc; //描述連接的結構體,被dbopen()函數返回

19 RETCODE erc; //庫函數中最普遍的返回類型.

20 /*************************************************************/

21 //在開始調用本庫函數前常常要先調用dbinit()函數

22 if (dbinit() == FAIL) {

23 fprintf(stderr, "%s:%d: dbinit() failed\\n", argv[0], __LINE__);

24 exit(1);

25 }

26 //dblogin()函數申請 LOGINREC 結構體,此結構體被傳遞給dbopen()函數,用來創建一個連接。

27 //雖然基本上不會調用失敗,但是檢查它!.

28 if ((login = dblogin()) == NULL) {

29 fprintf(stderr, "%s:%d: unable to allocate login structure\\n", argv[0], __LINE__);

30 exit(1);

31 }

32 //LOGINREC結構體不能被直接訪問,要通過以下宏設置,下面設置兩個必不可少的域

33 DBSETLUSER(login, SQLDBUSER);

34 DBSETLPWD(login, SQLDBPASSWD);

35 /*************************************************************/

36 //dbopen()與服務器建立一個連接. 傳遞 LOGINREC 指針和服務器名字

37 if ((dbproc = dbopen(login, SQLDBSERVER)) == NULL) {

38 fprintf(stderr, "%s:%d: unable to connect to %s as %s\\n",

39 argv[0], __LINE__,

40 SQLDBSERVER, SQLDBUSER);

41 exit(1);

42 }

43 // 可以調用dbuser()函數選擇我們使用的數據庫名,可以省略,省略後使用用戶默認數據庫.

44 if (SQLDBNAME && (erc = dbuse(dbproc, SQLDBNAME)) == FAIL) {

45 fprintf(stderr, "%s:%d: unable to use to database %s\\n",

46 argv[0], __LINE__, SQLDBNAME);

47 exit(1);

48 }

49 /*************************************************************/

50 dbcmd(dbproc, DBSQLCMD);//將SQL語句填充到命令緩衝區

51 printf("\\n");

52 if ((erc = dbsqlexec(dbproc)) == FAIL) {

53 fprintf(stderr, "%s:%d: dbsqlexec() failed\\n", argv[0], __LINE__);

54 exit(1); //等待服務器執行SQL語句,等待時間取決於查詢的複雜度。

55 }

56 /*************************************************************/

57 //在調用dbsqlexec()、dbsqlok()、dbrpcsend()返回成功之後調用dbresults()函數

58 printf("then fetch results:\\n");

59 int count = 0;

60 while ((erc = dbresults(dbproc)) != NO_MORE_RESULTS) {

61 struct col { //保存列的所有信息

62 char *name; //列名字

63 char *buffer; //存放列數據指針

64 int type, size, status;

65 } *columns, *pcol;

66 int ncols;

67 int row_code;

68 if (erc == FAIL) {

69 fprintf(stderr, "%s:%d: dbresults failed\\n",

70 argv[0], __LINE__);

71 exit(1);

72 }

73 ncols = dbnumcols(dbproc);//返回執行結果的列數目

74 if ((columns = calloc(ncols, sizeof(struct col))) == NULL) {

75 perror(NULL);

76 exit(1);

77 }

78 /* read metadata and bind. */

79 for (pcol = columns; pcol - columns < ncols; pcol++) {

80 int c = pcol - columns + 1;

81 pcol->name = dbcolname(dbproc, c); //返回指定列的列名

82 pcol->type = dbcoltype(dbproc, c);

83 pcol->size = dbcollen(dbproc, c);

84 printf("%*s(%d)", 20, pcol->name, pcol->size);

85 if ((pcol->buffer = calloc(1, 20)) == NULL) {

86 perror(NULL);

87 exit(1);

88 }

89 erc = dbbind(dbproc, c, NTBSTRINGBIND, 20, (BYTE*)pcol->buffer);

90 if (erc == FAIL) {

91 fprintf(stderr, "%s:%d: dbbind(%d) failed\\n",

92 argv[0], __LINE__, c);

93 exit(1);

94 }

95 erc = dbnullbind(dbproc, c, &pcol->status); //(5)

96 if (erc == FAIL) {

97 fprintf(stderr, "%s:%d: dbnullbind(%d) failed\\n",

98 argv[0], __LINE__, c);

99 exit(1);

100 }

101 }

102 printf("\\n");

103 /* 打印數據 */

104 while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {//讀取行數據

105 switch (row_code) {

106 case REG_ROW:

107 for (pcol = columns; pcol - columns < ncols; pcol++) {

108 char *buffer = pcol->status == -1 ?

109 "null" : pcol->buffer;

110 printf("%*s ", 20, buffer);

111 }

112 printf("\\n"); break;

113 case BUF_FULL: break;

114 case FAIL:

115 fprintf(stderr, "%s:%d: dbresults failed\\n",

116 argv[0], __LINE__);

117 exit(1); break;

118 default: // (7)

119 printf("data for computeid %d ignored\\n", row_code);

120 }

121 }

122 /* free metadata and data buffers */

123 for (pcol = columns; pcol - columns < ncols; pcol++) {

124 free(pcol->buffer);

125 }

126 free(columns);

127 if (DBCOUNT(dbproc) > -1) /* 得到SQL語句影響的行數 */

128 fprintf(stderr, "%d rows affected\\n", DBCOUNT(dbproc))

129 }

130 dbclose(dbproc);

131 dbexit();

132 }

freetds簡介、安裝、配置及使用介紹


分享到:


相關文章: