oracleproc編程Oracle系列參考教程ProC程序開發(fā)_第1頁
oracleproc編程Oracle系列參考教程ProC程序開發(fā)_第2頁
oracleproc編程Oracle系列參考教程ProC程序開發(fā)_第3頁
oracleproc編程Oracle系列參考教程ProC程序開發(fā)_第4頁
oracleproc編程Oracle系列參考教程ProC程序開發(fā)_第5頁
已閱讀5頁,還剩160頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領

文檔簡介

前 讀者范 內(nèi)容組 約 ORACIE9IRELEASE2(9.2)新特 ORACLE9IRELEASE1(9.0.1)新特 Oracle8iReleasee8.1.5新特 ORACLE8IRELEASE8.1.4新特 ORACLE8IRELEASE8.1.3新特 概 樣例 樣例程 宿主變 指示變 通用 指針變 靜態(tài) 滾動游 優(yōu)化提 游標控 METHOD METHOD METHOD METHOD 得到宿主變量值并分配空 打開游 釋放資 關閉游 METHOD4實現(xiàn)sqlplus命令的例 METHOD4滾動游標的例 GET SET Useof DESCRIBE UseofEXECUTE UseofDYNAMICDECLARE OPEN CLOSEaDynamic 樣例程 附 參考文 SQLSQL語句書寫方法和含義Oracle※Oracle首先,本資料為內(nèi)部培訓,不是,在整個文檔中不會對C語言及其而不遵循ANSISQL的規(guī)定。為了描述方便,書中范例采用SQLC語言編寫。Pro*C/C++語言就是在標準C/C++語言中通過嵌入SQL語句完成對數(shù)據(jù)庫操作的一種c/c++編譯器編譯成可執(zhí)行程序。在以后的章節(jié)中將多次涉及到預編譯器(預編譯程序Pro*C預編譯程序${ORACLE_HOME}/bin/proc。 語言變量同 要注意用戶表盡量不要建立在大寫定寬小寫定寬 while(1)} 包含在此描述符號中的內(nèi)容為可選包含在此描述符號中的內(nèi)容為可選|…SELECTcol1,col2,...,coln.SQL>SELECTNAMEFROM.....9rows本文所涉及樣例程序在編譯時需要替換掉筆者試驗用的數(shù)據(jù)庫用戶名和Oracie9iRelease29.2)Pro*C/C++Pro*C/C++Oracle9iRelease19.0.1)※UNICODEV8OCIXA編程中通過XA連接到Oracle,在SQLLIB中,然后通過V8OCI中的函數(shù)SQLEnvGet和SQLSvcCtxGet獲得已經(jīng)建立和使用的連接。Oracle8iReleasee8.1.5※Oracle從此版本起,Oracle允許用預編譯器直接編譯頭文件(.h),將其生成一個二進制文件,在真正對程序進行編譯時,Oracle可直接使用此文件而不是重新編譯所有Oracle8iRelease8.1.4Oracle8iRelease8.1.3SQLLOB語句接口的功能。標準動態(tài)SQL語句接口支持所有Oracle的數(shù)據(jù)類型,包括Objects,結(jié)構(gòu)數(shù)組,游標變量和LOBS。※DML語句開始支持返回(returning)ROWIDPro*C/C++ALLOCATE和ROWID類型,所分配描述符號支持物理ROWID和邏輯ROWID※擴展過程支Pre-fetchingOracleCSQL語句轉(zhuǎn)換成高后可應用操作系統(tǒng)的編譯器將其編譯成可執(zhí)行的Oracle應用程序。下圖展示了一個SQLCHECK=FULL選項,預編譯程序可以檢查在程序中嵌入SQL的正確性,包括出現(xiàn)在源代碼中的數(shù)據(jù)庫表、字段的檢查,將程序出錯機率其可以在Oraclesqlplus工具中直接使用,也可以嵌入到c/c++語言中,做為Pro*C/C++PL/SQL的主要目的是為了提高應用程序的執(zhí)行效率。同單SQLPro*c/C++PL/SQL塊可以看作一組包含特定邏輯功能這就減少了網(wǎng)絡和Oracle進行SQL解析的時間,從而提高了程序處理的性能。SQLSQL語句的(proc)支持很多可選選項,能在編譯過程中靈活調(diào)整,加快應用程SQL通訊區(qū)域(SQLCA)WHENEVERDO語句的結(jié)合,可更簡單的捕獲和LOBs※支持數(shù)據(jù)庫的多國國際語言設置和OCI(OracleCallInterface)編譯和應用程序是個很平臺化的工作,在本文中以UNIX為例子,首先需要保證操作系統(tǒng)級別的C/C++編譯器可用,然后正確的安裝Oracle數(shù)據(jù)庫服務器和proc #設定Oracle #設定Oracle procprociname=foo.pccc- 但對于復雜的工程項目用這種方式進行編譯將非常效率低下,建議采寫 includePROCPPFLAGS= lines=ture.SUFFIXES:.o.c@$(CC) -c@$(CC)$(CFLAGS) -c$(<:.pc=.c)OBJ=foo1.ofool2.ofool3.ofoo:$(OBJ)@rm-f*.lis@make對本文中所提到的所有范例程序只需改動OBJ=foo1.ofool2.ofool3.o內(nèi)容及其以后兩unix系統(tǒng)命令makefoo–fMakefilemakeall–fMakefile既編譯出所需要的應用程序。 2個字節(jié)的代表字符長度的變量,n個字符的字符數(shù)組。OracleAPIOracleSQLLIB的函數(shù)調(diào)用OracleCallInterface(OCI)C語言的編程處SELECT*FROMempWHERESELECT*FROMempWHEREmallocmalloc都是在運行時通過變量分配長在這種情況下,Oraclestrlen()函數(shù)所得到的值,所以在應我可以在任意版本的Oracle中使用任意版本的預編在舊版本數(shù)據(jù)庫服務器中使用新版本的Pro*C/C++編譯程序。3.6.121405錯誤(Fetchcolumnvaluesisnull)應用場合為Oracle數(shù)據(jù)庫服務端,這樣的Pro*C/C++應用程序又稱為主機應用程序。Oracle相關SETPro*C/C++C/C++SQL語句,并通語句前加入“EXECSQLSQL語句后面用分號“;”作為結(jié)尾既可。C語言量既可。Pro*C/C++預處理程序?qū)㈩A編譯這些語句為SQLLIB對應調(diào)用的C/C++語句SELECTnameFROMempWHERE值賦給一個c語言變量sName,則在程序中書寫樣式如下:EXECSQLSELECTnameINTO:sNameFROMempWHERESQL,也就是在編程SQL語法、語句,知道了數(shù)據(jù)庫中數(shù)據(jù)的變更方式,決定了數(shù)據(jù)庫中列值SQL宿主變量不能應用到表名、列名等位置,故提出了動態(tài)SQL的需求。Oracle支持動態(tài)SQL,其執(zhí)行過程的效率和可操作性。SQLPro*C/C++編程中一種高級編程技術,其基于數(shù)據(jù)類型轉(zhuǎn)換在運行時完成SQL語句的建立和執(zhí)行。入單條SQL語句的地方,都可以嵌入PL/SQL語句塊。鍵字開始到END-EXEC關鍵字結(jié)束。宿主變量是在C/C++語言中的變量,用于同Oracle數(shù)據(jù)庫進行數(shù)據(jù)交互。輸入變SQL語句通過在結(jié)構(gòu)變量前加入冒號“:”符號,Pro*C/C++Oracle進行SQLNULL狀態(tài)、被數(shù)據(jù)庫為sName,指示變量為sIntName,則用法如下:通常Pro*C/C++應用程序是為了數(shù)據(jù)到Oracle數(shù)據(jù)庫或從Oracle數(shù)據(jù)庫數(shù)據(jù)儲和檢索工作,這就引入了Oracle的數(shù)據(jù)類型。Oracle能識別兩種類型的數(shù)據(jù)類型:內(nèi)置類型和外部類型。內(nèi)置數(shù)據(jù)類型直接標明了Oracle按照何種方式列數(shù)據(jù),Oracle也使用內(nèi)部數(shù)據(jù)類型作為特殊值向應用程序的傳外部數(shù)據(jù)類型描述了宿主變量數(shù)據(jù)的類型和方式。當應用程序通過INPUT變量向OracleOracle會將按照外部類型的定義方式,將宿主變量的Pro*C/C++允許用戶定義宿主數(shù)組變量(hostarrays)SQLSELECT、FETCH、DELETE、INSERTUPDATE語句中使用宿主數(shù)組自定義數(shù)據(jù)類型,則必須在Proc*C/C++代碼中定義轉(zhuǎn)換規(guī)則。area)。在這個Area中著執(zhí)行這條SQL語句所需的信息。用戶可以采用cursor指示符通過此區(qū)域得到這條SQL語句的相關信息和控制其執(zhí)行過程。(acvee)SQL移動游標過程中(ETH),在未到達記錄集頭尾時每次指向當前記錄集的記錄有且只有一條。OracleSQLROLLBACKSQL語句單元執(zhí)行失敗情況下,SQLSAVEPOINT允許將事務進行分塊管理,以方便部分成功數(shù)據(jù)的提交和部分SQL語句執(zhí)行后,Oracle肯定會返回此語句的執(zhí)行結(jié)果,成功或是失敗,也可能執(zhí)行成功但包含警告。Pro*C/C++SQL語句的執(zhí)行結(jié)果,一種是WHENEVER語句,另一種是通過OracleSQLCommunicationsArea(SQLCA)。EXECSQLINCLUDE或#includeEXECSQLINCLUDE或#include修改可以在嵌入SQL語句的任何空白位置使用C語言風格的注釋(/*…*/),但在關鍵字EXECSQLSQLANSI-SQL風格的注釋(--…)注釋掉從符號“--”后面的語句。INTO:emp_name,:salary--outputhostvariablesFROMEMPWHEREDEPTNO=量前添加0x或0X表明該常量為一個十六進制的常數(shù)。Char*uid=”xcl/xclxcl”;… EXECSQLDECLAREEXECSQLINCLUDEEXECSQLVAREXECSQLTYPEEXECORACLEauto,char,const,double,enum,extern,float,int,long,ulong_varchar,OCIBFileLocatorOCIBlobLocator,OCIRowid,OCIDate,OCINumber,OCIRaw,OCIString,register,short,signed,sql_context,sql_cursor,static,struct,typedef,union,unsigned,utext,uvarchar,varchar,void,volatile,atypedefname,a piledheader,execoracle,execoraclebegin,exec,execsql,execsqlbegin,execsqlend,execsqltype,execsqlvar,execsql當預編譯軟件proc的參數(shù)設置有如下值設定時,變量必須在變量段中,而不能在SQL語句中直接使用C語言中的變量。CODE=CPPC++應用程序OracleSQL中使用單引號作為字符串限定字符,標識了字符串的開始和結(jié)尾(C語言EXECSQLSELECTenameFROMempWHERE常用于定界數(shù)據(jù)庫sengmet名稱,例如:EXECSQLSELECTempnoFROM或EXECSQLSELECTempnoFROMEXECSQLSELECTempnoFROM標準C語言需要在使用函數(shù)前對函數(shù)原型進行,函數(shù)指明了函數(shù)參數(shù)個數(shù)、Pro*C/C++預編譯工具proc令行參數(shù)CODE可指定Pro*C/C++所生成的C/C++語言代碼符合何種C/C++語言規(guī)范,其取值如下:externvoidsqlora(long*,voidKR是("KernighanandRitchie")的縮寫,用此參數(shù)所產(chǎn)生的函數(shù)中函數(shù)的參數(shù)將被注釋掉,其他同ANSI_C一致。externvoidsqlora(/*_long*,void*C31,請參考其手冊,宿主變量名長度以二者Pro*C/C++SQL語句可以在一行較長時換行到下一行繼續(xù)書寫,除非上EXECSQLINSERTINTOdept(deptno,dname)VALUES(50,’PURCHAS\Pro*C/C++1299ASCII324個Pro*C/C++預編譯工具proc命令行參數(shù)MAXLIL指定了其預編譯成C/C++語言源CSQL語句中的邏輯操作符是不同的,C語言的邏輯運算操作符不能用于SQL語句中。列表區(qū)分如下:!=&&,|,^,*3EXECSQLDELETEFROMempWHEREdeptno=:dept_number --EXECORACLEIFDEFsymbol; --如果這個符號被定義了EXECORACLEIFNDEFsymbol; --如果這個符號沒有定義EXECORACLEELSE; --否則EXECORACLE --則刪除AUP表數(shù)據(jù),否則刪除表ADOWN,則部分源代碼如下:EXECORACLEIFDEFEXECSQLDELETEFROMAUP;EXECORACLEELSE;EXECSQLDELETEFROMADOWN;EXECORACLEENDIF;C/C++源代碼尺寸,并且邏輯清楚, 對應的記錄信息,并回顯給用戶,然后繼續(xù)循環(huán),等待用戶輸入下個empno。個結(jié)構(gòu)類型的指示變量顯示對應宿主變量是否存在NULL值。@file:@brief:TestPro*C@file:@brief:TestPro*Cprogramsample1@build:makes1–f#include<stdio.h>/*定義Oracle數(shù)據(jù)庫用戶名長度和 長度*/#defineUNAME_LEN20#definePWD_LEN/*如果MODE=ORACLE,則定義變量不需要BEGINDECLARESECTION…等*/VARCHARusername[UNAME_LEN];/* /*VARCHAR是一個Oracle支持的結(jié)構(gòu)類型,可以用小寫書寫*/varcharpassword[PWD_LEN]; struct{floatsalary;float}{shortemp_name_ind; shortsal_ind;short}intemp_number;int/*包含上SQLCA,可用#includeEXECSQLINCLUDEsqlca*/#include<sqlca.h> voidsql_error();{char strncpy((char*)username.arr,"xcl",UNAME_LEN);username.len=strlen((char*)username.arr);strncpy((char*)password.arr,"xclxcl",PWD_LEN);password.len=strlen((char*)password.arr); EXECSQLWHENEVERSQLERRORDOsql_error("ORACLEerror--EXECSQLCONNECT:usernameIDENTIFIEDBY:password;printf("\nConnectedtoORACLEasuser:%s\n",username.arr);total_queried=0;for(;;){EXECSQLWHENEVERNOTFOUNDDOfor{emp_number=printf("\nEnteremployeenumber(0toquit):");emp_number=atoi(temp_char);if(emp_number==0)EXECSQLSELECTename,sal,NVL(comm,0)INTO:emprecINDICATOR:emprec_indFROMEMPWHEREEMPNO=:emp_number;

