【C語言】使用ODBC串連Microsoft SQL server資料庫

來源:互聯網
上載者:User

因為最近要用C對SQL Server進行串連,但發現網上關於這方面的資料不多,就把這兩天查到的資料和心得歸攏了下,留著以後自己看。

使用C語言通過ODBC(開放式資料庫互連)對SQL Server進行串連,分為兩步操作:1.配置本地ODBC環境;2.碼代碼...=_=

【首先配置本地環境】
1.啟動SQLSERVER服務,例如:HNHJ,開始菜單 ->運行 ->net start mssqlserver


2.更改SQL server登入方式為SQL Server身分識別驗證登陸。

步驟:進入你的資料庫->在伺服器上右鍵->屬性->安全性->SQL Server和Windows身分識別驗證模式->點確定。


3.開啟企業管理器,建立資料庫,並在資料庫中建立一張表。

我的資料庫名字是CCCS,建立city表

4.建立系統DSN,開始菜單 ->運行 ->odbcad32

點擊添加->SQL Server->資料來源名稱(自己起個名字記住,一會有用,我的是CCCS)->選擇SQL Server伺服器(選取本機名稱,不要選local)->使用使用者使用登入ID和密碼的SQL Server驗證->登入ID:sa,密碼:(為空白)->更改預設的資料庫為:CCCS->測試資料來源,測試成功,即DNS添加成功。

【C語言 關鍵函數】

1.SQLBindCol()函數具有六個參數,分別是

SQLRETURN SQLBindCol(SQLHSTMT            StatementHandle,SQLUSMALLINT     ColumnNumber,SQLSMALLINT       TargetType,SQLPOINTER        TargetValuePtr,SQLINTEGER        BufferLength,SQLLEN *              StrLen_or_Ind);

其中第一個參數是控制代碼,第二個參數是目標表中的列數(unsigned short),第三個是目標類型,第四個是儲存資料庫反饋資訊(城市,緯度等)的字串變數,第五個是第四個參數的長度(推薦使用strlen(string)測長度),第六個是啥玩意的緩衝區,為0即可。

2.SQLExecDirect()函數具有三個參數,分別是

SQLRETURN SQLExecDirect(     SQLHSTMT     StatementHandle,     SQLCHAR *    StatementText,     SQLINTEGER   TextLength);

其中第一個參數是控制代碼,第二個參數是儲存送給資料庫的SQL語句的字串變數,第三個函數是第二個參數的長度(推薦使用strlen(string)測長度)。

【原始碼】

標頭檔functions.h附在主代碼CCCS-insert.cpp和CCCS-select.cpp之後

【CCCS-insert.cpp】

