SQL/C學習筆記 在C中嵌入SQL
公司最近有個項目,需要在Linux下訪問DB2數(shù)據(jù)庫,Linux在我機器上裝了好幾年了也沒碰過,郁悶。DB2
就只是聽說過,沒有見過。C倒是用過一段時間。于是打開百度,狗狗開搜。
于是找到一部分文章,從中找了一些代碼:短小,感覺適合入門。被我改了改,程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include <sqlca.h>
EXEC SQL INCLUDE SQLCA;
main()
{
EXEC SQL BEGIN DECLARE SECTION;
char firstname[130];
char userid[9];
char passwd[19];
EXEC SQL END DECLARE SECTION;
EXEC SQL CONNECT TO Test;
EXEC SQL SELECT SEALNAME INTO :firstname
FROM SEAL fetch first 1 row only;
printf( "First name = %s\n", firstname );
EXEC SQL CONNECT RESET;
return 0;
}
我就不解釋這段程序了,網(wǎng)上一搜解釋的都比我好。一會最后貼出原貼方便以后使用。
打開VC編輯環(huán)境,將代碼貼了進去。編譯。我考,一堆錯誤,說什么不認識EXEC ....,這是怎么回事啊
,難道是少包含了頭文件,趕快找啊。找了一堆,加上,外甥打燈籠-照舊(招舅)。TNND,再查。
好長時間過去了,怎么得有幾個小時吧,狗狗都累了。最后才明白,VC編譯器不能直接編譯這種代碼,(
我突然覺得怎么有點像ASP呢,混在一起)必須先使用預處理器將這些代碼轉換成c代碼,VC編譯環(huán)境才能
認。那怎么轉換呢?使用什么樣的預處理器呢?再查,忘了是從哪查到一個 DB2 prep *.sqc bindfile命
令,感覺上這個可以了,馬上運行cmd打開控制臺,輸入試,N次后我差點一屁股就坐地上了,前面帶了個
DB2,應該是在DB2的命令行下運行吧,于是在bin下找到了什么exe來著,就是命令行工具中的全集窗口。
打開,輸入,興奮啊。在我可愛的sqc文件旁邊出了個.c的文件,哈哈,就是他了。
或許是我高興的太早,或許是我運氣不好,該例子始終過不去,沒報什么錯
,NND。這是為啥?!難道我的SQL語句錯了?!在DB2的控制臺下再試,考,成功。再運行我的程序,還
是報這個錯。改程序,或許是我的Select 語句不行,我建個表試試不取數(shù)據(jù)總行吧。于是有了如下的代
碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include <sqlca.h>
EXEC SQL INCLUDE SQLCA;
#define CHECKERR(CE_STR) if (check_error (CE_STR, &sqlca) != 0) return 1;
int check_error (char eString[], struct sqlca *caPointer)
{
char eBuffer[1024];
char sBuffer[1024];
short rc, Erc;
if (caPointer->sqlcode != 0)
{
printf ("--- error report ---\n");
printf ("ERROR occured : %s.\nSQLCODE : %ld\n", eString,
caPointer->sqlcode);
}
return 0;
}
int main(int argc, char *argv[])
{
EXEC SQL BEGIN DECLARE SECTION;
char firstname[13];
char userid[9];
char passwd[19];
EXEC SQL END DECLARE SECTION;
printf( "Sample C program: STATIC\n" );
if (argc == 1)
{
EXEC SQL CONNECT TO test user test using hdshtest;
CHECKERR ("CONNECT TO SAMPLE");
}
else if (argc == 3)
{
strcpy (userid, argv[1]);
strcpy (passwd, argv[2]);
EXEC SQL CONNECT TO test USER :userid USING :passwd;
CHECKERR ("CONNECT TO SAMPLE");
}
else
{
printf ("\nUSAGE: static [userid passwd]\n\n");
return 1;
} /* endif */
// create table
EXEC SQL CREATE TABLE tbname(col1 SMALLINT,
col2 CHAR(7),
col3 VARCHAR(7),
col4 DEC(9, 2),
col5 DATE,
col6 BLOB(5000),
col7 CLOB(5000));
CHECKERR("Table -- Create");
EXEC SQL COMMIT;
CHECKERR("Transaction -- Commit");
/*
EXEC SQL SELECT account.moneytype INTO :firstname FROM test.account fetch first
1 row only;
*/
EXEC SQL SELECT name INTO :firstname FROM accounttype where id = '1';
CHECKERR ("SELECT statement");
printf( "First name = %s\n", firstname );
EXEC SQL CONNECT RESET;
CHECKERR ("CONNECT RESET");
return 0;
}
/* end of program : STATIC.SQC */
重復上述步驟,重新生成了.C的文件,還是出不了我要的結果,但是我加上出錯處理了, 先看看出錯信
息,出錯信息如下:
sqlcode: -805
sqlstate: 51002
這是什么東西?再搜。我可是在百度上搜了N分鐘啊。大多是java的,看不懂。老天不負我有心人吶,最
終找到了解釋:
請問db2的這個錯誤是什么意思?
DB2 SQL error: SQLCODE: -805, SQLSTATE: , SQLERRMC: NULLID.SYSSH200
回答:
解釋: 此信息 (SQLCODE) 的可能原因是:
o 未在數(shù)據(jù)庫中定義指定的程序包或程序。
o 未聯(lián)編該程序或它已被卸下。
o 正在運行的應用程序未與數(shù)據(jù)庫聯(lián)編。
o 若試圖運行 DB2 實用程序或 CLI 應用程序, 則 DB2
實用程序可能需要重新聯(lián)編至數(shù)據(jù)庫。
不能處理該語句。
用戶響應:
指定正確的程序包名或聯(lián)編該程序。若正在運行的應用程序未與數(shù)據(jù)庫聯(lián)編
,則與數(shù)據(jù)庫管理員聯(lián)系以執(zhí)行必需的聯(lián)編。
若 DB2
實用程序需要重新聯(lián)編至數(shù)據(jù)庫,則當連接至數(shù)據(jù)庫時,數(shù)據(jù)庫管理員可以
通過從實例的 bnd 子目錄發(fā)出下列 CLP 命令之一來完成此操作:
o 對于 DB2 實用程序,發(fā)出 "DB2 bind @db2ubind.lst blocking all
grant public"。
o 對于 CLI,發(fā)出 "DB2 bind @db2cli.lst blocking all grant
public"。
聯(lián)合體系統(tǒng)用戶:確保在適用的數(shù)據(jù)源上聯(lián)編 聯(lián)合體服務器
所必需的程序包。參考“安裝和配置補遺”指南以獲取有關將程序包與數(shù)據(jù)
源聯(lián)編的詳情。
sqlcode: -805
sqlstate: 51002
當真是遇上救星了?于是乎,我將剛才搜到的信息總結了一下,三句話:
如果您打完補丁10后,您需要對每一個數(shù)據(jù)庫執(zhí)行
db2 terminate
db2 CONNECT TO <dbname>
db2 BIND <path>/db2schema.bnd BLOCKING ALL GRANT PUBLIC sqlerror continue
db2 terminate
DB2 bind @db2ubind.lst blocking all grant public
DB2 bind @db2cli.lst blocking all grant public
bind "C:\Program Files\IBM\SQLLIB\BINtestmain.bnd" BLOCKING ALL GRANT PUBLIC sqlerror
continue
如上在DB2后輸入的上述命令,我暈,程序還是不對。不能出來正確結果。今天注定我一晚上睡不好嗎?
就是我要失去信心的時候,發(fā)現(xiàn)了在我的.c的旁邊一直躲著個.bnd的文件???,再bind一次這個家伙。哈哈哈,我要的結果出來了!爽,痛快,寫下來,省得過幾天忘了,有做這方面的朋友也可以少走些彎路,呵呵。