Chapter 8:Programmatic SQL - Renmin University of Chinaidke.ruc.edu.cn/xfmeng/course/Introduction to...

111
Chapter 8:Programmatic SQL Chapter 8:Programmatic SQL - - Embedded SQL Embedded SQL - - ODBC ODBC - - PL/SQL PL/SQL

Transcript of Chapter 8:Programmatic SQL - Renmin University of Chinaidke.ruc.edu.cn/xfmeng/course/Introduction to...

Chapter 8:Programmatic SQLChapter 8:Programmatic SQL

--Embedded SQLEmbedded SQL--ODBCODBC

--PL/SQLPL/SQL

Programmatic SQLProgrammatic SQLSQLSQL--92 standard lacked computational 92 standard lacked computational completeness:completeness:•• No flow of control commands such as IF No flow of control commands such as IF …… ELSE, ELSE,

DO DO …… WHILEWHILE•• SQL allows statements to be embedded in a highSQL allows statements to be embedded in a high--

level procedural language as well as being able to level procedural language as well as being able to enter SQL interactively at a terminal.enter SQL interactively at a terminal.

•• In many case, the SQL language is identical, In many case, the SQL language is identical,

Programmatic SQLProgrammatic SQL

Three types of programmatic SQLThree types of programmatic SQL•• Embedded SQL statementsEmbedded SQL statements

ISO standard specifies embedded support for ISO standard specifies embedded support for AdaAda, C, , C, COBOL, Fortran, Pascal, PL/1COBOL, Fortran, Pascal, PL/1

•• Application Programming Interface (API)Application Programming Interface (API)ODBCODBCJDBCJDBCSpecific API, like APIs in COBASESpecific API, like APIs in COBASE

•• Procedure SQLProcedure SQLPL/SQLPL/SQL

Embedded SQLEmbedded SQL

Embedded SQL into a existing Embedded SQL into a existing programming language programming language

Select * from studentWhere sno=‘S1’

#Include <stdio.h>……Main() {……Char name [16];Int age;……

}

=

Embedded SQL

Host language

Simple Embedded SQL StatementsSimple Embedded SQL Statements

例例1 1 建立一个建立一个““学生学生””表表StudentStudentEXEC SQL CREATE TABLE StudentEXEC SQL CREATE TABLE Student

((SnoSno CHAR(5) NOT CHAR(5) NOT NULL UNIQUE,NULL UNIQUE,

SnameSname CHAR(20),CHAR(20),SsexSsex CHAR(1),CHAR(1),Sage INT,Sage INT,SdeptSdept CHAR(15));CHAR(15));

/* Program to create student table *//* Program to create student table */#include <#include <stdio.hstdio.h>>#include <#include <stdlib.hstdlib.h>>EXEC SQLEXEC SQL INCLUDE INCLUDE sqlcasqlca;;Main()Main(){{

EXEC SQLEXEC SQL BEGIN DECLARE SECTIONBEGIN DECLARE SECTION;;char *username = char *username = ““ Manager/ManagerManager/Manager””;;char *connect String= char *connect String= ““CollegeCollege””

EXEC SQL END DECLARE SECTIONEXEC SQL END DECLARE SECTION;;/* connect to database*//* connect to database*/

EXEC SQL CONNECTEXEC SQL CONNECT ::connectStringconnectString USER :username ;USER :username ;if (if (sqlca.sqlcodesqlca.sqlcode < 0 ) exit (< 0 ) exit (--1);1);

/* display message for user and create the table *//* display message for user and create the table */printfprintf ((““ Creating student table Creating student table \\nn””););EXEC SQLEXEC SQL CREATE TABLE StudentCREATE TABLE Student

((SnoSno CHAR(5) NOT NULL UNIQUE,CHAR(5) NOT NULL UNIQUE,SnameSname CHAR(20),CHAR(20),SsexSsex CHAR(1),CHAR(1),Sage INT,Sage INT,SdeptSdept CHAR(15));CHAR(15));

if (if (sqlca.sqlcodesqlca.sqlcode >=0) >=0) /*Check success *//*Check success */printfprintf ((““Creation successfulCreation successful\\nn””););

elseelseprintfprintf ((““Creation unsuccessfulCreation unsuccessful\\nn””););

/* commit the transaction and disconnect from the db *//* commit the transaction and disconnect from the db */EXEC SQLEXEC SQL COMMIT WORK RELEASE;COMMIT WORK RELEASE;

Some comments for the exampleSome comments for the exampleEmbedded SQL statements start with keyword Embedded SQL statements start with keyword EXEC SQL EXEC SQL •• EXEC SQLEXEC SQL <<sqlsql语句语句>;>;

The embedded statements are same as ISQLThe embedded statements are same as ISQLConnect to databaseConnect to database•• EXEC SQLEXEC SQL CONECT TO db [AS connectCONECT TO db [AS connect--name] [USER name] [USER

useruser--name];name];Close database Close database •• EXEC SQLEXEC SQL COMMIT WORK RELEASECOMMIT WORK RELEASE•• EXEC SQLEXEC SQL DISCONNCET [connection]DISCONNCET [connection]

An embedded SQL statement can appear anywhere An embedded SQL statement can appear anywhere that an executable host language statement can that an executable host language statement can appearappear

Processing Programs with Embedded SQLProcessing Programs with Embedded SQLHost language

+ Embedded SQL

Preprocessor

Host language

+ Function Calls

Host Lang Compiler

Executable Host language

SQL Library

Embedded SQL Application Embedded SQL Application RunningRunning

Embedded SQL Application DBMS

Embedded SQL(1)Embedded SQL(1)

Types of embedded SQL:Types of embedded SQL:•• Static embedded SQL, where the entire Static embedded SQL, where the entire

SQL statement is known when the SQL statement is known when the program is writtenprogram is written

Select Select snosno, age from student, age from studentwhere dept=where dept=‘‘CSCS’’;;

Embedded SQL(2)Embedded SQL(2)

Types of embedded SQL:Types of embedded SQL:•• Dynamic embedded SQL, which allows all or Dynamic embedded SQL, which allows all or

part of the SQL statement to be specified at part of the SQL statement to be specified at runtimeruntime

Select Select snosno, age from student, age from studentwhere dept=where dept=‘‘????’’;;

>>> dept: CS >>> dept: CS Select Select snosno, age from student, age from studentwhere dept=where dept=‘‘CSCS’’;;

•• Dynamic SQL provides increased flexibility and Dynamic SQL provides increased flexibility and helps produce more generalhelps produce more general--purpose softwarepurpose software

Embedded SQL (3)Embedded SQL (3)

Without query results: embedded SQL Without query results: embedded SQL statements do not produce any query resultsstatements do not produce any query results•• NonNon--select statement, e.g. INSERT, UPDATE, select statement, e.g. INSERT, UPDATE,

DELETE, CREATE TABLE etc..DELETE, CREATE TABLE etc..

With query results: embedded SQL With query results: embedded SQL statements produce any query resultsstatements produce any query results•• Select statementSelect statement

Embedded SQL Statements with Embedded SQL Statements with query resultsquery results

SingleSingle--row queries, where the query result row queries, where the query result contains at most one row of datacontains at most one row of data•• Select * from student Select * from student

where where snosno==““S1S1””;;MultiMulti--row queries, where the query result row queries, where the query result may contain an arbitrary number of rows, may contain an arbitrary number of rows, which may be zero, one, more.which may be zero, one, more.•• Select * from studentSelect * from student

where age between 18 and 20;where age between 18 and 20;

Impedance Mismatch Impedance Mismatch

Host LanguageHost Language•• Variables Variables

Embedded SQLEmbedded SQL•• Single resultsSingle results•• Multiple ResultsMultiple Results•• System information, like System information, like ““ how many records how many records

returnedreturned””

Communication between Communication between Application vs. DBMSApplication vs. DBMS

DBMS( Embedded SQL)DBMS( Embedded SQL)

Sys infoSys info Single Single datadata

Multi Multi datadata

SQLCASQLCA

Host Host Lang Lang varvar

Single Single datadata

CursorCursor

ApplicatiApplication( Host on( Host language)language)

Communication between Communication between Application vs. DBMSApplication vs. DBMS

SQL Communication AreaSQL Communication Area•• DBMS information DBMS information applicationsapplications

Host Language variableHost Language variable•• Single data from DBMS to applicationsSingle data from DBMS to applications•• Single data from application to DBMSSingle data from application to DBMS

CurserCurser•• Multiple data from DBMS to applicationsMultiple data from DBMS to applications