#include "functions.h"SQLHENV henv = SQL_NULL_HENV;     SQLHDBC hdbc1 = SQL_NULL_HDBC;     SQLHSTMT hstmt1 = SQL_NULL_HSTMT; /* cpp檔案功能說明: 1.資料庫操作中的添加,修改,刪除,主要體現在SQL語句上 2.採用直接執行方式和參數先行編譯執行方式兩種 */  int main(){     RETCODE retcode;     UCHAR   szDSN[SQL_MAX_DSN_LENGTH+1]   =   "CCCS";     //資料庫名UCHARszUID[MAXNAME]   =   "sa";//使用者名稱UCHARszAuthStr[MAXNAME]   =   "";           //密碼charsql[60] = "\0";                        //插入時是用的sql語句的存放變數 charsqlh1[26] = "insert into city values('"; //拼合字串charsqlh2[4] = "','";charsqlh3[3] = "')";//UCHAR   pre_sql[31] = "insert into city values(?,?,?)"; //先行編譯SQL語句  CityMsg * citymsg;//城市資訊//SQL語句  //1.串連資料來源  //1.環境控制代碼  retcode   =   SQLAllocHandle   (SQL_HANDLE_ENV,   NULL,   &henv);     retcode   =   SQLSetEnvAttr(henv,   SQL_ATTR_ODBC_VERSION,     (SQLPOINTER)SQL_OV_ODBC3,     SQL_IS_INTEGER);     //2.串連控制代碼    retcode   =   SQLAllocHandle(SQL_HANDLE_DBC,   henv,   &hdbc1);     retcode   =   SQLConnect(hdbc1,   szDSN,   4,   szUID,   2,   szAuthStr,   0);  //判斷串連是否成功  if ( (retcode   !=   SQL_SUCCESS)   &&   (retcode   !=   SQL_SUCCESS_WITH_INFO)   )   {       printf("串連失敗!\n");  }   else   {     //2.建立並執行一條或多條SQL語句  /* 1.分配一個語句控制代碼(statement handle) 2.建立SQL語句 3.執行語句 4.銷毀語句 */  retcode   =   SQLAllocHandle(SQL_HANDLE_STMT,   hdbc1,   &hstmt1);     //第一種方式  //直接執行  //添加操作//開啟檔案citymsg = getCityMsg();citymsg = citymsg->next;while(citymsg->next != NULL){//拼合字串strcpy(sql,sqlh1);strcat(sql,citymsg->city);strcat(sql,sqlh2);strcat(sql,citymsg->lat);strcat(sql,sqlh2);strcat(sql,citymsg->lon);strcat(sql,sqlh3);//執行sql語句//SQLExecDirect (hstmt1,(UCHAR *)sql,50); //測試switch( SQLExecDirect (hstmt1,(UCHAR *)sql,strlen(sql))) { case SQL_SUCCESS_WITH_INFO: { printf("SQL_SUCCESS_WITH_INFO\n");break;} case SQL_SUCCESS: { printf("SQL_SUCCESS\n"); break;   }  case SQL_ERROR: {printf("SQL_ERROR\n"); break; } default: printf("else Return\n"); } //測試結束printf("%s\n",sql);//test//重新初始化sql語句存放變數strcpy(sql,sqlh1);//鏈表指向下一節點citymsg = citymsg->next;}//第二種方式  //綁定參數方式  /*char a[200]="bbb";  char b[200]="200";  char c[200]="200";SQLINTEGER   p   =   SQL_NTS;  //1先行編譯  SQLPrepare(hstmt1,pre_sql,31); //第三個參數與數組大小相同,而不是資料庫列相同  //2綁定參數值  SQLBindParameter(hstmt1,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,200,0,&a,0,&p);  SQLBindParameter(hstmt1,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,200,0,&b,0,&p);  SQLBindParameter(hstmt1,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,200,0,&c,0,&p); //3 執行  SQLExecute(hstmt1);*/  printf("操作成功!");  //釋放語句控制代碼  SQLCloseCursor (hstmt1);  SQLFreeHandle (SQL_HANDLE_STMT, hstmt1);  }     //3.斷開資料來源  /* 1.斷開與資料來源的串連. 2.釋放串連控制代碼. 3.釋放環境控制代碼 (如果不再需要在這個環境中作更多串連) */  SQLDisconnect(hdbc1);      SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);     SQLFreeHandle(SQL_HANDLE_ENV, henv);     getchar();return 0;     }     

【CCCS-select.cpp】

