Minggu 6, Pertemuan 11 Programmatic SQL Matakuliah : T0206-Sistem Basisdata

advertisement
Matakuliah
Tahun
Versi
: T0206-Sistem Basisdata
: 2005
: 1.0/0.0
Minggu 6, Pertemuan 11
Programmatic SQL
1
Learning Outcomes
Pada akhir pertemuan ini, diharapkan
mahasiswa dapat mendemonstrasikan
bagaimana SQL dapat diintegrasikan di
dalam high level programming language
(C3)
2
Outline Materi
• How SQL statements can be embedded
in high-level programming languages.
• Difference between static and dynamic
embedded SQL.
• How to write programs that use static
embedded SQL.
• How to write programs that use
dynamic embedded SQL.
3
Embedded SQL
• SQL can be embedded in high-level
procedural language.
• In many cases, language is identical
although SELECT statement differs.
• Two types of programmatic SQL:
– Embedded SQL statements.
• SQL supports
Ada,
C,
COBOL,
FORTRAN, MUMPS, Pascal, and PL/1.
– Application program interface (API).
4
Example 21.1 - CREATE TABLE
EXEC SQL CREATE TABLE Viewing (
propertyNo
VARCHAR2(5)
NOT
NULL,
clientNo VARCHAR2(5) NOT NULL,
viewDate DATE NOT NULL,
comment VARCHAR2(40));
if (sqlca.sqlcode >= 0)
printf(“Creation successful\n”);
5
Embedded SQL
• Embedded SQL starts with identifier, usually
EXEC SQL [ ‘@SQL(’ in MUMPS].
• Ends with terminator dependent on host
language:
– Ada, ‘C’, and PL/1: terminator is semicolon
(;)
– COBOL: terminator is END-EXEC
– Fortran: ends when no more continuation
lines.
• Embedded SQL can appear anywhere an
executable host language statement can
appear.
6
SQL Communications Area
(SQLCA)
• Used to report runtime errors to the
application program.
• Most important part is SQLCODE
variable:
0 - statement executed successfully;
< 0 - an error occurred;
> 0 - statement executed successfully, but
an exception occurred, such as no more
rows returned by SELECT.
7
SQLCA for Oracle
8
WHENEVER Statement
• Every embedded SQL statement can
potentially generate an error.
• WHENEVER is directive to precompiler
to generate code to handle errors after
every SQL statement:
EXEC SQL WHENEVER
<condition>
<action>
9
WHENEVER Statement
• condition can be:
SQLERROR - generate code to handle errors
(SQLCODE < 0).
SQLWARNING - generate code to handle warnings.
NOT FOUND - generate code to handle specific
warning that a retrieval operation has found no
more records.
10
WHENEVER Statement
• action can be:
CONTINUE - ignore condition and proceed to next
statement.
DO - transfer control to an error handling function.
DO BREAK - place an actual “break” statement in the
program.
DO CONTINUE - place an actual “continue” statement in
the program.
GOTO label or GO TO label - transfer control to specified
label.
STOP - rollback all uncommitted work and terminate the
program.
11
WHENEVER Statement
EXEC SQL WHENEVER SQLERROR GOTO
error1;
EXEC SQL INSERT INTO Viewing VALUES
(‘CR76’, ‘PA14’, ‘12-May-2001’, ‘Not enough
space’);
• would be converted to:
EXEC SQL INSERT INTO Viewing VALUES
(‘CR76’, ‘PA14’, ‘12-May-2001’, ‘Not enough
space’);
if (sqlca.sqlcode < 0) goto error1;
12
Host Language Variables
• Program variable declared in host
language.
• Used in embedded SQL to transfer data
from database into program and vice
versa.
• Can be used anywhere a constant can
appear.
• Cannot be used to represent database
objects, such as table names or column
names.
• To use host variable, prefix it by a colon (:).
13
Host Language Variables
EXEC SQL UPDATE Staff
SET salary = salary + :increment
WHERE staffNo = ‘SL21’;
• Need to declare host language
variables to SQL, as well as to host
language:
EXEC SQL BEGIN DECLARE SECTION;
float increment;
EXEC SQL END DECLARE SECTION;
14
Indicator Variables
• Indicates presence of null:
0
associated host variable contains valid
value.
<0 associated host variable should be assumed
to contain a null; actual contents of host
variable irrelevant.
>0 associated host variable contains valid
value.
• Used immediately following associated
host variable with a colon (:)
separating two variables.
15
Indicator Variables - Example
EXEC SQL BEGIN DECLARE SECTION;
char address[51];
short
addressInd;
EXEC SQL END DECLARE SECTION;
addressInd = -1;
EXEC SQL UPDATE PrivateOwner
SET
address
=
:address
:addressInd
WHERE ownerNo = ‘CO21’;
16
Singleton SELECT - Retrieves
Single Row
EXEC SQL SELECT fName, lName, address
INTO
:firstName,
:lastName,
:address
:addressInd
FROM PrivateOwner
WHERE ownerNo = ‘CO21’;
• Must be 1:1 correspondence between
expressions in SELECT list and host
variables in INTO clause.
• If successful, SQLCODE set to 0; if
there are no rows that satisfies
WHERE, SQLCODE set to NOT FOUND.
17
Cursors
• If query can return arbitrary number of
rows, need to use cursors.
• Cursor allows host language to access
rows of query one at a time.
• Cursor acts as a pointer to a row of
query result. Cursor can be advanced
by one to access next row.
• Cursor must be declared and opened
before it can be used and it must be
closed to deactivate it after it is no
longer required.
18
Cursors - DECLARE CURSOR
• Once opened, rows of query result can
be retrieved one at a time using FETCH:
EXEC SQL DECLARE
propertyCursor CURSOR FOR
SELECT propertyNo, street, city
FROM PropertyForRent
WHERE staffNo = ‘SL41’;
19
Cursors - OPEN
• OPEN statement opens specified
cursor and positions it before first row
of query result:
EXEC SQL OPEN propertyCursor;
20
Cursors - FETCH and CLOSE
• FETCH retrieves next row of query result
table:
EXEC SQL FETCH propertyCursor
INTO :propertyNo, :street, :city
• FETCH is usually placed in a loop. When
there are no more rows to be returned,
SQLCODE is set to NOT FOUND.
EXEC SQL CLOSE propertyCursor;
21
ISO Standard for Embedded SQL
• Standard
does
not
recognize
SQLWARNING of WHENEVER statement.
• Standard does not mention an SQLCA. It
does, however, recognize the integer
variable SQLCODE, although this is a
deprecated feature that is supported only
for compatibility with earlier versions of
the standard.
• Instead, defines a character string
SQLSTATE parameter, comprising a twocharacter class code followed by a threecharacter subclass code.
22
ISO Standard for Embedded SQL
• Standard specifies definition and
processing
of
cursors
slightly
differently from that presented above.
ISO DECLARE CURSOR is:
EXEC SQL DECLARE cursorName
[INSENSITIVE] [SCROLL]
CURSOR FOR selectStatement
[FOR {READ ONLY |
UPDATE [OF columnNameList]}]
23
ISO Standard for Embedded SQL
• FETCH statement:
EXEC SQL FETCH [[fetchOrientation] FROM]
cursorName INTO hostVariable [, . . . ]
• fetchOrientation can be one of:
–
–
–
–
–
–
NEXT
PRIOR
FIRST
LAST
ABSOLUTE
RELATIVE
24
Dynamic Embedded SQL
• With static embedded SQL, cannot use host
variables where database object names required.
• Dynamic SQL allows this.
• Idea is to place complete SQL statement in a
host variable, which is passed to DBMS to be
executed.
• If SQL statements do not involve multi-row
queries, use EXECUTE IMMEDIATE statement:
EXEC SQL EXECUTE IMMEDIATE
[hostVariable | stringLiteral]
25
Dynamic Embedded SQL
For example:
sprintf(buffer, “UPDATE Staff
SET salary = salary + %f
WHERE
staffNo
=
‘SL21’
increment);
EXEC SQL EXECUTE IMMEDIATE :buffer;
”,
26
PREPARE and EXECUTE
• DBMS must parse, validate, and optimize
each EXECUTE IMMEDIATE statement,
build execution plan, and execute plan.
• OK if SQL statement is only executed
once in program; otherwise inefficient.
• Dynamic SQL provides alternative:
PREPARE and EXECUTE.
• PREPARE
tells
DBMS
to
ready
dynamically built statement for later
execution.
27
PREPARE and EXECUTE
• Prepared statement assigned name.
When statement is subsequently
executed, program need only specify
this name:
EXEC SQL PREPARE statementName
FROM [hostVariable | stringLiteral]
EXEC SQL EXECUTE statementName
[ USING hostVariable [indicatorVariable] [, ...] |
USING DESCRIPTOR descriptorName ]
28
Parameter Markers
• USING allows portions of prepared
statement to be unspecified, replaced
by placeholders (parameter markers).
• Placeholder can appear anywhere in
hostVariable
or
stringLiteral
of
PREPARE that constant can appear.
• Tells DBMS value will be supplied later,
in EXECUTE statement.
29
Placeholders
sprintf(buffer, “UPDATE Staff
SET salary = :sal
WHERE staffNo = :sn”);
EXEC SQL PREPARE stmt FROM :buffer;
EXEC SQL EXECUTE stmt
USING :newSalary, :staffNo;
• sal and sn are placeholders.
30
Static versus Dynamic SQL
31
SQL Descriptor Area (SQLDA)
• Alternative way to pass parameters to
EXECUTE statement is through SQLDA.
• Used when number of parameters and
their data types unknown when
statement formulated.
• SQLDA can also be used to dynamically
retrieve data when do not know number
of columns to be retrieved or the types
of the columns.
32
SQLDA for Oracle
33
Retrieving Data Using Dynamic
SQL
• Again, use cursors to retrieve data from a query
result table that has an arbitrary number of rows.
EXEC SQL DECLARE cursorName
CURSOR FOR selectStatement
EXEC SQL OPEN cursorName [FOR READONLY]
{USING hostVariable [indicatorVariable] [,...] |
USING DESCRIPTOR descriptorName }
EXEC SQL FETCH cursorName
{INTO hostVariable [indicatorVariable] [,...] |
USING DESCRIPTOR descriptorName }
EXEC SQL CLOSE cursorName
34
Retrieving Data Using Dynamic
SQL
• OPEN allows values for placeholders
to be substituted using one or more
hostVariables in:
– USING clause or
– passing values via descriptorName
(SQLDA) in a USING DESCRIPTOR
clause.
• Main difference is with FETCH, which
now uses descriptorName to receive
rows of query result table (or one or
more
hostVariables/
indicatorVariables).
35
Retrieving Data Using Dynamic
SQL
• Before FETCH, program must provide data areas to
receive retrieved data and indicator variables.
• Basic steps for dynamic SQL statement are:
(1) Declare host string in DECLARE SECTION to hold
text of the query.
(2) Declare a select SQLDA and, if required, a bind
SQLDA.
(3) Allocate storage space for the SQLDA(s).
(4) Set maximum number of columns in select SQLDA
and, if query can have placeholders, maximum number
of placeholders in bind SQLDA.
36
Retrieving Data Using Dynamic
SQL
(5) Put the query text into the host string.
(6) PREPARE the query from the host string.
(7) DECLARE a cursor for the query.
(8) If the query can have placeholders:
(a) DESCRIBE bind variables into bind SQLDA.
(b) Reset number of placeholders to number actually
found by DESCRIBE.
(c) Get values and allocate storage space for bind
variables found by DESCRIBE.
(9) OPEN cursor USING the bind SQLDA, or if no
bind SQLDA has been used, USING the select
SQLDA.
37
Retrieving Data Using Dynamic
SQL
(10) DESCRIBE the column list INTO the select SQLDA.
(11) Reset number of column list items to number actually
found by DESCRIBE.
(12) Reset length and data type of each column list item.
(13) FETCH each row from database into allocated data
buffers pointed to by the select SQLDA and process it,
as appropriate.
(14) Deallocate the storage space used for the column list
items, placeholders, indicator variables, and SQLDAs.
(15) CLOSE the cursor.
38
Download