SQL Communication Area(1)SQL Communication Area(1)The DBMS uses an SQL Communication Area (SQLCA) The DBMS uses an SQL Communication Area (SQLCA) to report runtime errors to the applicationto report runtime errors to the applicationSQLCA is a data structure that contains error variables SQLCA is a data structure that contains error variables and status indicatorsand status indicatorsAn application program can examine the SQLCA to An application program can examine the SQLCA to determine the success or failure of each SQL statementdetermine the success or failure of each SQL statementEXEC SQLEXEC SQL INCLUDE INCLUDE sqlcasqlca•• This tells the This tells the precompilerprecompiler to include the SQLCA data to include the SQLCA data

structure in the programstructure in the program

SQLCA for SQLCA for OracleOracle

SQL Communication Area(2)SQL Communication Area(2)

The most important part of the structure is the The most important part of the structure is the SQLCODE variableSQLCODE variableSQLCODE is set by DBMS as follows:SQLCODE is set by DBMS as follows:•• Zero: statements executed successful (maybe there Zero: statements executed successful (maybe there

warning message in warning message in sqlwarnsqlwarn•• Negative: error occurred. The value indicates Negative: error occurred. The value indicates

specific error that occurredspecific error that occurred•• Positive: statements executed successful, but an Positive: statements executed successful, but an

exceptional condition occurred exceptional condition occurred

SQL Communication Area(3)SQL Communication Area(3)The WHENEVER statementThe WHENEVER statement•• Oracle Oracle precompilerprecompiler provides an alternative method to simplify provides an alternative method to simplify

error handlingerror handling•• EXEC SQL WHENEVEREXEC SQL WHENEVER <condition> <action><condition> <action>•• The condition can be one of the following:The condition can be one of the following:

SQLERROR : SQLCODE <0SQLERROR : SQLCODE <0SQLWARNING: SQLCODE >0SQLWARNING: SQLCODE >0NOT FOUNDNOT FOUND

•• Action can be :Action can be :CONTINUE: to ignore the conditionCONTINUE: to ignore the conditionGOTO GOTO DO BREAKDO BREAKDO CONTINUEDO CONTINUESTOP: to rollback all STOP: to rollback all uncommiteduncommited work and terminate work and terminate progprog

SQL Communication Area(4)SQL Communication Area(4)ExampleExampleEXEC SQLEXEC SQL WHENEVER SQLERROR GOTO er1WHENEVER SQLERROR GOTO er1EXEC SQLEXEC SQL INSERT INTO student VALUES (INSERT INTO student VALUES (‘‘s1s1’’, ..), ..)EXEC SQLEXEC SQL INSERT INTO student VALUES (INSERT INTO student VALUES (‘‘s3s3’’, ..), ..)

Would be converted by the Would be converted by the precompilerprecompiler to:to:

EXEC SQLEXEC SQL INSERT INTO student VALUES (INSERT INTO student VALUES (‘‘s1s1’’, ..), ..)If (If (sqlca.sqlcodesqlca.sqlcode < 0) < 0) gotogoto er1er1EXEC SQLEXEC SQL INSERT INTO student VALUES (INSERT INTO student VALUES (‘‘s2s2’’, ..), ..)If (If (sqlca.sqlcodesqlca.sqlcode < 0) < 0) gotogoto er1er1

Host Language Variables(1)Host Language Variables(1)Host language variables can be used in Host language variables can be used in embedded SQL statements to transfer data embedded SQL statements to transfer data from database into the program, and vise from database into the program, and vise versaversaThey can be used in anywhere that a constant They can be used in anywhere that a constant can appear in SQL statementscan appear in SQL statementsThey can not be used to represent database They can not be used to represent database objects, such as table or column namesobjects, such as table or column names

Host Language Variables(2)Host Language Variables(2)

They are prefix ed by a colon(They are prefix ed by a colon( : ): )•• EXEC SQLEXEC SQL UPDATE student UPDATE student

SET age= SET age= ageage+ :increment+ :incrementWHERE SSN=WHERE SSN=““23452345””;;

Host language variables must be declared to Host language variables must be declared to SQL SQL •• EXEC SQLEXEC SQL BEGIN DECLARE SECTIONBEGIN DECLARE SECTION;;

float increment;float increment;EXEC SQLEXEC SQL END DECLARE SECTIONEND DECLARE SECTION;;

Host Language Variables(3)Host Language Variables(3)

主变量的类型主变量的类型── 输入主变量输入主变量

由应用程序对其赋值,由应用程序对其赋值,SQLSQL语句引用语句引用

── 输出主变量输出主变量

由由SQLSQL语句赋值或设置状态信息,返回给应用程序语句赋值或设置状态信息,返回给应用程序

── 一个主变量有可能既是输入主变量又是输出主一个主变量有可能既是输入主变量又是输出主

变量变量

Host Language Variables(4)Host Language Variables(4)

主变量的用途主变量的用途── 输入主变量输入主变量

指定向数据库中插入的数据指定向数据库中插入的数据

将数据库中的数据修改为指定值将数据库中的数据修改为指定值

指定执行的操作指定执行的操作

指定指定WHEREWHERE子句或子句或HAVINGHAVING子句中的条件子句中的条件

── 输出主变量输出主变量获取获取SQLSQL语句的结果数据语句的结果数据

获取获取SQLSQL语句的执行状态语句的执行状态

Host Language Variables(5)Host Language Variables(5)指示变量指示变量(indicator variable)(indicator variable)── Most programming languages do not provide Most programming languages do not provide

support for unknown or missing values, as support for unknown or missing values, as represented in database by nullsrepresented in database by nulls

一个主变量可以附带一个指示变量(一个主变量可以附带一个指示变量(Indicator Indicator VariableVariable)用于标明主变量的取值情况)用于标明主变量的取值情况

── 指示变量的用途指示变量的用途

输入主变量可以利用指示变量赋空值输入主变量可以利用指示变量赋空值

输出主变量可以利用指示变量检测出是否空值,值输出主变量可以利用指示变量检测出是否空值,值是否被截断是否被截断

Host Language Variables(6)Host Language Variables(6)The meaning of the indicator variable is as The meaning of the indicator variable is as follow:follow:•• 0 : associated host variable contains a valid 0 : associated host variable contains a valid

valuevalue•• --1 : associated host variable should be assumed 1 : associated host variable should be assumed

to contain a nullto contain a null•• >0 : associated host variable contains a >0 : associated host variable contains a validevalide

value, which may have been rounded or value, which may have been rounded or truncated ( host variable was not large enough truncated ( host variable was not large enough to hold the value)to hold the value)

Host Language Variables(7)Host Language Variables(7)

For example: to set the age of student For example: to set the age of student ““23452345”” to NULLto NULL•• EXEC SQL BEGIN DECLARE SECTION;EXEC SQL BEGIN DECLARE SECTION;

intint age;age;shortshort ageIndageInd;;

EXEC SQL END DECLARE SECTION;EXEC SQL END DECLARE SECTION;ageIndageInd ==--1;1;EXEC SQL UPDATE student EXEC SQL UPDATE student

SET age= :age :SET age= :age :ageIndageInd;;WHERE SSN= WHERE SSN= ““23452345””;;

Retrieving data Using Embedded Retrieving data Using Embedded SQL and Cursors (1)SQL and Cursors (1)

Most highMost high--level programming languages can level programming languages can process only individual data items or process only individual data items or individual rows of a structure whereas SQL individual rows of a structure whereas SQL can process multiple rows of data can process multiple rows of data To overcome the To overcome the impedance mismatchimpedance mismatch, SQL , SQL provides a mechanism for allowing the host provides a mechanism for allowing the host language to access the rows of a query result language to access the rows of a query result one at a time, one at a time, cursorcursor

Retrieving data Using Embedded Retrieving data Using Embedded SQL and Cursors (2)SQL and Cursors (2)

什么是游标什么是游标── 游标是系统为用户开设的一个数据缓冲区,存放游标是系统为用户开设的一个数据缓冲区,存放

SQLSQL语句的执行结果语句的执行结果

── 每个游标区都有一个名字每个游标区都有一个名字

── 用户可以用用户可以用SQLSQL语句逐一从游标中获取记录,并语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理赋给主变量,交由主语言进一步处理

用户空间 系统空间

用户变量

cursor result

Embedded SQL divides queries into two Embedded SQL divides queries into two groups:groups:•• SingleSingle--row queriesrow queries

Host variable Host variable

•• MultiMulti--row queriesrow queriescursorcursor

SingleSingle--row Queries(1)row Queries(1)In embedded SQL, singleIn embedded SQL, single--row queries are handled row queries are handled by the singleton select statement. by the singleton select statement. 语句格式:语句格式:EXEC SQLEXEC SQL SELECT [ALL|DISTINCT] <SELECT [ALL|DISTINCT] <目标列表达式目标列表达式

>[,<>[,<目标列表达式目标列表达式>]...>]...INTO <INTO <主变量主变量>[<>[<指示变量指示变量>][,<>][,<主变量主变量>[<>[<指示指示

变量变量>]]... >]]... FROM <FROM <表名或视图名表名或视图名>[,<>[,<表名或视图名表名或视图名>] ...>] ...[WHERE <[WHERE <条件表达式条件表达式>]>][GROUP BY <[GROUP BY <列名列名1> [HAVING <1> [HAVING <条件表达式条件表达式>]]>]][ORDER BY <[ORDER BY <列名列名2> [ASC|DESC]];2> [ASC|DESC]];

SingleSingle--row Queries(2)row Queries(2)── 对交互式对交互式SELECTSELECT语句的扩充就是多了一个语句的扩充就是多了一个

INTOINTO子句子句

把从数据库中找到的符合条件的记录,放到把从数据库中找到的符合条件的记录,放到INTOINTO子句指出的主变量中去。子句指出的主变量中去。

使用注意事项使用注意事项── 1. 1. 使用主变量使用主变量

INTOINTO子句子句

WHEREWHERE子句的条件表达式子句的条件表达式

HAVINGHAVING短语的条件表达式短语的条件表达式

SingleSingle--row Queries(3)row Queries(3)

── 2. 2. 使用指示变量使用指示变量

指示变量只能用于指示变量只能用于INTOINTO子句中子句中

如果如果INTOINTO子句中主变量后面跟有指示变量,则当子句中主变量后面跟有指示变量,则当

查询得出的某个数据项为空值时,系统会自动将相查询得出的某个数据项为空值时,系统会自动将相应主变量后面的指示变量置为负值,但不向该主变应主变量后面的指示变量置为负值,但不向该主变量执行赋值操作,即主变量值仍保持执行量执行赋值操作,即主变量值仍保持执行SQLSQL语句语句

之前的值之前的值

当发现指示变量值为负值时,不管主变量为何值,当发现指示变量值为负值时,不管主变量为何值,均应认为主变量值为均应认为主变量值为NULLNULL

SingleSingle--row Queries(4)row Queries(4)

── 3. 3. 查询结果为空集查询结果为空集

如果数据库中没有满足条件的记录,即查询如果数据库中没有满足条件的记录,即查询结果为空,则结果为空,则DBMSDBMS将将SQLCODESQLCODE的值置为的值置为100100。。??((查查SQL92SQL92标准标准))

── 4. 4. 查询结果为多条记录查询结果为多条记录

程序出错,程序出错,DBMSDBMS会在会在SQLCASQLCA中返回错误中返回错误

信息信息

/* Program to print out student table *//* Program to print out student table */#include <#include <stdio.hstdio.h>>#include <#include <std;ib.hstd;ib.h>>EXEC SQLEXEC SQL INCLUDE INCLUDE sqlcasqlca;;Main()Main(){{

EXEC SQLEXEC SQL BEIGIN DECLARE SECTIONBEIGIN DECLARE SECTION;;char char ssn[6];ssn[6];charchar name[16];name[16];intint age;age;shortshort ageindageind;;char char *username = *username = ““ Manager/ManagerManager/Manager””;;char char *connect String= *connect String= ““CollegeCollege””

EXEC SQL END DECLARE SECTIONEXEC SQL END DECLARE SECTION;;/* prompt for /* prompt for ssnssn number */number */

printfprintf ((““Enter Enter ssnssn number:number:””););scanfscanf ((““%d%d””, , ssnssn););

/* connect to database*//* connect to database*/EXEC SQL CONNECTEXEC SQL CONNECT :username :username USINGUSING ::connectStringconnectStringif (if (sqlca.sqlcodesqlca.sqlcode < 0 ) exit (< 0 ) exit (--1);1);

/* Establish SQL error handling prior to executing SELECT *//* Establish SQL error handling prior to executing SELECT */EXEC SQL WHENEVER SQLERROR GOTO error;EXEC SQL WHENEVER SQLERROR GOTO error;EXEC SQL WHENEVER NOT FOUND GOTO done;EXEC SQL WHENEVER NOT FOUND GOTO done;

EXEC SQL SELECT EXEC SQL SELECT ssn,name,sgessn,name,sge INTO :INTO :ssnssn, :name, :, :name, :age:ageIndage:ageIndFROM studentFROM studentWHERE WHERE ssnssn=:=:ssnssn

/* display data *//* display data */printfprintf ((““ Name: Name: %s %s \\nn””, name);, name);if (if (ageIndageInd < 0) < 0)

printfprintf ((““Age:Age: NULLNULL\\nn””););elseelse

printfprintf (Age:(Age: %%ss\\nn””, age), age)gotogoto finishedfinished

/*Error condition /*Error condition ––print out error */print out error */error:error:

printfprintf ((““SQL error %SQL error %dd\\nn””, , sqlca.sqlcodesqlca.sqlcode););gotogoto finished;finished;

done:done:printf(printf(““NoNo student with specified numberstudent with specified number\\nn””););

/* Finally, disconnect from the database *//* Finally, disconnect from the database */EXEC SQL WHENEVER SQLERROR continue;EXEC SQL WHENEVER SQLERROR continue;EXEC SQLEXEC SQL COMMIT WORK RELEASECOMMIT WORK RELEASE;;

}}