/*China City Coord SystemSELECT*/#include "functions.h"//定義查詢方式宏#defineSELECT_ALL0#defineSELECT_CITYStill_Unsigned_Yet>_<|||#defineSELECT_LAT_EXACT1#defineSELECT_LAT_SCOPE2SQLHENV henv = SQL_NULL_HENV;   SQLHDBC hdbc1 = SQL_NULL_HDBC;   SQLHSTMT hstmt1 = SQL_NULL_HSTMT;   /******************************************************全 部 查 詢 *******************************************************/void selectAll(RETCODE retcode,char * sql,char * sqlh1,char * initialize){/*1.確認一個結果集是否可用。2.將結果集的資料行繫結在適當的變數上。3.取得行*/CityMsg citymsg;getchar();//儲存在choose介面的斷行符號字元,防止第一次翻頁之前輸出兩倍的行數strcpy(sql,sqlh1);//拼合sql語句字串SQLExecDirect (hstmt1,(UCHAR *)sql,strlen(sql));//對資料庫發送select all語句//SQLBindCol(hstmt1, 1, SQL_C_CHAR, list, 5, 0);//該函數對資料庫發送語句SQLBindCol(hstmt1, 1, SQL_C_CHAR, citymsg.city, 10, 0);//該函數是資料庫的反饋資訊函數SQLBindCol(hstmt1, 2, SQL_C_CHAR, citymsg.lon, 11, 0);//第二個參數是目標表中的列號SQLBindCol(hstmt1, 3, SQL_C_CHAR, citymsg.lat, 11, 0);//第五個參數是傳回的字串長度do{retcode = SQLFetch(hstmt1);if(retcode == SQL_NO_DATA){break;}printf("%s%s%s\n",citymsg.city, citymsg.lon, citymsg.lat);static int n=1;//翻頁計數器n++;if(n%20 == 0)//每頁20行{printf("\n【第%d頁】",n/20);//頁碼getchar();//按斷行符號換頁}}while(1);strcpy(sql,initialize);//重新初始化字串getchar();//結束標誌,按一下斷行符號}/******************************************************緯 度 精 確 查 詢 *******************************************************/void selectByLat(char * sqlh1,char * sql,char * initialize){char sqlh5[10]="\0";CityMsg citymsg;getchar();printf("輸入要查詢的緯度:\n");printf("例如:34.17\n");printf("北緯");gets(sqlh5);strcpy(sql,sqlh1);strcat(sql,"where latitude='北緯");strcat(sql,sqlh5);strcat(sql,"'");puts(sql);//顯示向資料庫發送的sql語句SQLExecDirect (hstmt1,(UCHAR *)sql,strlen(sql));SQLBindCol(hstmt1, 1, SQL_C_CHAR, citymsg.city, 10, 0);//該函數是資料庫的反饋資訊函數SQLBindCol(hstmt1, 2, SQL_C_CHAR, citymsg.lon, 11, 0);//第二個參數是目標表中的列號SQLBindCol(hstmt1, 3, SQL_C_CHAR, citymsg.lat, 11, 0);//第五個參數是傳回的字串長度SQLFetch(hstmt1);printf("%s%s%s\n",citymsg.city, citymsg.lon, citymsg.lat);strcpy(sql,initialize);//重新初始化字串getchar();//結束標誌,按一下斷行符號}/*查詢SQLSERVER資料庫,1.條件查詢,2.直接查詢全部*/int main(){       RETCODE retcode;     UCHAR   szDSN[SQL_MAX_DSN_LENGTH+1]   =   "CCCS";     //資料庫名UCHARszUID[MAXNAME]   =   "sa";//使用者名稱UCHARszAuthStr[MAXNAME]   =   "";//密碼charsql[57] = "\0";//插入時是用的sql語句的存放變數 charinitialize[2] = "\0";//初始設定變數charsqlh1[20] = "select * from city ";//拼合字串retcode   =   SQLAllocHandle   (SQL_HANDLE_ENV,   NULL,   &henv);   retcode   =   SQLSetEnvAttr(henv,   SQL_ATTR_ODBC_VERSION,     (SQLPOINTER)SQL_OV_ODBC3,     SQL_IS_INTEGER);    retcode   =   SQLAllocHandle(SQL_HANDLE_DBC,   henv,   &hdbc1);   //1.串連資料來源retcode   =   SQLConnect(hdbc1,   szDSN,   4,   szUID,   2,   szAuthStr,   0);    if   (   (retcode   !=   SQL_SUCCESS)   &&   (retcode   !=   SQL_SUCCESS_WITH_INFO)   )   {   printf("串連失敗!");}   else   {   //2.建立並執行一條或多條SQL語句/*1.分配一個語句控制代碼(statement handle)2.建立SQL語句3.執行語句4.銷毀語句*/retcode   =   SQLAllocHandle(SQL_HANDLE_STMT,   hdbc1,   &hstmt1);   //第一種方式/*//直接執行SQLExecDirect (hstmt1,(UCHAR *)sql,strlen(sql));char list[5];SQLBindCol(hstmt1, 1, SQL_C_CHAR, list, 5, 0);SQLFetch(hstmt1);printf("%s\n",list);*///第二種方式/*//綁定參數方式char a[200]="aaa";SQLINTEGER   p   =   SQL_NTS;//1.先行編譯SQLPrepare(hstmt1,sql2,35); //第三個參數與數組大小相同,而不是資料庫列相同//2.綁定參數值SQLBindParameter(hstmt1,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,200,0,&a,0,&p);//3.執行SQLExecute(hstmt1);char list[5];SQLBindCol(hstmt1, 1, SQL_C_CHAR, list, 5, 0);SQLFetch(hstmt1);printf("%s\n",list);*/int choose;//使用者選擇序號的儲存變數while(1){printf("輸入查詢方式:\n");printf("0.全部查詢\n");printf("1.緯度精確查詢\n");printf("2.緯度區間查詢\n");printf("\n");scanf("%d",&choose);switch(choose){case SELECT_ALL:{//全部輸出selectAll(retcode, sql, sqlh1, initialize);break;}case SELECT_LAT_EXACT:{//通過具體緯度尋找selectByLat(sqlh1,sql,initialize);break;}case SELECT_LAT_SCOPE:{//通過緯度區間尋找}}}//釋放語句控制代碼SQLCloseCursor (hstmt1);SQLFreeHandle (SQL_HANDLE_STMT, hstmt1);}    //4.斷開資料來源/*         1.斷開與資料來源的串連. 2.釋放串連控制代碼. 3.釋放環境控制代碼 (如果不再需要在這個環境中作更多串連)    */SQLDisconnect(hdbc1);    SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);   SQLFreeHandle(SQL_HANDLE_ENV, henv);   getchar();getchar();return(0);   }


