数据库系统原理1陈岭浙江大学计算机学院关系模型2嵌入式SQLODBCSQL语言(5)嵌入式SQL3SQL标准定义了将SQL嵌入到程序设计语言中(如Pascal,PL/I,Fortran,CandCobol)SQL查询所嵌入的语言称为宿主语言,而在宿主语言中使用的SQL结构被称为EmbeddedSQLEXECSQL语句用于向预处理器标识嵌入式SQL请求EXECSQL嵌入式SQL语句END_EXEC注意:嵌入式SQL的确切语法依赖于宿主语言,如在Java中使用#SQL{…}嵌入式SQL-查询4例,单行查询(oracle)EXECSQLBEGINDECLARESECTION;charID[20],name[20];floatsal;EXECSQLENDDECLARESECTION;…….scanf(“%s”,&ID);//读入教师账号,然后据此在下面的语句获得name,sal的值EXECSQLselectname,salaryinto:name,:salfrominstructorwhereID=:ID;END_EXECprintf(“%s,%s,%f”,ID,name,sal);…….:ID、:name、:sal是宿主变量,可在宿主语言程序中赋值,从而将值带入SQL。宿主变量在宿主语言中使用时不加:号嵌入式SQL-查询5例,多行查询(oracle):假设有一个宿主变量credit_amount,找出学分高于credit_amount的所有学生的名字第1步:用SQL写查询并为它声明一个游标EXECSQLdeclareccursorforselectID,namefromstudentwheretot_cred:credit_amount;END_EXC第2步:用open语句来执行查询EXECSQLopencEND-EXEC游标嵌入式SQL-查询6第3步:用一系列的fetch语句把元组的值赋给宿主语言的变量EXECSQLfetchcinto:si,:sn;―循环调用fetch可逐条取得查询结果中的元组―SQL通信区(SQLCA)中的变量SQLSTATE被设置为‘02000’表示不再有数据了第4步:close语句使数据库系统删除用于保存查询结果的临时关系EXECSQLclosec;注意:上述细节随语言而变。例,Java中定义了Javaiterators来遍历结果中的元组嵌入式SQL-修改7例,单行修改EXECSQLBEGINDECLARESECTION;charID[20];floatsal;EXECSQLENDDECLARESECTION;…….scanf(“%s%f”,&ID,&sal);//读入教师账号,及要增加的工资值EXECSQLupdateinstructorsetsalary=salary+:salwhereID=:ID;…….嵌入式SQL-修改8例,多行修改:通过使用游标来更新数据库关系。例,要为音乐系的每个教师的salary都增加100EXECSQLBEGINDECLARESECTION;charID[20],name[20];floatsal;EXECSQLENDDECLARESECTION;EXECSQLDECLAREcsrCURSORselect*frominstructorwheredept_name=‘Music’forupdateofsalary;……嵌入式SQL-修改9(修改游标当前位置上的元组)EXECSQLOPENcsr;while(1){EXECSQLFETCHcsrINTO:ID,:name,:sal;if(sqlca.sqlcodeSUCCESS)BREAK;……//由宿主语句对ID,name,sal中的数据进行相关处理(如打印)EXECSQLupdateinstructorsetsalary=salary+100whereCURRENTOFcsr;}……EXECSQLCLOSEcsr;……或:EXECSQLdeletefromintructorwhereCURRENTOFcsr;ODBC10开放数据库互连(OpenDataBaseConnectivity,ODBC)用于应用程序与数据库服务通信的标准标准定义了一个API1.建立一个和服务器的连接2.发送查询、更新请求等3.获取返回结果应用程序(如,图形界面、电子表格等)可以使用相同的ODBCAPI来访问一个支持ODBC标准的数据库ODBC11嵌入式SQL和ODBC嵌入式SQL:程序在编译前必须由一个特殊的预处理器进行处理ODBC标准为应用程序连接数据库服务器定义了一个API―与具体DBMS无关―不需要预编译ODBC12ODBC提供了一个公共的、与具体数据库无关的应用程序设计接口API(ApplicationProgrammingInterface)。所谓公共的接口API就是为开发者提供单一的编程接口,这样同一个应用程序就可以访问不同的数据库服务器使用ODBC访问数据库的方法:ODBCAPI访问数据库VisualC++的MFC提供了丰富的ODBC类,它们封装了大量的函数用以完成数据库的大部分应用ODBC13访问数据库的其他方法OLEDB(ObjectLinkandEmbeddingDataBase),是一套通过COM(ComponentObjectModel,组件对象模型)接口访问数据库的ActiveX底层接口技术,速度快,支持关系型和非关系型数据库,编程量大ADO(ActiveXDataObjects),基于COM,建立在OLEDB之上,更易于使用DAO(DataAccessObjects),基于MicrosoftJet引擎,访问Access数据库(即*.MDB文件)时具有很好的性能,DAO类与ODBC类相比具有很多相似之处ODBC14定义ODBC数据源:控制面板-管理工具-数据源(ODBC)-DSN(datasourcename)MySQLOracleSQLServerODBC15ODBC程序会先分配一个SQL的环境变量,然后是一个数据库连接句柄ODBC程序随后会利用SQLConnect打开和数据库的连接,这个调用有几个参数,包括:数据库的连接句柄要连接的服务器用户的身份密码还必须指定参数的类型SQL_NTS表示前面参数是一个以null结尾的字符串ODBC16应用程序环境句柄连接句柄连接句柄连接句柄语句句柄语句句柄语句句柄ODBC接口定义了三种句柄类型ODBC171.分配环境句柄HENVhenv;SQLAllocEnv(&henv);2.分配连接句柄HDBChdbc;SQLAllocConnect(henv,&hdbc);3.用已分配的连接句柄连接数据源SQLConnect(hdbc,szDSN,cbDSN,szUID,cbUID,zAuthStr,cbAuthStr);说明:hdbc是一个已分配的连接句柄szDSN和cbDSN分别表示系统所要连接的数据源名称字符串及其长度szUID和cbUID分别表示连接数据源的用户名字符串及其长度szAuthStr和cbAuthStr分别表示连接数据源的权限字符串及其长度ODBC184.分配语句句柄HSTMThstmt;SQLAllocStmt(hdbc,&hstmt);5.1直接执行SQL语句SQLExecDirect(hstmt,szSqlStr,cbSqlStr);说明:hstmt是一个有效的语句句柄szSqlStr和cbSqlStr分别表示将要执行的SQL语句的字符串及其长度例,retcode=SQLExecDirect(hstmt,“deletefrombookwhereISBN=1”,SQL_NTS);―说明:删除book表中ISBN=1的记录。SQL_NTS是ODBC的一个常数,当字符串是以NULL结束时,可用它来表示字符串的长度ODBC195.2有准备地执行SQL语句如果SQL语句需要执行几次,则采用有准备的执行更好,避免了SQL语句的多次分析。有准备的执行需要两个函数SQLPrepare(hstmt,szSqlStr,cbSqlStr);―说明:SQL语句准备函数,参数同SQLExecDirectSQLExecute(hstmt);―说明:SQL语句执行函数ODBC206.查询结果的获取SQLFetch(hstmt);说明:把游标移到下一行,当查询语句执行后第一次调用时移到结果集的第一行SQLGetData(hstmt,icol,fCType,rgbValue,cbValueMax,pcbValue);说明:读取游标指向行的列值icol和fCType分别表示结果集的列号和类型rgbValue和cbValueMax是接收数据存储区的指针和最大长度pcbValue是返回参数,表示本次调用后实际接收到的数据的字节数ODBC217.释放语句句柄SQLfreeStmt(hstmt,foption);说明:foption指定选项,一个选项是用SQL_DROP表示释放所有与该句柄相关的资源8.断开数据源连接SQLDisconnect(hdbc);9.释放连接句柄SQLFreeConnect(hdbc);10.释放环境句柄SQLFreeEnv(henv);ODBC221.ODBC初始化SQLAllocEnv()SQLAllocConnect()SQLConnect()SQLAllocStmt()2.执行SQL命令SQLExecDirect()SQLPrepare()SQLExecute()3.获取结果数据SQLFetch()SQLGetData()4.释放空间SQLFreeStmt()SQLDisconnect()SQLFreeConnect()SQLFreeEnv()ODBC编程的基本流程//查询结果和自定义变量进行绑定SQLBindCol()SQLFetch()ODBC23ODBC代码示例intODBCexample()//程序结构{RETCODEerror;HENVenv;/*environment*/HDBCconn;/*databaseconnection*/SQLAllocEnv(&env);SQLAllocConnect(env,&conn);/*建立连接句柄*/SQLConnect(conn,“MySQLServer”,SQL_NTS,“user”,SQL_NTS,“password”,SQL_NTS);/*建立用户user与数据源的连接,SQL_NTS表示前一参量以null结尾*/{…Mainbodyofprogram…}//见下页SQLDisconnect(conn);SQLFreeConnect(conn);SQLFreeEnv(env);}ODBC24ODBC代码示例(Mainbodyofprogram){chardeptname[80];floatsalary;intlenOut1,lenOut2;HSTMTstmt;SQLAllocStmt(conn,&stmt);/*为该连接建立数据区,将来存放查询结果*/char*sqlquery=“selectdept_name,sum(salary)frominstructorgroupbydept_name”;/*装配SQL语句*/error=SQLExecDirect(stmt,sqlquery,SQL_NTS);/*执行sql语句,查询结果存放到数据区stmt,同时sql语句执行状态的返回值送变量error*/ODBC25ODBC代码示例(Mainbodyofprogram)……if(error==SQL_SUCCESS){SQLBindCol(stmt,1,SQL_C_CHAR,deptname,80,&lenOut1);SQLBindCol(stmt,2,SQL_C_FLOAT,&salary,0,&lenOut2);/*对stmt中的返回结果数据加以分离,并与相应