Vous êtes sur la page 1sur 25

Chapter - 3

Database Programming Techniques

INTRODUCTION
Here we shall discuss some of the methods that have been developed for accessing databases from programs. They are developed using general-purpose programming language like Java, C/C++/C#, COBOL, etc., or scripting languages like PHP and JavaScript, etc for web applications The general-purpose programming language is called the host language, whereas the database language SQL, in our caseis called the data sublanguage. Special database programming languages are developed specifically for writing database applications like PL/SQL (Oracle), MySQL stored procedures (a procedural language that closely adheres to SQL/PSM), PL/pgSQL (PostgreSQL language similar to SQL/PSM and PL/SQL), Transact-SQL (Microsoft and Sybase equivalent) etc. The purpose of the chapter is to introduce some of the main types of database programming techniques and to compare them
to illustrate the main differences that a programmer would face when using each of these database programming techniques Example concepts include embedded SQL, dynamic SQL, SQL/CLI, ODBC, JDBC etc

Database Programming: Techniques and Issues


Most database systems have an interactive interface where these SQL commands can be typed directly into a monitor for execution by the database system. Alternatively, a file of commands can be created and executed through the interactive interface by typing @<filename>. The system will execute the commands written in the file and display the results. Eg SQL > @ C:\My Programs\ sample PL/SQL block
DECLARE <variable declaration> BEGIN <Program body> EXCEPTION <Exception-handlers> END; /

PL/SQL Example
SQL> select * from student; REGNO SNAME ---------- -------------------1 Isaac 2 Fatima 3 Ibeltha 4 Zenab 5 Henry 6 Mohamed 7 Getachew 8 Seid 9 David 10 Solomon 10 rows selected.
SQL> get pre_except 1 declare 2 s student.sname%type; 3 begin 4 select sname into s from student 5 where regno = 11; 6 Exception 7 when no_data_found then 8 dbms_output.put_line('Student 9 detail Not Found'); 10* end; SQL> / Student detail Not Found

Approaches to Database Programming..1


Embedding database commands in a general-purpose programming language. DML statements are embedded into the host programming language and are identified by a special prefix( like EXEC SQL) A precompiler or preproccessor scans the source program code to identify database statements and extract them for processing by the DBMS. They are replaced in the program by function calls to the DBMSgenerated code. This technique is called as embedded SQL.

Approaches to Database Programming..2


Using a library of database functions. A library of functions is made available to the host programming language for database calls. For example, there could be functions to connect to a database, execute a query, execute an update, and so on. The DML commands are included as parameters in the function calls. This approach provides what is known as an application

programming interface (API) for accessing a database from application programs.

Approaches to Database Programming..3


Designing a brand-new language. A database programming language is designed from scratch to be compatible with the database model and query language. Additional programming structures such as loops and conditional statements are added to the database language to convert it into a fullfledged programming language like Oracles PL/SQL. This method is more appropriate for applications that have intensive database interaction This avoids impedence mismatch too

Impedance Mismatch
It refers to the problems that occur because of differences between the database model and the programming language model. For example, the practical relational model has three main constructs: columns (attributes) and their data types, rows (also referred to as tuples or records), and tables (sets or multisets of records). Problems
The data types of the programming language differ from the attribute data types that are available in the data model. Hence, a different binding for each host programming language for each attribute type is needed. (for C++, Java etc) the results of most queries are sets or multisets of tuples (rows), and each tuple is formed of a sequence of attribute values. A binding is needed to map the query result data structure (table) . Hence a cursor or iterator variable is typically used to loop over the tuples in a query result.

Sequence of Interaction in Database Programming


Open a connection to the database server.
specifying the Internet address (URL) of Server machine providing a login account name and password for database access.

Interact with the database by submitting queries, updates, and other database commands. Terminate or close the connection to the database.
There can be multiple connections but in certain cases only one connection can be active at a time

Embedded SQL with C


