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

來源:互聯網
上載者:User

什麼是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/freetds –with-tdsver=8.0 –enable-msdblib 解釋:–prefix為設定FreeTDS的安裝目錄,–with-tdsver是設定TDS版本, –enable-msdblib為是否允許Microsoft資料庫函數庫

4.make & make install

5.配置環境變數:vim ~/.bashrc向此檔案中加入: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/freetds/lib/

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檔案:

[global]
tds version = 4.2
[myserver]
host = ntbox.mydomain.com
port = 1433
[myserver2]
host = unixbox.mydomain.com
port = 4000
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);

執行個體代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sqlfront.h> /* sqlfront.h always comes first */
#include <sybdb.h> /* sybdb.h is the only other file you need */
#define SQLDBIP " " //SQL資料庫伺服器IP
#define SQLDBPORT " " //SQL資料庫伺服器連接埠
#define SQLDBNAME " " //SQL資料庫伺服器資料庫名
#define SQLDBUSER " " //SQL資料庫伺服器資料庫使用者名稱
#define SQLDBPASSWD " " //SQL資料庫伺服器使用者密碼
#define SQLDBSERVER SQLDBIP":"SQLDBPORT
#define DBSQLCMD "select * from yancao"
int main(int argc, char *argv[])
{
    int i, ch;
    LOGINREC *login; //描述用戶端的結構體,在串連時被傳遞到伺服器.
    DBPROCESS *dbproc; //描述串連的結構體,被dbopen()函數返回
    RETCODE erc; //庫函數中最普遍的傳回型別.
/*************************************************************/
//在開始調用本庫函數前常常要先調用dbinit()函數
    if (dbinit() == FAIL) {
        fprintf(stderr, "%s:%d: dbinit() failed\n",argv[0], __LINE__);
        exit(1);
     }
//dblogin()函數申請 LOGINREC 結構體,此結構體被傳遞給dbopen()函數,用來建立一個串連。
//雖然基本上不會調用失敗,但是檢查它!.
    if ((login = dblogin()) == NULL) {
        fprintf(stderr, "%s:%d: unable to allocate login structure\n",argv[0],__LINE__);
        exit(1);
    }
//LOGINREC結構體不能被直接存取,要通過以下宏設定,下面設定兩個必不可少的域
    DBSETLUSER(login, SQLDBUSER);
    DBSETLPWD(login, SQLDBPASSWD);
/*************************************************************/
//dbopen()與伺服器建立一個串連. 傳遞 LOGINREC 指標和伺服器名字
     if ((dbproc = dbopen(login, SQLDBSERVER)) == NULL) {
        fprintf(stderr, "%s:%d: unable to connect to %s as %s\n",
 argv[0], __LINE__,
        SQLDBSERVER, SQLDBUSER);
        exit(1);
    }
// 可以調用dbuser()函數選擇我們使用的資料庫名,可以省略,省略後使用使用者預設資料庫.
     if (SQLDBNAME && (erc = dbuse(dbproc, SQLDBNAME)) == FAIL) {
        fprintf(stderr, "%s:%d: unable to use to database %s\n",
argv[0], __LINE__, SQLDBNAME);
         exit(1);
     }
/*************************************************************/
    dbcmd(dbproc, DBSQLCMD);//將SQL語句填充到命令緩衝區
     printf("\n");
    if ((erc = dbsqlexec(dbproc)) == FAIL) {
        fprintf(stderr, "%s:%d: dbsqlexec() failed\n", argv[0], __LINE__);
        exit(1); //等待伺服器執行SQL語句,等待時間取決於查詢的複雜度。
    }
/*************************************************************/
//在調用dbsqlexec()、dbsqlok()、dbrpcsend()返回成功之後調用dbresults()函數
    printf("then fetch results:\n");
    int count = 0;
    while ((erc = dbresults(dbproc)) != NO_MORE_RESULTS) {
        struct col { //儲存列的所有資訊
        char *name; //列名字
        char *buffer; //存放列資料指標
        int type, size, status;
    } *columns, *pcol;
    int ncols;
    int row_code;
    if (erc == FAIL) {
        fprintf(stderr, "%s:%d: dbresults failed\n",
argv[0], __LINE__);
        exit(1);
     }
    ncols = dbnumcols(dbproc);//返回執行結果的列數目
    if ((columns = calloc(ncols, sizeof(struct col))) == NULL) {
        perror(NULL);
        exit(1);
     }
 /* read metadata and bind. */
    for (pcol = columns; pcol - columns < ncols; pcol++) {
        int c = pcol - columns + 1;
         pcol->name = dbcolname(dbproc, c); //返回指定列的列名
        pcol->type = dbcoltype(dbproc, c);
        pcol->size = dbcollen(dbproc, c);
         printf("%*s(%d)", 20, pcol->name, pcol->size);
        if ((pcol->buffer = calloc(1, 20)) == NULL) {
        perror(NULL);
         exit(1);
    }
    erc = dbbind(dbproc, c, NTBSTRINGBIND, 20, (BYTE*)pcol->buffer);
    if (erc == FAIL) {
        fprintf(stderr, "%s:%d: dbbind(%d) failed\n",
argv[0], __LINE__, c);
        exit(1);
    }
    erc = dbnullbind(dbproc, c, &pcol->status); //(5)
     if (erc == FAIL) {
        fprintf(stderr, "%s:%d: dbnullbind(%d) failed\n",
argv[0], __LINE__, c);
        exit(1);
    }
 }
    printf("\n");
/* 列印資料 */
    while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {//讀取行資料
    switch (row_code) {
    case REG_ROW:
     for (pcol=columns; pcol - columns < ncols; pcol++) {
    char *buffer = pcol->status == -1?
"null" : pcol->buffer;
    printf("%*s ", 20, buffer);
    }
    printf("\n"); break;
    case BUF_FULL: break;
    case FAIL:
     fprintf(stderr, "%s:%d: dbresults failed\n",
     argv[0], __LINE__);
exit(1); break;
 default: // (7)
 printf("data for computeid %d ignored\n", row_code);
}
 }
 /* free metadata and data buffers */
 for (pcol=columns; pcol - columns < ncols; pcol++) {
free(pcol->buffer);
}
 free(columns);
if (DBCOUNT(dbproc) > -1) /* 得到SQL語句影響的行數 */
fprintf(stderr, "%d rows affected\n", DBCOUNT(dbproc))
}
dbclose(dbproc);
dbexit();
}   

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.