SingleSingle--row Queries(7)row Queries(7)

从提高应用程序的数据独立性角度考虑,从提高应用程序的数据独立性角度考虑,SELECTSELECT语句在任何情况下都应该使用游标语句在任何情况下都应该使用游标

── 对于仅返回一行结果数据的对于仅返回一行结果数据的SELECTSELECT语句虽然语句虽然可以不使用游标可以不使用游标, , 但如果以后数据库改变了,但如果以后数据库改变了,该该SELECTSELECT语句可能会返回多行数据,这时该语句可能会返回多行数据,这时该

语句就会出错语句就会出错

MultiMulti--row Queries(1)row Queries(1)

When a database can return an arbitrary When a database can return an arbitrary number of rows, embedded SQL use number of rows, embedded SQL use cursorscursorsto return the data.to return the data.In effect, the cursor acts as a pointer to a In effect, the cursor acts as a pointer to a particular row of the query resultparticular row of the query resultCursor must be Cursor must be declareddeclared and and openedopened before before it can be used, and it must be it can be used, and it must be closedclosed to to deactivate it. deactivate it.

MultiMulti--row Queries(2)row Queries(2)

使用游标的步骤使用游标的步骤── 1. 1. 说明游标说明游标 DECLAREDECLARE── 2. 2. 打开游标打开游标 OPENOPEN── 3. 3. 移动游标指针,然后取当前记录移动游标指针,然后取当前记录 FETCHFETCH── 4. 4. 关闭游标关闭游标 CLOSECLOSE

1. 1. 说明游标说明游标使用使用DECLAREDECLARE语句语句

语句格式语句格式EXEC SQLEXEC SQL DECLARE <DECLARE <游标名游标名> CURSOR FOR > CURSOR FOR <SELECT<SELECT语句语句>;>;

功能功能── 是一条说明性语句,这时是一条说明性语句,这时DBMSDBMS并不执行并不执行SELECTSELECT指指

定的查询操作。定的查询操作。

For exampleFor example•• EXEC SQL DECLAREEXEC SQL DECLARE student CURSOR FORstudent CURSOR FOR

SELECT SELECT ssnssn, name, age, name, ageFROM studentFROM studentWHERE WHERE ssnssn==‘‘ 23452345’’

2. 2. 打开游标打开游标

使用使用OPENOPEN语句语句

语句格式语句格式EXEC SQLEXEC SQL OPEN <OPEN <游标名游标名>;>;

功能功能── 打开游标实际上是执行相应的打开游标实际上是执行相应的SELECTSELECT语句,把所有语句,把所有满足查询条件的记录从指定表取到缓冲区中满足查询条件的记录从指定表取到缓冲区中

── 这时游标处于活动状态,指针指向查询结果集中第一这时游标处于活动状态,指针指向查询结果集中第一条记录之前条记录之前

For exampleFor example•• EXEC SQL OPEN EXEC SQL OPEN studentCursorstudentCursor

3. 3. 读取当前记录读取当前记录

使用使用FETCHFETCH语句语句

语句格式语句格式EXEC SQL FETCH [[NEXT|PRIOR|FIRST|LAST] EXEC SQL FETCH [[NEXT|PRIOR|FIRST|LAST] FROM] <FROM] <游标名游标名> >

INTO <INTO <主变量主变量>[<>[<指示变量指示变量>][,<>][,<主变量主变量>[<>[<指示变指示变量量>]]...;>]]...;

For exampleFor example•• EXEC SQL FETCH EXEC SQL FETCH studentCursorstudentCursor

INTO :INTO :ssnssn, :name, :age, :name, :age

3. 3. 读取当前记录读取当前记录(续)(续)

功能功能── 指定方向推动游标指针,然后将缓冲区中的当前记录指定方向推动游标指针,然后将缓冲区中的当前记录

取出来送至主变量供主语言进一步处理。取出来送至主变量供主语言进一步处理。

── NEXT|PRIOR|FIRST|LASTNEXT|PRIOR|FIRST|LAST::指定推动游标指针的方指定推动游标指针的方

式。式。NEXTNEXT::向前推进一条记录向前推进一条记录

PRIORPRIOR::向回退一条记录向回退一条记录

FIRSTFIRST::推向第一条记录推向第一条记录

LASTLAST::推向最后一条记录推向最后一条记录

缺省值为缺省值为NEXTNEXT

3. 3. 读取当前记录读取当前记录(续)(续)

说明说明── (1) (1) 主变量必须与主变量必须与SELECTSELECT语句中的目标列表语句中的目标列表达式具有一一对应关系达式具有一一对应关系

── (2) FETCH(2) FETCH语句通常用在一个循环结构中,通语句通常用在一个循环结构中,通过循环执行过循环执行FETCHFETCH语句逐条取出结果集中的行语句逐条取出结果集中的行进行处理进行处理

── (3)(3)当没有记录可读时当没有记录可读时, SQLCODE , SQLCODE 设置为设置为NOT FOUND. (NOT FOUND. (问题问题: : 若查询结果为空若查询结果为空, , SQLCODESQLCODE设为何值设为何值?)?)

── (4) (4) 为进一步方便用户处理数据,现在一些关为进一步方便用户处理数据,现在一些关系数据库管理系统对系数据库管理系统对FETCHFETCH语句做了扩充,允语句做了扩充,允许用户向任意方向以任意步长移动游标指针许用户向任意方向以任意步长移动游标指针

4. 4. 关闭游标关闭游标

使用使用CLOSECLOSE语句语句

语句格式语句格式EXEC SQL CLOSE <EXEC SQL CLOSE <游标名游标名>;>;

功能功能── 关闭游标,释放结果集占用的缓冲区及其他资源关闭游标,释放结果集占用的缓冲区及其他资源

说明说明── 游标被关闭后,就不再和原来的查询结果集相联系游标被关闭后,就不再和原来的查询结果集相联系

── 被关闭的游标可以再次被打开,与新的查询结果相联被关闭的游标可以再次被打开,与新的查询结果相联系系

/* Program to print out student table *//* Program to print out student table */#include <#include <stdio.hstdio.h>>#include <#include <std;ib.hstd;ib.h>>EXEC SQLEXEC SQL INCLUDE INCLUDE sqlcasqlca;;Main()Main(){{

EXEC SQLEXEC SQL BEIGIN DECLARE SECTIONBEIGIN DECLARE SECTION;;char char ssn[6];ssn[6];charchar name[16];name[16];intint age;age;shortshort ageindageind;;char char *username = *username = ““ Manager/ManagerManager/Manager””;;char char *connect String= *connect String= ““CollegeCollege””

EXEC SQL END DECLARE SECTIONEXEC SQL END DECLARE SECTION;;/* prompt for /* prompt for ssnssn number */number */

printfprintf ((““Enter student name:Enter student name:””););scanfscanf ((““%s%s””, name);, name);

/* connect to database*//* connect to database*/EXEC SQL CONNECTEXEC SQL CONNECT :username :username USINGUSING ::connectStringconnectStringif (if (sqlca.sqlcodesqlca.sqlcode < 0 ) exit (< 0 ) exit (--1);1);

/* Establish SQL error handling prior to executing SELECT *//* Establish SQL error handling prior to executing SELECT */EXEC SQL WHENEVER SQLERROR GOTO error;EXEC SQL WHENEVER SQLERROR GOTO error;EXEC SQL WHENEVER NOT FOUND GOTO done;EXEC SQL WHENEVER NOT FOUND GOTO done;

EXEC SQL DECLARE EXEC SQL DECLARE studentCursorstudentCursor CURSOR FORCURSOR FORSELECT SELECT ssn,name,sgessn,name,sgeFROM studentFROM studentWHERE name=:nameWHERE name=:nameORDER BY ORDER BY ssnssn;;

/* Open the cursor to start of selection, then loop to fetch row/* Open the cursor to start of selection, then loop to fetch row*/*/EXEC SQL OPEN student Cursor;EXEC SQL OPEN student Cursor;

for ( ; ; ) {for ( ; ; ) {

/* Fetch next row of the result table *//* Fetch next row of the result table */EXEC SQL FETCH student Cursor EXEC SQL FETCH student Cursor INTO :INTO :ssnssn, :name, :, :name, :age:ageIndage:ageInd

/* display data *//* display data */printfprintf ((““Student Student numnernumner %%ss\\nn””, , ssnssn))printfprintf ((““ Name: Name: %s %s \\nn””, name);, name);if (if (ageIndageInd < 0) < 0)

printfprintf ((““Age:Age: NULLNULL\\nn””););elseelse

printfprintf (Age:(Age: %%ss\\nn””, age), age)

}}

/*Error condition /*Error condition ––print out error */print out error */error: error:

printfprintf ((““SQL error %SQL error %dd\\nn””, , sqlca.sqlcodesqlca.sqlcode););gotogoto finished;finished;

done:done:/* Close the cursor before completing*//* Close the cursor before completing*/

EXEC SQLEXEC SQL WHENEVER SQLERROR continue;WHENEVER SQLERROR continue;EXEC SQLEXEC SQL CLOSE CLOSE studentCursorstudentCursor;;EXEC SQLEXEC SQL COMMIT WORK RELEASECOMMIT WORK RELEASE;;

}}

DECLARE CURSOR C1

OPEN C1

FOR(;;) {

FETCH C1}

CLOSE

SERVERCLIENT

PARSE

OPT

EXECUTE

LLLMMMNNNBBB

YYYHHHJJJJKKLLL

MMMNNNBBB

YYYHHHJJJJKK

Using Cursor to Modify Data(1)Using Cursor to Modify Data(1)

A cursor is either A cursor is either readonlyreadonly or updatableor updatableIf the table/view identified by a cursor is not If the table/view identified by a cursor is not updatable then the cursor is updatable then the cursor is readonlyreadonly; ; otherwise, the cursor is updatable, otherwise, the cursor is updatable, positioned UPDAT and DELETE positioned UPDAT and DELETE CURRENT statements can be used.CURRENT statements can be used.

Using Cursor to Modify Data(1)Using Cursor to Modify Data(1)

To update data through a cursor in Oracle To update data through a cursor in Oracle requires a minor extension to DECLARE requires a minor extension to DECLARE CURSOR statementCURSOR statementEXEC SQL DECLAREEXEC SQL DECLARE cursorNamecursorNameCURSOR FORCURSOR FOR selectStatementselectStatementFOR UPDATE OFFOR UPDATE OF columnNamecolumnName[,[,……]]EXEC SQL UPDATEEXEC SQL UPDATE TableNameTableName

SET SET columnNamecolumnName==dataValuedataValue[,[,……]]WHERE CURRENT OF WHERE CURRENT OF cursorNamecursorName

Using Cursor to Modify Data(2)Using Cursor to Modify Data(2)

The update does not advance the cursor, The update does not advance the cursor, and so another FETCH must be performed and so another FETCH must be performed to move the cursor forward to the next rowto move the cursor forward to the next rowDELETEDELETE•• EXEC SQLEXEC SQL DELETE FROM DELETE FROM TableNameTableName

WHERE WHERE CURRENT OFCURRENT OF cursorNamecursorName

Dynamic SQL(1)Dynamic SQL(1)

Static SQLStatic SQL•• Allowing access to the database using the Allowing access to the database using the

normal interactive SQL statements, with normal interactive SQL statements, with minor modifications in some cases. minor modifications in some cases.

•• The pattern of database access is fixed The pattern of database access is fixed and can be and can be ‘‘hardhard--codedcoded’’ into the programinto the program

Dynamic SQLDynamic SQL•• There are many situations where the There are many situations where the

pattern of database access is not fixed and pattern of database access is not fixed and is known only at runtimeis known only at runtime

Dynamic SQL(2)Dynamic SQL(2)The basic difference between the two types of The basic difference between the two types of embedded SQL is Static SQL does not allow host embedded SQL is Static SQL does not allow host variables to be used in place of table names or variables to be used in place of table names or column namescolumn names•• For example, in static SQL we can not write:For example, in static SQL we can not write:•• EXEC SQL BEGIN DECLARE SECTIONEXEC SQL BEGIN DECLARE SECTION

char TableName[20];char TableName[20];EXEC SQL END DECLARE SECTION;EXEC SQL END DECLARE SECTION;EXEC SQL INSERT INTO :EXEC SQL INSERT INTO :TableNameTableName

VALUES (VALUES (““S1S1””, , ““SimthSimth””, 24), 24)•• EXEC SQL DECLARE cursor1 CURSOR FOREXEC SQL DECLARE cursor1 CURSOR FOR

SELECT * FROM :SELECT * FROM :TableNameTableName

Dynamic SQL(3)Dynamic SQL(3)

ProblemsProblems•• ““**”” indicates that all columns from the table, indicates that all columns from the table,

TableNameTableName, but the number of columns will , but the number of columns will vary with the choice of table.vary with the choice of table.

•• Data types of the columns will vary between Data types of the columns will vary between tablestables

•• But if we do not know the number and data But if we do not know the number and data type, we can not use FETCH statementtype, we can not use FETCH statement

Dynamic SQL can overcome these problems Dynamic SQL can overcome these problems and allow more generaland allow more general--purpose software to purpose software to be developedbe developed

The EXECUTE IMMEDIATE The EXECUTE IMMEDIATE Statement(1)Statement(1)

The basic idea of dynamic SQL is to place The basic idea of dynamic SQL is to place the complete SQL statement to be executed the complete SQL statement to be executed in a host variable. The host variable is then in a host variable. The host variable is then passed to the DBMS to be executedpassed to the DBMS to be executedThe simplest way to do this for statement The simplest way to do this for statement that do not involve SELECT is:that do not involve SELECT is:EXEC SQL EXECUTE IMMEDIATE [EXEC SQL EXECUTE IMMEDIATE [hostVariablehostVariable | | stringLiteralstringLiteral ]]

This command allows the SQL statement This command allows the SQL statement stored in stored in hostVariablehostVariable, or in the literal, , or in the literal, stringLiteralstringLiteral

The EXECUTE IMMEDIATE The EXECUTE IMMEDIATE Statement(1)Statement(1)

For example,For example,Static SQL:Static SQL:

EXEC SQL BEGIN DECLARE SECTIONEXEC SQL BEGIN DECLARE SECTIONfloat increment;float increment;

EXEC SQL END DECLARE SECTIONEXEC SQL END DECLARE SECTIONEXEC SQL UPDATE staff SET salary=EXEC SQL UPDATE staff SET salary=salary+:incrementsalary+:increment

WHERE WHERE staffNostaffNo==““SL21SL21””

Dynamic SQL:Dynamic SQL:EXEC SQL BEGIN DECLARE SECTION;EXEC SQL BEGIN DECLARE SECTION;

char buffer[100];char buffer[100];EXEC SQL END DECLARE SECTION;EXEC SQL END DECLARE SECTION;

sprintfsprintf (buffer, (buffer, ““ UPDATE staff SET salary = UPDATE staff SET salary = salarysalary + %f+ %fWHERE WHERE staffNostaffNo==‘‘SL21SL21’’ ””, increment);, increment);

EXEC SQL EXECUTE IMMEDIATE :buffer;EXEC SQL EXECUTE IMMEDIATE :buffer;

PREPARE and EXECUTE PREPARE and EXECUTE statementsstatements

Every time EXECUTE IMMEDIATE statement is Every time EXECUTE IMMEDIATE statement is processed, the DBMS must parse, validate and processed, the DBMS must parse, validate and optimize the statement, build an execution plan optimize the statement, build an execution plan for the statement and finally execute the plan.for the statement and finally execute the plan.However, if the SQL statement is executed many However, if the SQL statement is executed many times, then this command is not particularly times, then this command is not particularly efficient.efficient.Dynamic SQL provides an alternative approach Dynamic SQL provides an alternative approach for SQL statement that may be executed more for SQL statement that may be executed more than once using two complementary statementsthan once using two complementary statements•• PREPARE statement FROM [PREPARE statement FROM [hostVar|stringhostVar|string]]•• EXECUTE statement USING EXECUTE statement USING hostVarhostVar

PREPARE and EXECUTE PREPARE and EXECUTE These two statements used together not only These two statements used together not only improve the performance of executing an SQL improve the performance of executing an SQL statement that is used more than once, but also statement that is used more than once, but also provide additional functionality through the provide additional functionality through the USING USING hostVariablehostVariable clause of EXECUTE clause of EXECUTE statementstatementUSING USING hostVariablehostVariable clause allows parts of clause allows parts of prepared statement to be unspecified, replaced prepared statement to be unspecified, replaced instead by instead by placeholdersplaceholdersA placeholder is a dummy host variable that can A placeholder is a dummy host variable that can appear anywhere in the appear anywhere in the hostVar|stringLithostVar|stringLit of the of the PREPARE statementPREPARE statementA placeholder does not need to be declared and A placeholder does not need to be declared and can be given any name. It signals to DBMS that a can be given any name. It signals to DBMS that a value will be supplied later.value will be supplied later.

PREPARE and EXECUTEPREPARE and EXECUTEEXEC SQL BEGIN DECLARE SECTIONEXEC SQL BEGIN DECLARE SECTION;;

char buffer[100];char buffer[100];float float newSalarynewSalary;;char staffNo[6];char staffNo[6];