【標頭檔functions.h】

#include <stdio.h>     #include <string.h>     #include <windows.h>     #include <sql.h>     #include <sqlext.h>     #include <sqltypes.h>     #include <odbcss.h> //存放城市及座標的結構體typedef struct CityMsg{charcity[50];//城市citycharlon[50];//經度longitudecharlat[50];//緯度latitudestruct CityMsg*next;//下一節點}CityMsg;//函式宣告CityMsg * nextNood(CityMsg * );//構建鏈表 函數CityMsg * getCityMsg();//擷取城市及座標 函數//構建鏈表CityMsg * nextNood(CityMsg * oldCM){//尾插法CityMsg * newCM;newCM = (CityMsg *)malloc(sizeof(CityMsg));//為新節點開闢空間newCM->next = NULL;//初始化新節點oldCM->next = newCM;return newCM;//返回新節點}//擷取城市及座標CityMsg * getCityMsg(){CityMsg * head,//頭指標 * citymsg;//存放城市及座標的結構體FILE *fp;//檔案指標->存放城市及座標的檔案head = (CityMsg *)malloc(sizeof(CityMsg));//為頭指標開闢空間citymsg = (CityMsg *)malloc(sizeof(CityMsg));//為首節點開闢空間head->next = citymsg;//初始化頭指標citymsg->next = NULL;//初始化首節點fp = fopen("CityCoord.txt","rt");//嘗試開啟檔案if(fp == NULL){//若打不開,反饋資訊並退出printf("Cannot Open This File,Press Any Key to Exit.\n");getchar();exit(1);}while(!feof(fp)){//迴圈讀取城市及座標資訊,直到檔案末尾fscanf(fp,"%s %s %s",citymsg->city,citymsg->lon,citymsg->lat);//讀入城市及座標citymsg = nextNood(citymsg);//開闢並指向下一節點}return head;}

【參考資料】

C語言與SQL SERVER資料庫

如何更改SQL Server 2008 登陸驗證方式

SQLExecDirect Function - SQL Server msdn

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.