emprec.emp_name.arr[emprec.emp_name.len]=printf("%-8s\t%6.2f\t\t",emprec.emp_name.arr,emprec.salary);if( m_ind==-1) }if(emp_number==0)printf("\nNotavalidemployeenumber-try}printf("\n\nTotalrowsreturnedwas%d.\n",total_queried);/*EXECSQLCOMMITWORK}}char*msg;{charerr_msg[128];intbuf_len,msg_len;EXECSQLWHENEVERSQLERRORprintf("\n%s\n",msg);buf_len=sizeof(err_msg);sqlglm(err_msg,&buf_len,&msg_len);printf("%.*s\n",msg_len,err_msg);EXECSQLROLLBACKRELEASE;}所在,在PROCPPFLAGS變量值后面加入:MODE=ORACLEall前面加入如下內(nèi)@$(CC)$(CFLAGS)$(S1_OBJ)-os1-L${ORACLE_HOME}/lib$(PROLDLIBS)-@rm-f*.lisUNIX指令:makes1s1,然后運行./s1即可。EXECSQLCONNECT{:userIDENTIFIEDBY:oldpswd|:usr_psw}[[AT{dbname|:host_variable}]USING:connect_string]user:存放Oracle用戶數(shù)據(jù)庫名常用的連接方法有兩種,一是將用戶名和存放在兩個宿主變量中,采用EXECSQLCONNECT:usernameIDENTIFIEDBY:passwordEXECSQLCONNECT也可以采用移植性不好的方式:直接在SQL語句中書寫用戶名和字符串,連接EXECSQLCONNECT‘xcl’IDENTIFIEDBYEXECSQLCONNECT可以利用ALTERAUTHORIZATION選項在數(shù)據(jù)連接時改變數(shù)據(jù)庫用戶,在改動成EXECSQLCONNECT‘xcl’IDENTIFIEDBY‘xclxcl’ALTERAUTHORIZATION‘xcl123’;是操作系統(tǒng)用戶名,CLUSTER$username是有效的數(shù)據(jù)庫用戶名,CLUSTER$Oraclespfilepfile(init.ora)中定義。在這種模式下,用戶只需簡char假設上例中操作系統(tǒng)用戶名為xcl,則上例將以CLUSTER$xcl數(shù)據(jù)庫用戶的連接Oracle數(shù)據(jù)庫。需要注意的是反斜線前后不能有空格,如果oid=”/“將連接失敗。INSYSDBA|SYSOPERMODE子句確定連接所用的數(shù)據(jù)庫SYSDBASYSOPER權(quán)限,否則無用。需注意的是在同node間進行信息(sql語句、數(shù)據(jù)、狀態(tài)值)的傳輸。在本地域中,OracleNETservice名稱作為網(wǎng)絡標識,用于連接數(shù)據(jù)庫,對非本域的節(jié)點,必須使用全局規(guī)范NET描述符來查找對應的數(shù)據(jù)庫服務器。Oracle的Pro*C/C++應用程序支持同時連接多個數(shù)據(jù)庫和對一個數(shù)據(jù)庫同時使用多個連接,下面圖展示了應用程序同時連接ORA2、ORA3、ORA4數(shù)據(jù)庫,并通過簡單的CONNECT語句連接到本地數(shù)據(jù)庫。Pro*C/C++OracleNET配置文件中,所有的數(shù)據(jù)庫都不應該重OracleNETEXECSQLATdb_name1SELECTEXECSQLATdb_name1DELETEEXECSQLAT:db_name1INSERT……EXECSQLAT:db_name2DELETE……EXECSQLAT:db_name2UPDATE……EXECSQLAT:db_name2INSERT……/*PL/SQLblockhere*/EXECSQLAT:db_nameDECLAREemp_cursorCURSORFOR...EXECSQLOPENemp_cursor...EXECSQLFETCHemp_cursor...EXECSQLCLOSEemp_cursor;EXECSQLAT:db_nameDECLAREsql_stmtSTATEMENT;EXECSQLPREPAREsql_stmtFROM:sql_string;EXECSQLDECLAREemp_cursorCURSORFORsql_stmt;EXECSQLOPENemp_cursor...EXECSQLFETCHemp_cursorINTO...EXECSQLCLOSEemp_cursor;EXECSQLCREATEDATABASELINKCONNECTTOusernameIDENTIFIEDBYUSINGEXECSQLSELECTENAME,JOBINTO:emp_name,:job_titleFROMemp@db_linkWHEREDEPTNO=起Oracle數(shù)據(jù)的回滾和提交。當程序中包含數(shù)據(jù)定義語句,例如(ALTER、GRANT、CREATE等,在這些語句前,OracleCOMMIT操作。這種方法隱式的對之前修改的數(shù)據(jù)進行了存在數(shù)據(jù)庫定義語言,Oracle才會提交數(shù)據(jù)。直到COMMIT語句執(zhí)行后,其他用戶才能應用程序中對數(shù)據(jù)庫改變的數(shù)據(jù),在事MODE=ANSIMODE=ORACLE模式時則不SAVEPOINT標識處。在一個事務中可有多個SAVEPOINT語句。for{printf("Customernumber?");cust_number=atoi(temp);if(cust_number==0)printf("Newstatus?");EXECSQLUPDATEmail_listSETstat=:new_statusWHEREcustno=}EXECSQLSAVEPOINTstart_delete;EXECSQLDELETEFROMmail_listWHEREstat=if(sqlca.sqlerrd[2]25)*25*/printf("Numberofrowsdeletedis%d\n",sqlca.sqlerrd[2]);{}

printf("Unngdeletionof%drows\n",EXECSQLWHENEVERSQLERRORGOTOsql_error/*出錯則跳轉(zhuǎn)到C語言特定EXECSQLWHENEVERSQLERRORCONTINUE;EXECSQLCOMMITWORKRELEASE;EXECSQLWHENEVERSQLERRORCONTINUE;EXECSQLROLLBACKWORKRELEASE;ROLLBACK語句完成事務中對數(shù)據(jù)庫數(shù)據(jù)所做修改的回滾(恢復,其主要完成的工 不采用只讀事務進行查詢,Oracle會認為事務有可能對目標數(shù)據(jù)進行更新,所以會根據(jù)編程在只讀事務中,其他用戶進程可以繼續(xù)對目標表進行數(shù)據(jù)和查詢。當一個用于包含CURRENTOF子句的DELETE、UPDATE語句的游標時,使用正UPDATE和DELETE語句前該行數(shù)據(jù)沒有被修改。EXECSQLDECLAREemp_cursorCURSORSELECTename,job,salFROMempWHEREdeptno=20FORUPDATEOFsal;EXECSQLDECLAREemp_cursorCURSORSELECTename,job,salFROMempWHEREdeptno=加入FORUPDATE子句。LOCKTABLErowshare模式鎖定了EMP表。ROWSHARE鎖定模式允許當前進程表,避免其他進程用exclusive獨占模式鎖定整表。COMMITROLLBACK語句時,釋放加在表上的鎖。后將釋放鎖,而鎖是在OPEN時加在記錄集上的,所以需要重新打開游標才能正常使用后FETCHrowidrowid對記錄集進行更新,例EXECSQLDECLAREemp_cursorCURSORSELECTename,sal,ROWIDFROMempWHEREjob=EXECSQLOPENfor{EXECSQLUPDATEempSETsal=:new_salaryWHEREROWID=:row_id;EXECSQL}狀況,在這種情況下,需要具有TRANSACTION系統(tǒng)權(quán)限的用戶通過查詢EXECSQLCOMMIT…EXECSQLROLLBACKPL/SQLCOMMITROLLBACK語句將影響外部整個事務。例如EXECSQLINSERTINTOEMP...EXECSQLEXECUTE變長字符 <=4000字<=4000<=2**31-1<=2000LONG<=2**31-1<=2000存放固定長度的國際特征多字節(jié)字符串。<=2000節(jié)CCNUMBER的NUMBER38位,這是任何操作系值以將數(shù)據(jù)庫數(shù)據(jù)值傳遞給C語言變量。變長字符 <=65535字<=2**31-1類似<65533<=65535LONG<=2**31-1LONGLONG應用是應用程序通過輸入宿主變量向Oracle數(shù)據(jù)庫數(shù)據(jù),通過輸出變量從Oracle數(shù)據(jù)庫中數(shù)據(jù)。宿主變量可以是C語言中任何一種能轉(zhuǎn)換成Oracle外部數(shù)據(jù)類型的變量類型,并且支持C語言的數(shù)組和結(jié)構(gòu)作為數(shù)組宿主變量和結(jié)構(gòu)宿主變量。如果預編譯選項MODE=ANSI或CODE=CPP或PARSE=NONE,或者否則在MODE=ORACLE的情況下可以象C語言變量那樣、定義宿主變量。N個字節(jié)長度的字符數(shù)組unsignedLONGunsignedunsignedPro*C/C++SQL語句中使用宿主變量,必須在宿主變量前加入冒號“:”指示符,而在其它地方使用則等同于C語言變量,不能加指示符。charbuf[15];intemp_number;floatsalary;emp_number=EXECSQLSELECTsalINTO:salaryFROMempWHEREempno=:emp_number;intempno;floatsal;EXECSQLSELECTename,salINTO:ename,:salFROMempWHEREempno=:empno;代碼單元不允許同名、大小寫等C語言關于變量使用要求。 #defineMAX_EMP_NUMintEXECSQLINSERTINTOemp(empno,ename,deptno)VALUES(:MAX_EMP_NUM+10,’CHEN’,:get_dept());(short緊跟在與其關聯(lián)的宿主變量后。如果使用DECLARESECTION宿主變量,則相關指示變量也必須采用DECLARESECTION進行。后面所根的是指示變量,在SQL語句中指示變量前也需要加入“:”指示符。:host_variableINDICATOR值0--intfloatsalary,shortcomm_ind/*charfloatpay;/*notusedinaSQLstatementprintf("Employeenumber?");emp_number=EXECSQLSELECTSAL, FROMWHEREEMPNO= m1)/*commission變量是NULL*/pay=salary;pay=salary+調(diào)整Pro*C/C++預編譯程序proc令行參數(shù),設定MODE=ORACLE類型進行操作時,VARCHAR類型要比C語言的char字符串類型方便的多。{unsignedshortlen;unsignedchararr[20];}VARCHARFETCHSELECTOracle數(shù)據(jù)庫中選擇可以在一行中定義多個VARCHAR變量:VARCHAR變量長度可以是宏,也可以是任何在預編譯過程中能識別的表達式。#define續(xù)“6.9指針變量”章節(jié)。intpart_number;VARCHARpart_desc[40];{EXECSQLSELECTpdescINTOFROMWHEREpnum=printf(“part_descis}置arr成員變量有效長度,arr成員存放具體數(shù)據(jù)值。INSERTUPDATE時,在沒有非空約束情況下,Oracle更新對應數(shù)據(jù)庫表該列數(shù)據(jù)為NULLVARCHARC語言結(jié)構(gòu),只要按照結(jié)構(gòu)的調(diào)用方法進行函數(shù)VARCHARemp_name.len=SELECTenameINTO:emp_nameFROMempWHEREempno=7499;VARCHAR*name;{printf("nameis%.*s\n",name->len,name-}#includeSQLVarcharGetLengthdvoid*contextunsignedlong*datlen,unsignedlong*totlen);或#include#include<sqlca.h>/*VARCHAR指針類型*/structmy_vc_ptr{unsignedshortlen;unsignedchararr[32767];typedefstructmy_vc_ptrmy_vc_ptr;my_vc_ptr*vc_ptr;intlimit;char*username="xcl/xclxcl";EXECSQLENDDECLAREvoidexternvoidsqlvcp(),sqlgls();{unsignedintvcplen,function_code,padlen,buflen;inti;charEXECSQLWHENEVERSQLERRORDOEXECSQLCONNECT:username;EXECSQLSELECTCOUNT(*)INTO:limitFROMEXECSQLDECLAREemp_name_cursorCURSORFORSELECTenameFROMemp;EXECSQLFOR:limitOPENemp_name_cursor;vcplen=10;/*sqlvcp()malloc的長度names=(VARCHAR*)malloc((sizeof(short)+(int)padlen)*limit);if(names==0){printf("Memoryallocationerror.\n");}for(vc_ptr=(my_vc_ptr*)names,i=0;i<limit;{vc_ptr->len=(short)vc_ptr=(my_vc_ptr*)((char*)vc_ptrpadlen+sizeof}EXECSQLFOR:limitFETCHemp_name_cursorINTOfor(vc_ptr=(my_vc_ptr*)names,i=0;i<limit;{vc_ptr=(my_vc_ptr*)((char*)vc_ptr+padlen+sizeof}buflen=(long)sizeofsqlgls(stmt_buf,&buflen,&function_code);if(buflen!={}{}}

printf("TheSQLstatementwas--\n%.*s\n",buflen,stmt_buf);printf("Thestatementlengthis%ld\n",buflen);printf("Thefunctioncodeis%ld\n",function_code);EXECSQLCOMMITRELEASE;printf("TheSQLGLSfunctionreturnedanerror.\n");EXECSQLROLLBACKRELEASE;void{charerr_msg[512];intbuf_len,msg_len;buf_len=sizeofsqlglm(err_msg,&buf_len,&msg_len);printf("%.*s\n",msg_len,err_msg);}只需改變PL/SQL語句即可,無需改動每個應用程序。 SQL_CURSORdept_cursor; EXECSQLALLOCATE:emp_cursor;ALLOCATEcursorCLOSE語句或連接關EXECSQLCLOSE例如在應用程序外部,通過編寫如下過程打開SQL_CURSOR類型的變TYPEEmpNameISRECORD(nameTYPEcur_typeISREFCURSORRETURNEmpName;PROCEDUREopen_emp_cur(cursINOUTcur_type,CREATEPROCEDUREopen_emp_cur(cursINOUTcur_type,OPENcursSELECTenameFROMempORDERBYenameASC; /*sql_cursor在Oracle數(shù)據(jù)庫服務器上正確編譯和建立了這個包后,就可以在外部Pro*C/C++應用 EXECEXECSQL;for{EXECSQLFETCH:emp_cursorINTO:emp_name;printf("%s\n",emp_name);}intdept_num=10;OPEN:emp_cursorintdept_num=10;OPEN:emp_cursorFORSELECTenameFROMempWHEREdeptno=:dept_num;之后使用和檢索數(shù)據(jù)方法同上面命名PL/SQL過程打開游標后的處理方法完全EXECSQLCLOSEOPEN、FETCH、CLOSE游標變量,但如果用戶斷開數(shù) EXEC 和 ALLOCATEATSQL_CURSOR TYPEemp_cur_typeISREFCURSORRETURNemp%ROWTYPE;PROCEDURE TYPEemp_cur_typeISREFCURSORRETURNemp%ROWTYPE;PROCEDUREopen_cur(cursINOUTemp_cur_type,dnoINNUMBER);ENDCREATEOR PROCEDUREopen_cur(cursINOUTemp_cur_type,dnoINNUMBER)ISOPENcursFORSELECTFROMempWHEREdeptno=dnoORDERBYenameASC;END#include#include<stdio.h>#include<sqlca.h>#include<stdlib.h>#include<sqlda.h>#includechar*msg;{size_tclen,fc;clen=sizeofsqlgls((char*)cbuf,(size_t*)&clen,(size_t*)&fc);printf("\n%s\n",msg);printf("Statementis--\n%s\n",cbuf);printf("Functioncodeis%ld\n\n",fc);sqlglm((char*)cbuf,(size_t*)&clen,(size_t*)printf("\n%.*s\n",clen,EXECSQLWHENEVERSQLERRORCONTINUE;EXECSQLROLLBACKWORKRELEASE;}void{charchar*uid="xcl/xclxcl";intdept_num;{intcharjob[10];intfloatsalary;intdept_num;{shortemp_num_ind;shortjob_ind;shortmanager_ind;shorthire_date_ind;shortsalary_ind;shortcommission_ind;shortdept_num_ind;EXECSQLWHENEVERSQLERRORdosql_error("Oracleerror");EXECSQLCONNECT:uid;for{{printf("\nEnterdepartmentnumber(0toexit):");dept_num=atoi(temp);if(dept_num<=0)EXECSQLprintf("\nFordepartment%d--\n",dept_num);printf("ENAMESALCOMM\n"); for{EXECSQLFETCHINTO:emp_infoINDICATOR:emp_info_ind;printf("%s",emp_info.emp_name);if( printf("NULL\n"); }}EXECSQLWHENEVERSQLERROREXECSQLCLOSEEXECSQLROLLBACKWORK}CONTEXTCURSOR,包含了MODE、HOLD_CURSOR等一些狀態(tài)信息。EXECSQLCONTEXTUSEcontext|DEFAULT} #include<sqlca.h>#include<ociextp.h>{sql_contextchar*usr1=char*usr2=/*xcl*/EXECSQLCONNECT:usr1;#include<sqlca.h>#include<ociextp.h>{sql_contextchar*usr1=char*usr2=/*xcl*/EXECSQLCONNECT:usr1;/*用SYSTEM連接,用作ctx1環(huán)境*/EXECSQLCONTEXTALLOCATEctx1;EXECSQLCONTEXTUSE:ctx1;}行操作。(有關OracleROWID的概念請參閱OracleDBA管理書籍)intn=4001EXECSQLSELECTrowidINTO:my_urowid_charFROMmy_tableWHERE...;EXECORACLEOPTION(CHAR_MAP=STRING);EXECSQLUPDATEmy_tableSET...WHERErowid=:my_urowid_charEXEC :myurowidcharC語言結(jié)構(gòu)包含宿主變量。任何合法的宿主變量類型都可以作為結(jié)構(gòu)代碼書寫,只需用此結(jié)構(gòu)作為Oracle數(shù)據(jù)庫到應用程序數(shù)據(jù)傳輸?shù)妮d體即可。typedef{intemp_number;intdept_number;floatsalary;}emp_recordnew_employee.emp_number=9876;new_employee.salary=EXECSQLINSERTINTOemp(ename,empno,deptno,sal)VALUES(:new_employee);{intemp_number[3];int}strcpy(emp_rec.emp_name[0],"ANQUETIL");strcpy(emp_rec.emp_name[1],"MERCKX");strcpy(emp_rec.emp_name[2],"HINAULT");emp_rec.emp_number[0]=1964;emp_rec.dept_number[0]=5;emprec.empnumber[1]=1974;emprec.deptnumber[1]=emp_rec.emp_number[2]=1985;emp_rec.dept_number[2]=5;EXECSQLINSERTINTOemp(ename,empno,deptno)PL/SQL{ints_id;char{shorts_name_ind;shorts_id_ind;shortgrad_date_ind;}EXECSQLSELECTstudent_name,student_idno,graduation_dateINTO:student_recordINDICATOR:student_record_indFROMcollege_enrollmentWHEREstudent_idno=#include<stdio.h>#include<sqlca.h>#definePWD_LENtypedefcharasciizusername;asciizpassword;structemp_info{asciizemp_name;floatsalary;floatvoid{structemp_info*emp_rec_ptr;if((emp_rec_ptr={fprintf(stderr,"Memoryallocationerror.\n");}strcpy(username,"xcl");EXECSQLCONNECT:usernameIDENTIFIEDBY:password;printf("\nConnectedtoORACLEasuser:%s\n",username);EXECSQLDECLAREsalespeopleCURSORFORSELECTENAME,SAL,COMMFROMWHEREJOBLIKEEXECSQLOPEN for{EXECSQLFETCHsalespeopleINTO:emp_rec_ptr;}}char*msg;{charerr_msg[512];intbuf_len,msg_len;buf_len=sizeof(err_msg);printf("%.*s\n",msg_len,err_msg);EXECSQLROLLBACKRELEASE;} charEXECSQLSELECTintcolINTO:int_ptrFROMstruct{intemp_number;floatsalary;char*name=structEMP_RECsal_rec=(structEMP_REC*)malloc(sizeof(structEXECSQLSELECTempno,salINTO:sal_recFROMempWHEREename=printf("Employeenumberandsalaryfor%s:",name);printf("%d,%g\n",sal_rec->emp_number,sal_rec->salary);SQL語句能夠讓用戶查詢、管理數(shù)據(jù)庫數(shù)據(jù),更改數(shù)據(jù)庫表、索引、視圖等組成DDLDBAOracle工具進行,很少有應用需要執(zhí)行這些語句,Pro*C/C++DDL語句的例子,SQL語句后,OracleSQLCA結(jié)構(gòu)置相應的執(zhí)行情況值,用戶可以通EXECSQLSELECTename,job,sal+2000INTO:emp_name,:job_title,:salaryFROMempWHEREempno=EXECSQLINSERTINTOemp(empno,ename,sal,VALUES(:emp_number,:emp_name,:salary,EXECSQLINSERTINTOemp2(empno,ename,sal,deptno)SELECTempno,ename,sal,deptnoFROMempWHEREjob=:job_titleEXECSQLUPDATESETsal=:salary, WHEREempno=:emp_number;SETsal=(SELECTAVG(sal)*1.1FROMempWHEREdeptno=20)WHEREempno=:emp_number;DELETEFROMempWHEREWHERESELECT、UPDATEDELETEWHERE子句限定操作數(shù)據(jù)記錄的WHERE子句中支持宿主變量、子查詢、數(shù)組宿主變量、系統(tǒng)函數(shù)和用戶自定義hviv{RETURNING|RETURN}{exprINTO{:hv[[INDICATOR]:iv][,:hvSELECT語句選擇新記錄信息的要求,RETURNING返回的值為新記錄的值。同時也消除了在DELETESELECT語句記錄所要刪除記錄的信息的做法,直接用DELETERETURNING子句可以將待刪除記錄信息記錄到宿主變量中。WHEREprintf(“AfterUPDATEempno=[%d]\n”,emp_number)/*emp_number19*/EXECSQLDELETEempWHEREempno=19 /*emp_number2DECLAREFETCH語句從活動記錄集中一條條的指向集合中當前記錄,供用戶到宿主變量中EXECSQLDECLAREemp_cursorCURSORFORSELECTename,empno,salFROMWHEREdeptno=emp_cursorOPEN、FETCH、CLOSE操作。游標名不是宿主變量,只是Pro*C/C++源代碼中的一個標識,不能在DECLARESECTION段中進行,其可以任意長度,但只有前31個字符有意義。為了同標準SQL兼容,游標名稱最好不要超過18個字符。CLOSEDELCARECURSOR語句放置在同一源文件內(nèi)。并且在一個源代碼文件如果在一個應用程序中,需要同時使用大量游標,應該調(diào)整proc命令行參數(shù)OPENEXECSQLOPEN標不需要預先執(zhí)行CLOSE語句進行關閉,這能提高應用程序性能。FETCHEXECSQLFETCHINTO:emp_name,:emp_number,FETCHDECLARECURSOROPENFETCH時返回FETCH語句將順序返回查詢結(jié)果集的下條記錄。構(gòu)的sqlcode1403(NoDataFound)錯誤,使用顯示的if(sqlca.sqlcode==1403INTOSELECT語句選擇出的列數(shù)相同,類型必須EXECSQLDECLAREemp_cursorCURSORSELECTename,salFROMempWHEREdeptno=EXECSQLOPENfor{EXECSQLFETCHemp_cursorINTO:emp_name1,:salary1;EXECSQLFETCHemp_cursorINTO:emp_name2,:salary2;EXECSQLFETCHemp_cursorINTO:emp_name3,:salary3;}CLOSEEXECSQLCLOSE子句的游標(一般用于UPDATE,時顯視的加入FORUPDATE子句,或通過使用則COMMIT和ROLLBACK語句關閉當前事務中所有打開的游標。FETCHNEXT:取當前記錄的后一條記錄。FETCHLAST:取記錄集的最后一條記錄。FETCHCURRENT:取當前記錄。EXECSQLDECLAREemp_cursorSCROLLCURSORSELECTename,salFROMempWHEREEXECSQLOPENEXECSQLFETCHLASTemp_cursorINTO:emp_name,:sal;EXECSQLCLOSEemp_cursor; MIT預編譯選項決定了是否在COMMIT語句時自動關閉事務中的游標,當MODE=ansi時, MIT默認為yes。明確的指定 為no,則COMMIT時不關閉游標,游標不需要重新打開,可以提升應用程序性能。器按照用戶的選擇進行適當?shù)乃惴▋?yōu)化,格式是在“/*+...*/”中加入優(yōu)化方式,例如:EXECSQLSELECT/*+ALL_ROWS(cost-based)*/empno,ename,sal,jobINTO:emp_recFROMempWHEREdeptno=CURRENTOFDELCARECURSOR語句時,F(xiàn)ORUPDATEUPDATE或DELETE當前游標所對應的查詢結(jié)果記錄時對記錄進行加鎖。在程序代碼中如果用到了CURRENTOFUPDATEDELETE,則預編譯器會根據(jù)情況自動在DECLARE語句中加入FORUPDATE子句。EXECSQLDECLAREemp_cursorCURSORSELECTename,salFROMempWHEREjob=FORUPDATEOFEXECSQLOPENEXECSQLWHENEVERNOTFOUNDGOTOfor(;;)EXECSQLFETCHemp_cursorINTO:emp_name,EXECSQLUPDATEempSETsal=:new_salaryWHERECURRENTOFemp_cursor;}/*EXECSQLDECLAREemp_cursorCURSORFORSELECTename,jobFROMWHEREempno=:emp_numberFORUPDATEOFjob;EXECSQLOPENemp_cursor;/*如果沒有記錄則breakEXECSQLWHENEVERNOTFOUNDDOfor(;;){EXECSQLFETCHemp_cursorINTO:emp_name,:job_title;EXECSQLUPDATEempSETjob=:new_job_titleWHERECURRENTOFemp_cursor;}#includecharuserid[12]="xcl/xclxcl";charemp_name[10];intemp_number;intdept_number;chartemp[32];voidsql_error();#include<sqlca.h>{emp_number=EXECSQLWHENEVERSQLERRORdosql_error("Oracleerror");EXECSQLCONNECT:userid;EXECSQLDECLAREemp_cursorCURSORFORSELECTenameFROMWHEREdeptno=printf("Departmentnumber?");dept_number=printf("EmployeeName\n"); while{EXECSQLFETCHemp_cursorINTO:emp_name;printf("%s\n",emp_name);}EXECSQLCLOSE}}char*msg;{charintbuflen,EXECSQLWHENEVERSQLERRORCONTINUE;EXECSQLROLLBACKWORKRELEASE;buflen=sizeof(buf);printf("%s\n",msg);printf("%*.s\n",msglen,buf);}#include#includecharemp_name[10];void{EXECSQLDECLAREemp_cursorSCROLLCURSORSELECTenameFROMemp;EXECSQLOPENemp_cursor;EXECSQLFETCHLASTemp_cursorINTOEXECSQLFETCHABSOLUTE5emp_cursorINTOEXECSQLFETCHFIRSTemp_cursorINTOEXECSQLFETCHmy_cursorINTO:emp_name;EXECSQLFETCHNEXTmy_cursorINTOEXECSQLFETCHPRIORmy_cursorINTO}char*msg;{charintbuflen,EXECSQLWHENEVERSQLERRORCONTINUE;EXECSQLROLLBACKTRANSACTION;buflen=sizeof(buf);}和可擴展性,運行應用程序在運行狀態(tài)時動態(tài)組織SQL語句并執(zhí)行和處理執(zhí)行結(jié)果。結(jié)構(gòu)數(shù)組(a

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論