Use EXEC SQL so that a preprocessor (or precompiler) can separate embedded SQL statements from the host language code. Terminate statements by a matching END-EXEC or by a semicolon (;). Within an embedded SQL command, we may refer to specially declared C program variables (called shared variables) Shared variables are prefixed by a colon (:) when they appear in an SQL statement. Common bindings of C types to SQL types are as follows. The SQL types INTEGER, SMALLINT, REAL, and DOUBLE are mapped to the C types long, short, float, and double, respectively. Fixed-length and varying-length strings (CHAR[i], VARCHAR[i]) in SQL can be mapped to arrays of characters (char [i+1], varchar [i+1]) in C (+1 indicates the NULL character)

Example Embedded SQL


0) int loop ; 1) EXEC SQL BEGIN DECLARE SECTION ; 2) varchar dname [16], fname [16], lname [16], address [31] ; 3) char ssn [10], bdate [11], sex [2], minit [2] ; 4) float salary, raise ; 5) int dno, dnumber ; 6) int SQLCODE ; char SQLSTATE [6] ; 7) EXEC SQL END DECLARE SECTION ;

Embedded SQL Connection Statements


CONNECT TO <server name>AS <connection name>

AUTHORIZATION <user account name and password> ; -- to establish connection SET CONNECTION <connection name> ; -- to set an active connection DISCONNECT <connection name> ; -- to disconnect a connection EXEC SQL include SQLCA ; -- Communication variables SQLCODE and SQLSTATE found in SQLCA
communication variables are used by the DBMS to communicate exception or error conditions to the program

Example 2 Embedded SQL


//Program Segment E1: 0) loop = 1 ; 1) while (loop) { 2) prompt("Enter a Social Security Number: ", ssn) ; 3) EXEC SQL 4) select Fname, Minit, Lname, Address, Salary 5) into :fname, :minit, :lname, :address, :salary 6) from EMPLOYEE where Ssn = :ssn ; 7) if (SQLCODE == 0) printf(fname, minit, lname, address, salary) 8) else printf("Social Security Number does not exist: ", ssn); 9) prompt("More Social Security Numbers (enter 1 for Yes, 0 for No): ", loop) ; 10) 10) }

Cursors
Applicable for both Embedded SQL and DB Server-side programming Cursor is a pointer / iterator that points to a single tuple (row) from the result of a query that retrieves multiple tuples. The cursor is declared when the SQL query command is declared in the program. An OPEN CURSOR command fetches the query result from the database and sets the cursor to a position before the first row in the result of the query. This becomes the current row for the cursor. FETCH commands are issued to move the cursor to the next row in the result of the query CLOSE CURSOR command is issued to indicate the processing with cursor is done.

Cursor Embedded SQL Example


//Program Segment E2: 0) prompt("Enter the Department Name: ", dname) ; 1) EXEC SQL 2) 3) 5) 7) select Dnumber into :dnumber from DEPARTMENT where Dname = :dname ; EXEC SQL DECLARE EMP CURSOR FOR select Ssn, Fname, Minit, Lname, Salary from EMPLOYEE where Dno = :dnumber FOR UPDATE OF Salary ;

8) EXEC SQL OPEN EMP ; 9) EXEC SQL FETCH from EMP into :ssn, :fname, :minit, :lname, :salary ; 10) while (SQLCODE == 0) { 11) 12) 13) 14) 17) 18) } printf("Employee name is:", Fname, Minit, Lname) ; prompt("Enter the raise amount: ", raise) ; EXEC SQL update EMPLOYEE set Salary = Salary + :raise where CURRENT OF EMP ; EXEC SQL FETCH from EMP into :ssn, :fname, :minit, :lname, :salary ;

19) EXEC SQL CLOSE EMP ;

Cursor PL/SQL Example


Before Execution: SQL> select * from student; REGNO SNAME MARK1 MARK2 TOTAL RESULT DEPT ---------- -------------------- ---------- ---------- ---------1 Raja 90 60 150 Maths 2 Rani 56 34 90 Maths 3 Kavi 78 76 154 Maths 4 Jeeva 12 45 57 Maths 5 Henry 100 90 190 CS 6 Mohamed 45 90 135 CS 7 Getachew 87 32 119 CS 8 Seid 67 89 156 CS Output: SQL> select * from student; REGNO SNAME MARK1 MARK2 TOTAL RESULT DEPT ---------- -------------------- ---------- ---------- ---------1 Raja 90 60 150 Maths 2 Rani 56 34 90 Maths 3 Kavi 78 76 154 Maths 4 Jeeva 12 45 57 Maths 5 Henry 100 90 190 pass CS 6 Mohamed 45 90 135 fail CS 7 Getachew 87 32 119 fail CS 8 Seid 67 89 156 pass CS
SQL> get ex_cursor 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24* end; 25 / end loop; dbms_output.put_line('Result updated in Student DB!'); end if; update student set result = rs where regno = r; else rs := 'fail'; declare cursor calc_result is select regno, mark1, mark2 from student where dept = 'CS'; r m2 rs c i begin select count(*) into c from student where dept = 'CS'; student.regno%type; student.mark2%type; student.result%type; integer; integer; m1 student.mark1%type;

open calc_result;
for i in 1..c loop

fetch calc_result into r,m1,m2;


if m1 >= 50 and m2 >= 50 then rs := 'pass';

close calc_result;

SQLJ: Embedding SQL Commands in Java


1) import java.sql.* ; 2) import java.io.* ; 3) import sqlj.runtime.* ; 4) import sqlj.runtime.ref.* ; 5) import oracle.sqlj.runtime.* ; ... 6) DefaultContext cntxt = 7) oracle.getConnection("<url name>", "<user name>", "<password>", true) ; 8) DefaultContext.setDefaultCo ntext(cntxt) ; ...
1) string dname, ssn , fname, fn, lname, ln, bdate, address ; 2) char sex, minit, mi ; 3) double salary, sal ; 4) integer dno, dnumber ;...
//Program Segment J1: 1) ssn = readEntry("Enter a Social Security Number: ") ; 2) try { 3) #sql { select Fname, Minit, Lname, Address, Salary 4) into :fname, :minit, :lname, :address, :salary 5) from EMPLOYEE where Ssn = :ssn } ; 6) } catch (SQLException se) { 7) System.out.println("Social Security Number does not exist: " + ssn) ; 8) Return ; 9) } 10) System.out.println(fname + " " + minit + " " + lname + " " + address + " " + salary)

Explanation for SQLJ Embedded SQL for Java


The format of this function call, which returns an object of type default context,is as follows:
public static DefaultContext getConnection(String url, String user, String password, Boolean autoCommit) throws SQLException ;

The connection established is set as the default context for subsequent commands. In SQLJ, the embedded SQL commands within a Java program are preceded by #sql instead of the keywords EXEC SQL

For queries that retrieve many tuples, SQLJ uses the concept of an iterator, which is similar to a cursor in embedded SQL.

Java with Oracle JDBC (Dynamic)


Download Oracle JDBC Driver
Get Oracle JDBC driver ojdbcxxx.jar (http://www.oracle.com/technetwork/database/features/jdbc/index-091264.html)

Write a program import java.sql.DriverManager; import java.sql.Connection; import java.sql.SQLException; public class OracleJDBC { public static void main(String[] argv) { System.out.println("----- Oracle JDBC Connection Testing ----"); try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) { System.out.println("Where is your Oracle JDBC Driver?"); e.printStackTrace(); return; } System.out.println("Oracle JDBC Driver Registered!"); Connection connection = null; try { connection = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:melita", "username", "password"); } catch (SQLException e) { System.out.println("Connection Failed! Check output console"); e.printStackTrace(); return; } if (connection != null) { System.out.println("You made it, take control your database now!"); } else { System.out.println("Failed to make connection!"); } } }

Execute C:\jdbc-test>javac OracleJDBC.java C:\jdbc-test>java -cp c:\jdbctest\ojdbc6.jar;c:\jdbc-test OracleJDBC ------ Oracle JDBC Connection Testing ------Oracle JDBC Driver Registered! You made it, take control your database now!

Specifying Queries at Runtime Using Dynamic SQL


In the previous case, if we want to write a different query, we must modify the program code. But it is convenient to write a program that can execute different SQL queries or updates (or other operations) dynamically at runtime. That is, we may want to write a program that accepts an SQL query typed from the monitor, executes it, and displays its result, which is called a dynamic SQL. The reason for separating PREPARE and EXECUTE is that if the command is :
To be executed multiple times in a program, it can be prepared only once. Preparing the command generally involves
syntax and other types of checks by the system and generating the code for executing it.

It is possible to combine the PREPARE and EXECUTE commands as:


EXEC SQL EXECUTE IMMEDIATE :sqlupdatestring ; This is useful if the command is to be executed only once But the previous one helps to the catch errors

Although dynamic SQL is preferable, it is much more complicated as the types or number of attributes to be retrieved is unknown at the time of writing code.

Example Dynamic SQL


//Program Segment E3: 0) EXEC SQL BEGIN DECLARE SECTION ; 1) varchar sqlupdatestring [256] ;

2) EXEC SQL END DECLARE SECTION ; ... 3) prompt("Enter the Update Command: ", sqlupdatestring) ;

4) EXEC SQL PREPARE sqlcommand FROM :sqlupdatestring ; 5) EXEC SQL EXECUTE sqlcommand ; ...

Database Programming with Function Calls and Stored Procedures: PL/SQL


Subprograms are named PL/SQL blocks that can accept parameters and can be invoked whenever required. A subprogram will have three parts namely,
Declarative part Executable part Exception Handling

There are two types of subprograms namely,


Procedures Functions

A Procedure is a subprogram that performs a specification. A procedure has two parts namely, specification and body. Procedure specification is from the procedure keyword to the parameter list and the procedure body is from the IS keyword to the End keyword.

Syntax Procedures and Functions

Example for Stored Procedure


Before Execution of the Procedure: SQL> select * from student_marks; REGNO MARK1 MARK2 TOTAL ---------- ---------- ---------- ---------1 67 90 2 78 56 3 23 56 SQL> select * from student_result; REGNO STATUS ---------- ---1 2 3

Output:
SQL> select * from student_marks; REGNO MARK1 MARK2 TOTAL ---------- ---------- ---------- ---------1 67 90 157 2 78 56 3 23 56 SQL> select * from student_result; REGNO STATUS ---------- ---1 pass 2 3

SQL> get proc_result; 1 create or replace procedure pro_result (reg number, m1 number, 2 m2 number) 3 is 4 mark number(3); 5 begin 6 update student_marks set total = mark1 + mark2 where 7 regno = reg; 8 mark := (m1+m2)/2; 9 if mark >= 50 then 10 update student_result set status = 'pass' where regno = reg; 11 else 12 update student_result set status = 'fail' where regno = reg; 13 end if; 14* end; SQL> / Procedure created. SQL> exec pro_result(1,67,90); PL/SQL procedure successfully completed.

Example for Writing and Calling Functions


Before Execution: SQL> select * from RDBMS_marks; REGNO MARK1 MARK2 MARK3 CONSOLIDATED GRADE ---------- ---------- ---------- ---------- ----------------- -1 90 80 88 86 2 55 65 50 57 3 60 70 68 66 4 20 40 45 35 5 99 95 90 95
Output: SQL> update RDBMS_marks set grade = grade_fn(consolidated); REGNO MARK1 MARK2 MARK3 CONSOLIDATED GRADE ---------- ---------- ---------- ---------- ----------------- -1 90 80 88 86 A 2 55 65 50 57 D 3 60 70 68 66 C 4 20 40 45 35 F 5 99 95 90 95 O

SQL> get calc_grade 1 create or replace function grade_fn (mark number) 2 return char 3 is 4 gd char; 5 begin 6 if mark >= 90 then 7 gd:= '0'; 8 elsif mark >= 80 and mark < 90 then 9 gd:='A'; 10 elsif mark >= 70 and mark < 80 then 11 gd:='B'; 12 elsif mark >= 60 and mark < 70 then 13 gd:='C'; 14 elsif mark >= 50 and mark < 60 then 15 gd:='D'; 16 else 17 gd:='F'; 18 end if; 19 return gd; 20* end; 21 / Function created.

Vous aimerez peut-être aussi