EXEC SQL END DECLARE SECTIONEXEC SQL END DECLARE SECTION;;sprintfsprintf (buffer, (buffer, ““ UPDATE staff SET salary = UPDATE staff SET salary = ::salsal WHERE WHERE

staffNostaffNo= = ::snsn ””););EXEC SQL PREPARE stmt FROM :buffer;EXEC SQL PREPARE stmt FROM :buffer;do { do { printfprintf( ( ““Enter staff number:Enter staff number:””););scanfscanf ( ( ““%s%s””, , staffNostaffNo););printfprintf( ( ““Enter new salaryEnter new salary””););scanfscanf ((““%f%f””, , newSalarynewSalary););EXEC SQL EXECUTE stmt USING :EXEC SQL EXECUTE stmt USING :newSalarynewSalary, :, :staffNostaffNo;;printfprintf ((““ Enter Enter another(Yanother(Y/N)?;/N)?;scanfscanf ((““%c%c””, more);, more);}}until ( more != until ( more != ‘‘YY’’););

In this example, dummy host In this example, dummy host varvar salsal and and snsn are are placeholderplaceholder

小结小结

嵌入式嵌入式SQLSQL语句与主语言之间的通信语句与主语言之间的通信

── 在嵌入式在嵌入式SQLSQL中,中,SQLSQL语句与主语语句与主语

言语句分工非常明确言语句分工非常明确

SQLSQL语句:直接与数据库打交道语句:直接与数据库打交道

主语言语句主语言语句

1. 1. 控制程序流程控制程序流程

2. 2. 对对SQLSQL语句的执行结果做进一语句的执行结果做进一

步加工处理步加工处理

小结小结((续续))主变量主变量── SQLSQL语句用主变量从主语言中接收执行参数,操纵数据语句用主变量从主语言中接收执行参数,操纵数据

库库

── 如果如果SQLSQL语句从数据库中成功地检索出数据,则通过主语句从数据库中成功地检索出数据,则通过主

变量传给主语言做进一步处理变量传给主语言做进一步处理

SQLCASQLCA── SQLSQL语句的执行状态由语句的执行状态由DBMSDBMS送至送至SQLCASQLCA中中

── 主语言程序从主语言程序从SQLCASQLCA中取出状态信息,据此决定下一步中取出状态信息,据此决定下一步

操作操作

游标游标── SQLSQL语言和主语言的不同数据处理方式通过游标来协调语言和主语言的不同数据处理方式通过游标来协调

Static versus Dynamic SQLStatic versus Dynamic SQL

The Open Database Connectivity The Open Database Connectivity Standard(1)Standard(1)

An alternative approach to embedding SQL An alternative approach to embedding SQL statements directly in a host language is to statements directly in a host language is to provide programmers with a library of provide programmers with a library of functions that can be invoked from the functions that can be invoked from the application software.application software.For many programmers, the use of library For many programmers, the use of library routines is standard practice, and they find routines is standard practice, and they find API a relatively straightforward way to use API a relatively straightforward way to use SQLSQL

The Open Database Connectivity The Open Database Connectivity Standard(2)Standard(2)

The API consists of a set of library function The API consists of a set of library function for many of the common types of database for many of the common types of database access that programmers required, such as access that programmers required, such as connecting to a database, executing SQL, connecting to a database, executing SQL, retrieving individual rows of a result tableretrieving individual rows of a result tableOne problem with this approach has been One problem with this approach has been lack of interoperabilitylack of interoperability•• Programs have to be processed using the DBMS Programs have to be processed using the DBMS

vendorvendor’’s s precompilerprecompiler and linked with this and linked with this vendorvendor’’s API librarys API library

•• That will produces DBMSThat will produces DBMS--specific code for specific code for each DBMS they want to accesseach DBMS they want to access

The Open Database Connectivity The Open Database Connectivity Standard(3)Standard(3)

In an attempt to standardize this approach, In an attempt to standardize this approach, Microsoft produced the Open Database Microsoft produced the Open Database Connectivity (ODBC) standardConnectivity (ODBC) standardODBC technology provides a common ODBC technology provides a common interface for accessing heterogeneous SQL interface for accessing heterogeneous SQL database, based on SQL as the standard for database, based on SQL as the standard for accessing dataaccessing dataThis interface provides a high degree of This interface provides a high degree of interoperatibilityinteroperatibility::•• A single application can access different SQL A single application can access different SQL

DBMSsDBMSs through a common set of codethrough a common set of code

The Open Database Connectivity The Open Database Connectivity Standard(4)Standard(4)

ODBC has emerged as a ODBC has emerged as a de factode facto industry standard. One industry standard. One reason for ODBC popularity is its flexibilityreason for ODBC popularity is its flexibility•• Application are not tied to a proprietary vendor APIApplication are not tied to a proprietary vendor API•• SQL statements can be explicitly included in source code or SQL statements can be explicitly included in source code or

constructed dynamically at runtime;constructed dynamically at runtime;•• An application can ignore the underlying data communications An application can ignore the underlying data communications

protocols;protocols;•• ODBC is designed in conjunction with the X/Open and ISO ODBC is designed in conjunction with the X/Open and ISO

CallCall--Level Interface (CLI) standardLevel Interface (CLI) standard•• There are ODBC database drivers available today for many of There are ODBC database drivers available today for many of

most popular most popular DBMSsDBMSs

ODBC Architecture(1)ODBC Architecture(1)

The ODBC interface defines the following:The ODBC interface defines the following:•• A library of function calls that allow an A library of function calls that allow an

application to connect to a DBMS, execute SQL application to connect to a DBMS, execute SQL statement, and retrieve results;statement, and retrieve results;

•• A standard way to connect and log on to a DBMSA standard way to connect and log on to a DBMS•• A standard representation of data typesA standard representation of data types•• A standard set of error codesA standard set of error codes•• SQL syntax based on the X/Open and ISO CallSQL syntax based on the X/Open and ISO Call--

Level Interface (CLI) specificationLevel Interface (CLI) specification

ODBC Architecture(2)ODBC Architecture(2)

The ODBC architecture has four components:The ODBC architecture has four components:•• ApplicationApplication•• Driver ManagerDriver Manager•• Driver and Database AgentDriver and Database Agent•• Data SourceData Source

ODBC Architecture(3)ODBC Architecture(3)

Application

Driver Manager

Driver Driver Driver

Data source

Data source

Data source

Data source

Data source

Data source

Application

Driver Manager

Driver

ODBC interface

Multiple drivers Single drivers

ODBC Conformance LevelsODBC Conformance LevelsODBC defines two different conformance levels ODBC defines two different conformance levels for drivers:for drivers:•• ODBC APIODBC API•• ODBC SQLODBC SQL

ODBC defines a core grammar that corresponds ODBC defines a core grammar that corresponds to the to the •• X/Open CAE specification (1992)X/Open CAE specification (1992)•• ISO CLI specification (1995)ISO CLI specification (1995)

ODBC 3.0 fully implements both these ODBC 3.0 fully implements both these specifications and adds features commonly needed specifications and adds features commonly needed by developers of screenby developers of screen--based database based database applications, such as scrollable cursorapplications, such as scrollable cursor

ODBC SQL Conformance Levels(1)ODBC SQL Conformance Levels(1)Minimum SQL grammarMinimum SQL grammar•• DDL: DDL:

CREATE TABLE CREATE TABLE DROP TABLEDROP TABLE

•• DML:DML:Simple SELECTSimple SELECTINSERT, UPDATE SEARCHED, DELETE INSERT, UPDATE SEARCHED, DELETE SEARCHEDSEARCHED

•• Expressions: simple ( such as A > B+C )Expressions: simple ( such as A > B+C )•• Data TypeData Type

CHAR, VARCHAR, LONG VARCHARCHAR, VARCHAR, LONG VARCHAR

ODBC SQL Conformance Levels(2)ODBC SQL Conformance Levels(2)Core SQL grammarCore SQL grammar•• Minimum SQL grammar and data typesMinimum SQL grammar and data types•• DDL: DDL:

ALTER TABLE, CREATE INDEX, DROP INDEX, ALTER TABLE, CREATE INDEX, DROP INDEX, CREATE VIEW, DROP VIEW, GRANT, REVOKE CREATE VIEW, DROP VIEW, GRANT, REVOKE

•• DML:DML:Full SELECTFull SELECT

•• Expressions: Expressions: subquerysubquery, set function, set function•• Data TypeData Type

DECIMAL, NUMBER, SMALLINT, INTEGER, DECIMAL, NUMBER, SMALLINT, INTEGER, REAL, FLOAT, DOUBLE PRECISIONREAL, FLOAT, DOUBLE PRECISION

ODBC SQL Conformance Levels(3)ODBC SQL Conformance Levels(3)Extended SQL grammarExtended SQL grammar•• Minimum and core SQL grammar and data Minimum and core SQL grammar and data

typestypes•• DML:DML:

Outer joins, positioned UPDATE, positioned Outer joins, positioned UPDATE, positioned DELETE, SELECT FOR UPDATE, unionDELETE, SELECT FOR UPDATE, union

•• Expressions: scalar functions such as Expressions: scalar functions such as SUBSTRING and ABS, date, timeSUBSTRING and ABS, date, time

•• Data TypeData TypeBIT, TINYBIT, BIGING, BINARY, VARBINARY, BIT, TINYBIT, BIGING, BINARY, VARBINARY, LONG VARBINARY, DATE, TIME, TIMESTAMPLONG VARBINARY, DATE, TIME, TIMESTAMP

•• Batch SQL statementsBatch SQL statements•• Procedure callsProcedure calls

Using ODBC(1)Using ODBC(1)Allocate an environment handle through the Allocate an environment handle through the call to call to SQLAllocEnvSQLAllocEnv(), which allocates (), which allocates memory for the handle and initialize the memory for the handle and initialize the ODBC CallODBC Call--Level Interface for use by the Level Interface for use by the applicationapplicationAllocate a connection handle through the Allocate a connection handle through the call to call to SQLAllocConnectSQLAllocConnect(). A connection (). A connection consists of a driver and a data source. A consists of a driver and a data source. A connection handle identifies each connection connection handle identifies each connection and identifies which driver to use and which and identifies which driver to use and which data source to use with that driver.data source to use with that driver.

Using ODBC (2)Using ODBC (2)Connect to the data source using Connect to the data source using SQLConnectSQLConnect(). This call loads a driver and (). This call loads a driver and establishes a connection to the named data establishes a connection to the named data source.source.Allocate a statement handle using Allocate a statement handle using SQLAllocStmtSQLAllocStmt(). A statement handle (). A statement handle references statement information such as references statement information such as network information, SQLSTATE values and network information, SQLSTATE values and error messages, cursor name, number of result error messages, cursor name, number of result set columnsset columnsOn completion, all handles must be freed and On completion, all handles must be freed and the connection to the data source terminatedthe connection to the data source terminated

intint Getdata_ODBC(Mo_infor_quadGetdata_ODBC(Mo_infor_quad**pdata[ROUTENUMBER],intpdata[ROUTENUMBER],int rmpidrmpid))

{{HENV HENV henvhenv;;HDBC HDBC hdbchdbc;;HSTMT HSTMT hstmthstmt;;RETCODE RETCODE rcrc;;UCHARUCHAR selStmt[500];selStmt[500];UCHARUCHAR sName[6]sName[6]SDWORDSDWORD sNameLensNameLen;;

rcrc==SQLAllocEnv(&henvSQLAllocEnv(&henv);); /* allocate an environment /* allocate an environment handle */handle */rcrc==SQLAllocConnect(henv,&hdbcSQLAllocConnect(henv,&hdbc););/* allocate a connection /* allocate a connection handle */handle */rcrc==SQLConnect(hdbcSQLConnect(hdbc,,

(unsigned char *)"SQL Server Source", SQL_NTS,/* (unsigned char *)"SQL Server Source", SQL_NTS,/* data source name */data source name */

(unsigned char *)"(unsigned char *)"rdingrding", SQL_NTS,", SQL_NTS, /* user /* user identifier */identifier */

(unsigned char *)(unsigned char *)““1234",SQL_NTS);1234",SQL_NTS); /* password /* password */*/

/* Note, SQL_NTS directs the driver to determine the length /* Note, SQL_NTS directs the driver to determine the length of the string by locating the nullof the string by locating the null--termination character */termination character */

if ( if ( rcrc==SQL_SUCCESS|| ==SQL_SUCCESS|| rcrc == SQL_SUCCESS_WITH_INFO) == SQL_SUCCESS_WITH_INFO) {{rcrc==SQLAllocStmt(SQL_HANDLE_STMT,hdbc,&hstmtSQLAllocStmt(SQL_HANDLE_STMT,hdbc,&hstmt); ); /* /*

allocate statement handle */allocate statement handle */

/* Now set up the SELECT statement, execute it, and then bind th/* Now set up the SELECT statement, execute it, and then bind the columns of the e columns of the result set */result set */lstrcp(selStmtlstrcp(selStmt, , ““ SELECT name from students WHERE SSN = SELECT name from students WHERE SSN = ‘‘23452345’”’”););

if ( if ( SQLExecDirect(hStmtSQLExecDirect(hStmt, , selStmtselStmt, SQL_NTS) != SQL_SUCCESS), SQL_NTS) != SQL_SUCCESS)exit(exit(--1);1);

SQLBindCol(hStmtSQLBindCol(hStmt, 1, SQL_C_CHAR, , 1, SQL_C_CHAR, sNamesName, (, (SDWORD)sizeof(sNameSDWORD)sizeof(sName), &), &sNameLensNameLen););

/* Now fetch the result set, row by row *//* Now fetch the result set, row by row */while ( while ( rcrc == SQL_SUCCESS || == SQL_SUCCESS || rcrc == SQL_SUCCESS_WITH_INFO) {== SQL_SUCCESS_WITH_INFO) {

rcrc = = SQLFetch(hStmtSQLFetch(hStmt););if (if (rcrc == SQL_SUCCESS || == SQL_SUCCESS || rcrc == SQL_SUCCESS_WITH_INFO) {== SQL_SUCCESS_WITH_INFO) {

………………}}

}}

SQLDisconnect(hstmtSQLDisconnect(hstmt););}}

SQLFreeConnect(hdbcSQLFreeConnect(hdbc););SQLFreeEnv(henvSQLFreeEnv(henv););

}}

PL/SQLPL/SQLPL/SQL is Oracle's Procedural Language PL/SQL is Oracle's Procedural Language

extension to SQL.extension to SQL.PL/SQL has many programming PL/SQL has many programming language features. language features. Program units written in PL/SQL can be Program units written in PL/SQL can be stored in compiled form. stored in compiled form. PL/SQL code is portable across all PL/SQL code is portable across all operating systems that support Oracle.operating systems that support Oracle.PL/SQL does not support DDL and DCL.PL/SQL does not support DDL and DCL.

PL/SQL BlockPL/SQL BlockA PL/SQL block contains logically A PL/SQL block contains logically

related SQL and PL/SQL statements. related SQL and PL/SQL statements. Three sections in a typical PL/SQL block: Three sections in a typical PL/SQL block:

declarationdeclaration (optional): declare (optional): declare identifiers (variables and constants). identifiers (variables and constants). executionexecution (required): execute SQL and (required): execute SQL and PL/SQL statements.PL/SQL statements.exceptionexception (optional): perform error (optional): perform error handling.handling.

Sample Program 1 (1)Sample Program 1 (1)declaredeclarestudent_name Students.Name%TYPE;student_name Students.Name%TYPE;student_dept Students.Dept_name%TYPE;student_dept Students.Dept_name%TYPE;

beginbeginselectselect Name, Dept_name Name, Dept_name intointo student_name, student_deptstudent_name, student_dept/* no /* no :: needed before host variables */ needed before host variables */

fromfrom Students Students wherewhere SSN = `123456789';SSN = `123456789';

Sample Program 1 (2)Sample Program 1 (2)if (student_dept = if (student_dept = ‘‘Computer ScienceComputer Science’’) then ) then

dbms_output.put_linedbms_output.put_line(`This is a CS (`This is a CS student.');student.');

else else dbms_output.put_line(`This is not a CS dbms_output.put_line(`This is not a CS

student.');student.');end if; end if;

end;end;/ /* end each PL/SQL program with / /* end each PL/SQL program with // */*/

Execute PL/SQL ProgramExecute PL/SQL Program

Save the program in a file: Save the program in a file: sample1.sqlsample1.sqlExecute the program in SQL*PlusExecute the program in SQL*Plus

SQL> start sample1SQL> start sample1Enable output to the screen:Enable output to the screen:

SQL> set serveroutput onSQL> set serveroutput onor place or place set serveroutput onset serveroutput on at the at the beginning of the PL/SQL program.beginning of the PL/SQL program.

ProcedureProcedureprocedure procedure_nameprocedure procedure_name[(parameter, parameter, [(parameter, parameter, ……, parameter)] is, parameter)] is[local declarations][local declarations]

beginbeginexecution section;execution section;

[exception section][exception section]end;end;parameter definition:parameter definition:

parameter_name [in | out | in out] data_typeparameter_name [in | out | in out] data_type

ProcedureProcedureA parameter has a specified name and data A parameter has a specified name and data type but can also be designated as:type but can also be designated as:•• IN parameter is used as an input value onlyIN parameter is used as an input value only•• OUT parameter is used as an output value onlyOUT parameter is used as an output value only•• IN OUT parameter is used as both an input and an IN OUT parameter is used as both an input and an

output valueoutput value

Sample Program 3 (1)Sample Program 3 (1)set serveroutput onset serveroutput ondeclaredeclare

v_cid customers.cid%type;v_cid customers.cid%type;v_cnamev_cname customers.cname%type;customers.cname%type;v_city customers.city%type;v_city customers.city%type;status boolean;status boolean;procedure get_customer(procedure get_customer(

cust_id in customers.cid%type,cust_id in customers.cid%type,cust_name out customers.cname%type,cust_name out customers.cname%type,cust_city out customers.city%type,cust_city out customers.city%type,status out boolean) isstatus out boolean) is

Sample Program 3 (2)Sample Program 3 (2)beginbegin

select cname, city into cust_name, cust_cityselect cname, city into cust_name, cust_cityfrom customers where cid = cust_id;from customers where cid = cust_id;status := true;status := true;

exceptionexceptionwhen no_data_found then status := false;when no_data_found then status := false;

end;end;beginbegin

v_cid := v_cid := ‘‘c001c001’’;;get_customer(v_cid, get_customer(v_cid, v_cnamev_cname, v_city, status);, v_city, status);

Sample Program 3 (3)Sample Program 3 (3)if (status) thenif (status) then

dbms_output.put_line(v_cid || dbms_output.put_line(v_cid || ‘‘ ‘‘ ||||v_cnamev_cname || || ‘‘ ‘‘ || v_city);|| v_city);

elseelsedbms_output.put_line(dbms_output.put_line(‘‘Customer Customer ‘‘ ||||

v_cid || v_cid || ‘‘ not foundnot found’’););end if;end if;

end;end;//

Stored Procedure and Function (1)Stored Procedure and Function (1)

procedure or function definitions can be procedure or function definitions can be stored for later use (in SQL and other stored for later use (in SQL and other PL/SQL blocks).PL/SQL blocks).Stored procedures/functions are stored Stored procedures/functions are stored in compiled form.in compiled form.Stored procedures and functions are Stored procedures and functions are created bycreated by

create or replacecreate or replace procedure proc_name procedure proc_name ……create or replacecreate or replace function function func_namefunc_name ……

•• only only inin parameter allowed for function.parameter allowed for function.

An ExampleAn Exampleset set serveroutputserveroutput ononcreate or replace procedurecreate or replace procedure get_cus_nameget_cus_name((

v_cust_idv_cust_id in customers.cid%type) isin customers.cid%type) isv_cust_namev_cust_name customers.cname%typecustomers.cname%type;;

beginbeginselect select cnamecname into into v_cust_namev_cust_namefrom customers where cid = from customers where cid = v_cust_idv_cust_id;;dbms_output.put_line(dbms_output.put_line(‘‘CustomerCustomer

name: name: ‘‘ || || v_cust_namev_cust_name); ); end;end;//show errorsshow errors

Stored Procedure and Stored Procedure and Function (2)Function (2)

Compile stored procedure in file Compile stored procedure in file proc.sqlproc.sqlSQL> start procSQL> start procshow errorsshow errors displays errors detected displays errors detected during compiling the procedure.during compiling the procedure.Execute stored procedure Execute stored procedure get_cus_nameget_cus_nameSQL> SQL> executeexecute get_cus_name(get_cus_name(‘‘c001c001’’););

PackagePackageA A packagepackage is a group of related PL/SQL is a group of related PL/SQL objects (variables, objects (variables, ……), procedures, and ), procedures, and functions.functions.Each package definition has two parts:Each package definition has two parts:•• package specificationpackage specification•• package bodypackage bodyPackage specification provides an Package specification provides an interface to the users of the package.interface to the users of the package.Package body contains actual code.Package body contains actual code.

Package Specification (1)Package Specification (1)

create or replace packagecreate or replace package banking banking asasfunction check_balancefunction check_balance(account_no in Accounts.acct_no%type)(account_no in Accounts.acct_no%type)return Accounts.balance%type;return Accounts.balance%type;

procedure depositprocedure deposit(account_no in Accounts.acct_no%type,(account_no in Accounts.acct_no%type,amount in Accounts.balance%type);amount in Accounts.balance%type);

Package Specification (2)Package Specification (2)

procedure withdrawprocedure withdraw(account_no in Accounts.acct_no%type,(account_no in Accounts.acct_no%type,amount in Accounts.balance%type);amount in Accounts.balance%type);

end;end;//show errorsshow errors

Package Body (1)Package Body (1)create or replace package bodycreate or replace package body banking banking asas

functionfunction check_balancecheck_balance(account_no in Accounts.acct_no%type)(account_no in Accounts.acct_no%type)return Accounts.balance%type isreturn Accounts.balance%type isacct_balance Accounts.balance%type;acct_balance Accounts.balance%type;

beginbeginselect balance into acct_balanceselect balance into acct_balancefrom Accountsfrom Accountswhere acct_no = account_no;where acct_no = account_no;return acct_balance;return acct_balance;

endend;;

Package Body (2)Package Body (2)procedureprocedure depositdeposit

(account_no in Accounts.acct_no%type,(account_no in Accounts.acct_no%type,amount in Accounts.balance%type) isamount in Accounts.balance%type) is

beginbeginif (amount <= 0) thenif (amount <= 0) then

dbms_output.put_line(dbms_output.put_line(‘‘WrongWrong amount.amount.’’););else update Accounts else update Accounts

set balance = balance + amountset balance = balance + amountwhere acct_no = account_no;where acct_no = account_no;

end if;end if;endend;;

Package Body (3)Package Body (3)

procedureprocedure withdrawwithdraw(account_no in Accounts.acct_no%type,(account_no in Accounts.acct_no%type,amount in Accounts.balance%type) isamount in Accounts.balance%type) isacct_balance Accounts.balance%type;acct_balance Accounts.balance%type;

Package Body (4)Package Body (4)beginbegin

acct_balance := check_balance(account_no);acct_balance := check_balance(account_no);if (amount > acct_balance) thenif (amount > acct_balance) then

dbms_output.put_line(dbms_output.put_line(‘‘InsufficientInsufficient fund.fund.’’););else update Accounts else update Accounts

set balance = balance set balance = balance -- amountamountwhere acct_no = account_no;where acct_no = account_no;

end if;end if;endend;;

endend; /* end of the package body */; /* end of the package body *///show errorsshow errors

Cursor in PL/SQL (1)Cursor in PL/SQL (1)Consider an SQL query returning Consider an SQL query returning multiple rows.multiple rows.

How to save the result of the query?How to save the result of the query?Save the result into a big array.Save the result into a big array.•• No easy way to estimate the size of the result. No easy way to estimate the size of the result. •• The result could be too large for any memoryThe result could be too large for any memory--

based array.based array.

Save Save oneone--rowrow--atat--aa--timetime: This is the SQL : This is the SQL approach.approach.

Cursor in PL/SQL (2)Cursor in PL/SQL (2)

Define a cursor:Define a cursor:cursorcursor cursor_name cursor_name is is select_statement;select_statement;

Example: Example: cursorcursor c1 c1 isisselectselect cid, cid, cnamecname, city , city fromfrom customers;customers;

The query defining the cursor is not The query defining the cursor is not executed at the declaration time.executed at the declaration time.

Working with Cursor (1)Working with Cursor (1)openopen cursor_name;cursor_name;fetchfetch cursor_name cursor_name intointo record_or_variablerecord_or_variable--list;list;closeclose cursor_name;cursor_name;

OpenOpen causes the query defining the causes the query defining the cursor to be executed.cursor to be executed.

BuiltBuilt--in Package: in Package: dbms_sqldbms_sql (1)(1)

dbms_sqldbms_sql can be used to dynamically can be used to dynamically create and execute SQL statements, create and execute SQL statements, including DDL statements.including DDL statements.Main steps:Main steps:•• Open a handle cursorOpen a handle cursor•• Parse the statementParse the statement•• Close the cursorClose the cursor

BuiltBuilt--in Package: in Package: dbms_sqldbms_sql (2)(2)declaredeclarehandle integer;handle integer;stmt varchar2(256);stmt varchar2(256);

beginbeginstmt := 'create table test (attr1 number(2)stmt := 'create table test (attr1 number(2)’’ || ||

' primary key, attr2 number(4))';' primary key, attr2 number(4))';handle := handle := dbms_sql.open_cursordbms_sql.open_cursor;;dbms_sql.parse(handle,stmt,DBMS_SQL.V7);dbms_sql.parse(handle,stmt,DBMS_SQL.V7);dbms_output.put_line('Tabledbms_output.put_line('Table TEST created');TEST created');dbms_sql.close_cursor(handledbms_sql.close_cursor(handle););

end;end;/ /

Trigger (1)Trigger (1)A trigger is an A trigger is an eventevent--drivendriven block of block of PL/SQL code.PL/SQL code.An event could be an insertion of a An event could be an insertion of a tupletupleinto a table, a deletion of an existing into a table, a deletion of an existing tupletuplefrom a table, and an update of a table.from a table, and an update of a table.A trigger A trigger firesfires (executes, activates) when (executes, activates) when an event occurs.an event occurs.Triggers are useful for enforcing various Triggers are useful for enforcing various integrity constraints and business rules.integrity constraints and business rules.

Trigger (2)Trigger (2)ECA Model:ECA Model:

EventEvent ConditionCondition ActionAction

an eventdetected?

Is the eventsignificant?

take actions

yes yes

insertdeleteupdate

need to satisfyadditionalcondition

executeSQL/PLblock

Trigger (3)Trigger (3)create or replace triggercreate or replace trigger raise_salraise_salbeforebefore update of salary on employeesupdate of salary on employeesfor each rowfor each rowwhenwhen (new.salary > old.salary * 1.2)(new.salary > old.salary * 1.2)beginbegin

dbms_output.put_line(dbms_output.put_line(‘‘Old salary is Old salary is ‘‘ || || :old.salary || :old.salary || ‘‘, , ‘‘ || || ‘‘New salary is New salary is ‘‘ || || :new.salary);:new.salary);

dbms_output.put_line(dbms_output.put_line(‘‘The raise is too high!The raise is too high!’’););end; end;

Trigger Applications (1)Trigger Applications (1)Use trigger for monitoring changesUse trigger for monitoring changes

Example: add a log entry each time the price Example: add a log entry each time the price of a product is changedof a product is changedlog table for product:log table for product:create table products_log create table products_log ((pidpid char(4), char(4),

username char(10), username char(10), update_date date, update_date date, old_price number(6, 2), old_price number(6, 2), new_price number(6, 2));new_price number(6, 2));

Trigger Applications (2)Trigger Applications (2)create or replace trigger update_p_pricecreate or replace trigger update_p_priceafter update of price on productsafter update of price on productsfor each rowfor each rowbeginbegininsert into products_log valuesinsert into products_log values(:(:old.pidold.pid, user, , user, sysdatesysdate, :old.price, :new.price);, :old.price, :new.price);

end;end;

Trigger Applications (3)Trigger Applications (3)Use trigger to enforce integrity constraintsUse trigger to enforce integrity constraints

Example: If a student is removed, delete all Example: If a student is removed, delete all enrollments by the student.enrollments by the student.

create or replace triggercreate or replace trigger stud_enrollstud_enrollafterafter delete on studentsdelete on studentsfor each rowfor each rowbeginbegindelete from enrollments where delete from enrollments where sidsid = := :old.sidold.sid;;

end;end;