Embedded SQL

advertisement
To Chapter 4.12
Embedded SQL
Written by T. Nikovits and A. B. Novak
Why:
 there are some problems which can not be
expressed in SQL (eg. loops)
 riport generation
 graphical interface
Solution:
-
embedded SQL
4GL developer tools
(Oracle Developer)
EXEC <SQL statements> (END-EXEC)
Declarations: variables for both languages (for the SQL
and for the host languagae)
EXEC SQL BEGIN DECLARE SECTION;
…..
EXEC SQL END DECLARE SECTION;
Host: C
C statement
SQL statement
C statement
C statement
SQL statement
…
File extensions: .ps (Oracle) .sc. (Ingres)
Embedded program  SQL Precompiler  SQL
C functions
Ingres: esqlc.
esqlc program.sc
program.c
Oracle: proc.
proc program.sc
program.c
The result is a C program  CompileRun
You have to attached the libraries. These can be found in
the DBMS, they are installed already with the DBMS
Environment
Client
Server
Procedures
SQL statement
SQL statement
execution
C variables
accept the answer
Answer
Other procedures for evaluation
of answer
 The SQL statement are sent to the server
 Answer:
 error message (depending of the success of a delete,
update)
 query result (Select…)
Syntax
Sql statements should be recognized, the precompiler
compiles only these ones.
General syntax:
EXEC SQL <SQL statement > ;
Example:
EXEC SQL
CREATE TABLE ITEM
(COD NUMBER(5), INAME VARCHAR2(15)) ;
EXEC SQL
DELETE FROM ITEM
WHERE INAME IN
('TABLE', 'MONITOR', 'PENCIL') ;
EXEC SQL
INSERT INTO ITEM(COD, CNAME)
VALUES (10, 'Keyboard') ;
Anywhere can be an SQL statement or a C statement.
Variables
In SQL - statements instead of using database items we
can use C variables. They could be simple variables,
structures, or pointers.
EXEC SQL DELETE FROM ITEM
WHERE CNAME = <C variable> ;
EXEC SQL INSERT INTO ITEM(COD, CNAME)
VALUES <C variable> ;
Variables must be declared in the declare session:
EXEC SQL BEGIN DECLARE SECTION ;
variable declaration by C syntax
EXEC SQL END DECLARE SECTION ;
Example:
EXEC SQL BEGIN DECLARE SECTION ;
long newcod;
char cname[16];
EXEC SQL END DECLARE SECTION ;
C variables should be written AFTER : . In this way they
can be distinguished from the database items (sharing same
name, eg. Attribute names)
Example:
EXEC SQL INSERT INTO ITEM(cod)
VALUES :newcod ;
EXEC SQL DELETE FROM ITEM
WHERE cname = :cname ;
What would happen if we forgot to put : there?
Question:
What is the result of the following program?
EXEC SQL
SELECT DNAME, DEPTNO, MANAGER, BUDGET,
ADDRESS, PHONE
INTO :dname, :deptno, :manager, :budget, :address, :phone
FROM DEPT
WHERE DNAME= "research";
Using structures
TABLE ITEM :
cod
cname
color
weight
integer
char(15)
char(15)
float
struct {
long cod;
char cname[16];
char color[16];
double weight;
} item_rec;
Referring to a strucuture in SQL:
EXEC SQL INSERT INTO ITEM
VALUES (:item_rec) ;
Or:
EXEC SQL INSERT INTO ITEM
VALUES (:item_rec.cod, :item_rec.cname,
:item_rec.color, :item_rec.weight) ;
Connect to database
Syntax:
EXEC SQL CONNECT : user_name
IDENTIFIED BY : password ;
Disconnect syntax:
EXEC SQL DISCONNECT ;
Remark:
 Oracle: COMMIT RELEASE
ROLLBACK RELEASE
 Ingres: multisession (SESSION)
Cursors
Cursors are useful to get back one row from the result of a
SELECT statement.
SELECT CURSOR pointing to the actual tuple
Creating a cursor:
EXEC SQL DECLARE cname CURSOR
FOR SELECT ... ;
This reflects changes.
EXEC SQL
CURSOR
DECLARE
knev
INSENSITIVE
FOR SELECT ... ;
Cursor can be defined only with SELECT grant
Examples:
1.
EXEC SQL
DECLARE DEPT-EMP CURSOR FOR
SELECT dname, surname, first_name
FROM DEPT d, EMP e
WHERE emp.deptno = emp.deptno
ORDER BY deptno, surname, first_name;
2. AVG salaries for each dept:
EXEC SQL
DECLARE dept-avg-sal CURSOR FOR
SELECT dnaem, AVG(sal)
FROM DEPT d, EMP e
WHERE d.deptno = e.deptno.
GROUP BY deptno
ORDER BY dname;
Using the cursor first we have to open it::
EXEC SQL OPEN cursor_name ;
(at runtime it will point to the tuple used latest by the
program, delete, update, insert)
Read and go to next:
EXEC SQL FETCH cursor_name
INTO <C variables> ;
The tuple, to that the cursor points will be read into C
variables. TYPE CONVERSION!!!
Closing cursor:
EXEC SQL CLOSE curso_name ;
Remark:
cursor_name is NOT a C-variable, that is why : is not
needed.
Updating data using cursors
The type of update must be declraed in the cursor
definition:
EXEC SQL DECLARE cursor_name CURSOR FOR
SELECT ....
FOR UPDATE [OF column1, column2, ...] ;
Remark:
Only for ONE table used by select. No distinct, no group
by, no having, no union!!
Syntax:
EXEC SQL UPDATE <table_name>
SET column = <statement>, ...
WHERE CURRENT OF <cursor_name> ;
Deleting rows:
EXEC SQL DELETE FROM <table_name>
WHERE CURRENT OF <cursor_name> ;
Error handling
For each SQL statement the system feeds back to the client
program whether the statement execution was successful or
not. That means, that the server program set the values of
certain variables of the client program.
The program is responsible for defining these variables:
EXEC SQL INCLUDE SQLCA;
This is a structure type C variables, Named: SQLCA.
Main elements:
sqlca.sqlcode:
long sqlcode;
error code for last SQL statement:
= 0 succesfully executed
< 0 error
> 0 exceptional case, like no rows in the answer =
100, or end table)
sqlca.sqlerrm
structure type: lenght of error message
and first 70 characters
NULL values handling - indicator variables
INTERBASE SQL TUTORIAL:The following program
declares a cursor, opens the cursor, and then loops through
the cursor’s active set, fetching and printing values. The
program closes the cursor when all processing is finished or
an error occurs.
#include <stdio.h>
EXEC SQL
BEGIN DECLARE SECTION;
char deptname[26];
char lname[16];
char fname[11];
EXEC SQL
END DECLARE SECTION;
main ()
{
EXEC SQL
WHENEVER SQLERROR GO TO abend;
EXEC SQL
DECLARE DEPT_EMP CURSOR FOR
SELECT DEPARTMENT, LAST_NAME, FIRST_NAME
FROM DEPARTMENT D, EMPLOYEE E
WHERE D.DEPT_NO = E.DEPT_NO"
ORDER BY DEPARTMENT, LAST_NAME,
FIRST_NAME;
EXEC SQL
OPEN DEPT_EMP;
EXEC SQL
FETCH DEPT_EMP
INTO :deptname, :lname, :fname;
while (!SQLCODE)
{
printf("%s %s works in the %s department.\n",fname,
lname, deptname);
EXEC SQL
FETCH DEPT_EMP
INTO :deptname, :lname, :fname;
}
EXEC SQL
CLOSE DEPT_EMP;
exit();
abend:
if (SQLCODE)
{
isc_print_sqlerror();
EXEC SQL
ROLLBACK;
EXEC SQL
CLOSE_DEPT_EMP;
EXEC SQL
DISCONNECT ALL;
exit(1)
}
else
{
EXEC SQL
COMMIT;
EXEC SQL
DISCONNECT ALL;
exit()
}
}
Questions to review:
1. Explain each unit briefly.
2. Insert a variable named as number_of tuples, type
INTEGER, whose value is equal to the number of rows
printed in the program.
3. List the variables in the host language (C)
4. How many cursors are defined in this program.
5. Give the names of the cursors.
6. What will be printed out if Xian Xi’s name, which is the
last in the table, will be changed to Xian Xu. Why? Could
you alter this result?
7. Is the transaction committed? Explain.
8. Mr. Cody has been granted for selection on all tables.
Could he run that program?
Download