《DB2操作 - DB2 -- 电脑知识与技术互动沟通平台.docx》由会员分享,可在线阅读,更多相关《DB2操作 - DB2 -- 电脑知识与技术互动沟通平台.docx(33页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、DB2操作-DB2-次元立方网-电脑知识与技术互动沟通平台注解:DECLARE语句的在程序中位置是任意的,但是它必须在第一次使用游标的位置之前。3.3.2游标与工作单元的考虑COMMIT或者ROLLBACK操作的动作随游标的不同而不同,依靠于游标的定义。1只读游标ReadOnlyCursors假如一个游标被确定为只读的,并且使用可重复读隔离级isolationlevel,那么系统表仍会采集和维护工作单元需要的可重复读锁。因而,即便只读游标,应用程序周期性地发出COMMIT语句还是很重要的。2有WITHHOLD选项假如应用程序通过发出一条COMMIT语句来完成一个工作单元,除了声明时有WITHH
2、OLD选项的游标,所有游标将自动地被数据库管理器关闭。用WITHHOLD声明的游标维护它访问的跨多个工作单元的资源。用WITHHOLD声明的游标遭到的影响依靠于工作单元怎样结束。假如工作单元使用一条COMMIT语句结束,已打开的定义为WITHHOLD的游标将保持打开状态。游标的位置在结果集的下一个逻辑行之前。另外,参考用WITHHOLD定义的已准备好的语句也会被保留。紧跟COMMIT语句后面,只要与一个某个特定游标相关联的FETCH和CLOSE请求才有效。UPDATEWHERECURRENTOF和DELETEWHERECURRENTOF语句仅仅对在同一个工作单元中提取的行有效。假如程序包在工作
3、单元期间被重新绑定,那么所有保持的游标都会被关闭。假如工作单元使用一条ROLLBACK语句结束,所有打开的游标被关闭,所有在工作单元中获得的锁被释放,以及所有依靠于这个工作单元的已准备好的语句被删除。举个例子,假设TEMPL表中有1000条记录。要更新所有雇员的工资,应该每更新100行就要发出一条COMMIT语句。A.使用WITHHOLD选项声明游标:EXECSQLDECLAREEMPLUPDTCURSORWITHHOLDFORSELECTEMPNO,LASTNAME,PHONENO,JOBCODE,SALARYFROMTEMPLFORUPDATEOFSALARYB.打开游标,每一次从结果表中
4、提取一行数据:EXECSQLOPENEMPLUPDT.EXECSQLFETCHEMPLUPDTINTO:upd_emp,:upd_lname,:upd_tele,:upd_jobcd,:upd_wage,C.当想要更新或者删除一行时,使用带WHERECURRENTOF选项的UPDATE或者DELETE语句。例如,要更新当前行,程序能够发出下面的语句:EXECSQLUPDATETEMPLSETSALARY=:newsalaryWHERECURRENTOFEMPLUPDT在一条COMMIT语句发出之后,在更新其它行之前必须发出FETCH语句。假如应用程序使用了用WITHHOLD声明的游标或者执行了
5、多个工作单元并且有一个用WITHHOLD声明的游标跨工作单元处于打开状态,那么在程序中应该参加代码检测和处理SQLCODE为-501SQLSTATE为24501的错误,这个错误由FETCH或者CLOSE语句返回。假如应用程序的程序包由于其依靠的表被删除而变得无效,程序包会自动被重新绑定。这种情况下,FETCH或CLOSE语句返回SQLCODE501SQLSTATE24501,由于数据库管理器关闭游标。在此情形下,处理SQLCODE501SQLSTATE24501的方法决定于能否要从游标提取行数据。l假如要从游标提取行,打开游标,然后运行FETCH语句。注意,OPEN语句使得游标重定位到开场处。
6、原来的位置信息丢失。l假如不准备从游标提取行,那么不要对游标发出任何SQL请求。WITHRELEASE选项:当应用程序用WITHRELEASE选项关闭一个游标时,DB2试图去释放游标持有的所有读锁READlocks。游标只继续持有写锁WRITElocks。假如应用程序没有用RELEASE选项关闭游标,那么在工作单元完成时,所有的读锁和写锁都被释放。3.3.3例程游标程序CExample:CURSOR.SQC#include#include#include#includeutil.h#ifdefDB268K/*NeedtoincludeASLMfor68Kapplications*/#inclu
7、de#endifEXECSQLINCLUDESQLCA;#defineCHECKERR(CE_STR)if(check_error(CE_STR,sqlca)!=0)return1;intmain(intargc,char*argv)EXECSQLBEGINDECLARESECTION;charpname10;shortdept;charuserid9;charpasswd19;EXECSQLENDDECLARESECTION;#ifdefDB268K/*BeforemakinganyAPIcallsfor68Kenvironment,needtoinitialtheLibraryManage
8、r*/InitLibraryManager(0,kCurrentZone,kNormalMemory);atexit(CleanupLibraryManager);#endifprintf(SampleCprogram:CURSOR/n);if(argc=1)EXECSQLCONNECTTOsample;CHECKERR(CONNECTTOSAMPLEelseif(argc=3)strcpy(userid,argv1);strcpy(passwd,argv2);EXECSQLCONNECTTOsampleUSER:useridUSING:passwd;CHECKERR(CONNECTTOSAM
9、PLEelseprintf(/nUSAGE:cursoruseridpasswd/n/nreturn1;/*endif*/EXECSQLDECLAREc1CURSORFOR(1)SELECTname,deptFROMstaffWHEREjob=MgrFORUPDATEOFjob;EXECSQLOPENc1;(2)CHECKERR(OPENCURSORdoEXECSQLFETCHc1INTO:pname,:dept;(3)if(SQLCODE!=0)break;printf(%-10.10sindept.%2dwillbedemotedtoClerk/n,pname,dept);while(1)
10、;EXECSQLCLOSEc1;(4)CHECKERR(CLOSECURSOREXECSQLROLLBACK;CHECKERR(ROLLBACKprintf(/nOnsecondthought-changesrolledback./n);EXECSQLCONNECTRESET;CHECKERR(CONNECTRESETreturn0;/*endofprogram:CURSOR.SQC*/JavaExample:Cursor.sqljimportjava.sql.*;importsqlj.runtime.*;importsqlj.runtime.ref.*;#sqliteratorCursorB
11、yName(Stringname,shortdept);#sqliteratorCursorByPos(String,short);classCursorstatictryClass.forName(COM.ibm.db2.jdbc.app.DB2Driver).newInstance();catch(Exceptione)System.out.println(/nErrorloadingDB2Driver./nSystem.out.println(e);System.exit(1);publicstaticvoidmain(Stringargv)trySystem.out.println(J
12、avaCursorSampleStringurl=jdbc:db2:sample/URLisjdbc:db2:dbnameConnectioncon=null;/Settheconnectionif(argv.length=0)/connectwithdefaultid/passwordcon=DriverManager.getConnection(url);elseif(argv.length=2)Stringuserid=argv0;Stringpasswd=argv1;/connectwithuser-providedusernameandpasswordcon=DriverManage
13、r.getConnection(url,userid,passwd);elsethrownewException(Usage:javaCursorusernamepassword/SetthedefaultcontextDefaultContextctx=newDefaultContext(con);DefaultContext.setDefaultContext(ctx);/Enabletransactionscon.setAutoCommit(false);/UsingcursorstryCursorByNamecursorByName;CursorByPoscursorByPos;Str
14、ingname=null;shortdept=0;/UsingtheJDBCResultSetcursormethodSystem.out.println(/nUsingtheJDBCResultSetcursormethodSystem.out.println(withabindbynamecursor./n#sqlcursorByName=SELECTname,deptFROMstaffWHEREjob=MgrFORUPDATEOFjob;(1)while(cursorByName.next()(2)name=cursorByName.name();(3)dept=cursorByName
15、.dept();System.out.print(name=+name);System.out.print(dept=+dept);System.out.print(/ncursorByName.close();(4)/UsingtheSQLJiteratorcursormethodSystem.out.println(/nUsingtheSQLJiteratorcursormethodSystem.out.println(withabindbypositioncursor./n#sqlcursorByPos=SELECTname,deptFROMstaffWHEREjob=MgrFORUPD
16、ATEOFjob;(1)(2)while(true)#sqlFETCH:cursorByPosINTO:name,:dept;(3)if(cursorByPos.endFetch()break;System.out.print(name=+name);System.out.print(dept=+dept);System.out.print(/ncursorByPos.close();(4)catch(Exceptione)throwe;finally/RollbackthetransactionSystem.out.println(/nRollbackthetransaction.#sqlR
17、OLLBACK;System.out.println(Rollbackdone.catch(Exceptione)System.out.println(e);游标程序假如工作:1声明游标。DECLARECURSOR语句将游标c1与一个查询关联起来。查询确定应用程序使用FETCH语句提取的行。表staff的job字段被定义为可更新的,即便它在结果表中。2打开游标。游标c1被打开,数据库管理器执行查询并创立结果表。游标的指向位于第一行的前面。3提取一行。FETCH语句使游标指向下一行,将那行的内容移动到宿主变量中。那行成为当前行。4关闭游标。发出CLOSE语句,释放与游标相关联的资源。游标仍然能够
18、再次打开。3.3.4更新和删除提取的数据能够更新和删除一个游标指向的行。要使行能被更新,对应于游标的查询不能是只读的。更新提取的数据为了利用游标来更新数据,在UPDATE语句中使用WHERECURRENTOF子句。使用FORUPDATE子句告诉系统结果表中的哪些列要更新。可以以在FORUPDATE中指出不在选择范围之内的列,从另一个角度讲,能够更新不被游标提取的列。假如FORUPDATE子句中没有指定任何列名,那么在第一个FROM子句中标识的表或者视图的所有列都被看作是可更新的。性能上要求只在FORUPDATE子句里指定要更新的列,假如指定不需要更新的列,DB2将浪费没有必要的开销去访问数据。
19、删除提取的数据为了利用游标来删除数据,在DELETE语句中使用WHERECURRENTOF条款。通常上,为了删除游标的当前行,定义游标时,不需要FORUPDATE条款。一个例外情况是,在应用程序中使用动态的SELECT语句或者DELETE语句,预编译时LANGLEVEL选项设为SAA1,捆绑时使用BLOCKINGALL选项。这种情况下,SELECT语句需要FORUPDATE条款。(具体信息请看3.3节开发动态SQL应用程序)DELETE语句使得游标指示的那行被删除。游标的位置指向下一行的前面。要进行下一个WHERECURRENTOF操作之前,必须对游标发出一条FETCH语句。游标的类型游标能够
20、分为三类:1只读类型游标指向的行只能够读,不能够更新。应用程序只是读取数据不修改时,使用只读游标。假如游标是基于只读SELECT语句,那么它便是只读的。只读游标在性能方面较好。2可更新类型游标指向的行能够更新。应用程序需要修改提取的数据时,使用可更新游标。指定的查询只能涉及到一个表或视图。查询必须包含FOTUPDATE子句,并写出每一个要更新的列除非预编译时使用LANGLEVELMIA选项。3不明确类型从游标的定义或者上下文来确定游标是可更新的还是只读的。当预编译或绑定时使用BLOCKINGALL选项,不明确的游标被看作是只读的。否则,被看作是可更新的。注意:动态处理的游标通常是不明确类型的。
21、例子OPENFTCH程序这个例子使用一个游标从一个表中选择行,打开游标,从表中提取行。对提取的每一行,判定能否要删除或者更新根据一个简单的条件。这个例子有下面语言的版本:C语言:openftch.sqcJava语言:Openftch.sqljandOpF_Curs.sqljCOBOL语言:openftch.sqbFORTRAN语言:openftch.sqfCExample:OPENFTCH.SQC#include#include#include#includeutil.h#ifdefDB268K/*NeedtoincludeASLMfor68Kapplications*/#include#en
22、difEXECSQLINCLUDESQLCA;#defineCHECKERR(CE_STR)if(check_error(CE_STR,sqlca)!=0)return1;intmain(intargc,char*argv)EXECSQLBEGINDECLARESECTION;charpname10;shortdept;charuserid9;charpasswd19;EXECSQLENDDECLARESECTION;#ifdefDB268K/*BeforemakinganyAPIcallsfor68Kenvironment,needtoinitialtheLibraryManager*/In
23、itLibraryManager(0,kCurrentZone,kNormalMemory);atexit(CleanupLibraryManager);#endifprintf(SampleCprogram:OPENFTCH/n);if(argc=1)EXECSQLCONNECTTOsample;CHECKERR(CONNECTTOSAMPLEelseif(argc=3)strcpy(userid,argv1);strcpy(passwd,argv2);EXECSQLCONNECTTOsampleUSER:useridUSING:passwd;CHECKERR(CONNECTTOSAMPLE
24、elseprintf(/nUSAGE:openftchuseridpasswd/n/nreturn1;/*endif*/EXECSQLDECLAREc1CURSORFOR(1)SELECTname,deptFROMstaffWHEREjob=MgrFORUPDATEOFjob;EXECSQLOPENc1;(2)CHECKERR(OPENCURSORdoEXECSQLFETCHc1INTO:pname,:dept;(3)if(SQLCODE!=0)break;if(dept40)printf(%-10.10sindept.%2dwillbedemotedtoClerk/n,pname,dept)
25、;EXECSQLUPDATEstaffSETjob=Clerk(4)WHERECURRENTOFc1;CHECKERR(UPDATESTAFFelseprintf(%-10.10sindept.%2dwillbeDELETED!/n,pname,dept);EXECSQLDELETEFROMstaffWHERECURRENTOFc1;CHECKERR(DELETE/*endif*/while(1);EXECSQLCLOSEc1;(5)CHECKERR(CLOSECURSOREXECSQLROLLBACK;CHECKERR(ROLLBACKprintf(/nOnsecondthought-cha
26、ngesrolledback./n);EXECSQLCONNECTRESET;CHECKERR(CONNECTRESETreturn0;/*endofprogram:OPENFTCH.SQC*/JavaExample:Openftch.sqljOpF_Curs.sqlj/PURPOSE:Thisfile,namedOpF_Curs.sqlj,containsthedefinition/oftheclassOpF_CursusedinthesampleprogramOpenftch.importsqlj.runtime.ForUpdate;#sqlpubliciteratorOpF_Cursim
27、plementsForUpdate(String,short);Openftch.sqljimportjava.sql.*;importsqlj.runtime.*;importsqlj.runtime.ref.*;classOpenftchstatictryClass.forName(COM.ibm.db2.jdbc.app.DB2Driver).newInstance();catch(Exceptione)System.out.println(/nErrorloadingDB2Driver./nSystem.out.println(e);System.exit(1);publicstati
28、cvoidmain(Stringargv)trySystem.out.println(JavaOpenftchSampleStringurl=jdbc:db2:sample/URLisjdbc:db2:dbnameConnectioncon=null;/Settheconnectionif(argv.length=0)/connectwithdefaultid/passwordcon=DriverManager.getConnection(url);elseif(argv.length=2)Stringuserid=argv0;Stringpasswd=argv1;/connectwithus
29、er-providedusernameandpasswordcon=DriverManager.getConnection(url,userid,passwd);elsethrownewException(/nUsage:javaOpenftchusernamepassword/n/if-elseif-else/SetthedefaultcontextDefaultContextctx=newDefaultContext(con);DefaultContext.setDefaultContext(ctx);/Enabletransactionscon.setAutoCommit(false);
30、/ExecutingSQLJpositionedupdate/deletestatements.tryOpF_CursforUpdateCursor;Stringname=null;shortdept=0;#sqlforUpdateCursor=SELECTname,deptFROMstaffWHEREjob=MgrFORUPDATEOFjob;/#sql(1)(2)while(true)#sqlFETCH:forUpdateCursorINTO:name,:dept;/#sql(3)if(forUpdateCursor.endFetch()break;if(dept40)System.out
31、.println(name+indept.+dept+willbedemotedtoClerk#sqlUPDATEstaffSETjob=ClerkWHERECURRENTOF:forUpdateCursor;/#sql(4)elseSystem.out.println(name+indept.+dept+willbeDELETED!#sqlDELETEFROMstaffWHERECURRENTOF:forUpdateCursor;/#sql/if-elseforUpdateCursor.close();(5)catch(Exceptione)throwe;finally/Rollbackth
32、etransactionSystem.out.println(/nRollbackthetransaction.#sqlROLLBACK;System.out.println(Rollbackdone./try-catch-finallycatch(Exceptione)System.out.println(e);/try-catch/main/classOpenftchOPENFTCH程序是怎样工作的:1声明游标。DECLARECURSOR语句将游标c1与一个查询关联起来。查询确定应用程序使用FETCH语句提取的行。表staff的job字段被定义为可更新的,即便它不在结果表中。2打开游标。游
33、标c1被打开,导致数据库管理器执行查询并创立一个结果表。游标的位置位于第一行的前面。3提取一行。FETCH语句将游标指向下一行,并将行的内容移到宿主变量中。那行成为当前行。4更新或删除当前行。当前行被更新或者被删除,决定于FETCH语句返回dept的值。假如一个UPDATE语句被执行,游标的位置保持不变,由于UPDATE语句不改变当前行的位置。假如一个DELETE语句被执行,游标的位置位于下一行的前面,由于当前行已被删除。在进行另外的WHERECURRENTOF操作之前,必须执行一条FETCH语句。5关闭游标。CLOSE语句被发出,释放与游标关联的资源。游标能够被再次打开。3.4诊断信息处理与
34、SQLCA构造3.4.1SQLCA构造SQLCA的全称为SQL通信区CommunicationArea,是应用程序用来接收数据库管理返回的SQL执行情况信息的数据构造。下面是SQLCA的C语言定义:SQL_STRUCTUREsqlca_SQLOLDCHARsqlcaid8;/*Eyecatcher=SQLCA*/sqlint32sqlcabc;/*SQLCAsizeinbytes=136*/sqlint32sqlcode;/*SQLreturncode*/shortsqlerrml;/*LengthforSQLERRMC*/_SQLOLDCHARsqlerrmc70;/*Errormessagetokens*/_SQLOLDCHARsqlerrp8;/*Diagnosticinformation*/sqlint32sqlerrd6;/*Diagnosticinformation*/_SQLOLDCHARsqlwarn11;/*Warningflags*/_SQLOLDCHARsqlstate5;/*StatecorrespondingtoSQLCODE*/;下表是SQLCA数据构造的具体描绘: