Upload
phamdang
View
217
Download
1
Embed Size (px)
Citation preview
数据库系统概论讲义,第8章 编程SQL,2015,3
数据库系统概论讲义,第8章 编程SQL,2015,3
数据库系统概论 An Introduction to Database Systems
第八章 数据库编程
(ODBC, PL/SQL)
2016, 3, 29
数据库系统概论讲义,第8章 编程SQL,2015,3
Programmatic SQL
• Three types of programmatic SQL – Embedded SQL statements
• ISO standard specifies embedded support for C, COBOL, Fortran, Pascal, PL/1
– Application Programming Interface (API) • ODBC • JDBC • Specific API, like APIs in COBASE
– Procedure SQL • PL/SQL
数据库系统概论讲义,第8章 编程SQL,2015,3
The Open Database Connectivity Standard(1)
• An alternative approach to embedding SQL statements directly in a host language is to provide programmers with a library of functions that can be invoked from the application software.
• For many programmers, the use of library routines is standard practice, and they find API a relatively straightforward way to use SQL
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Standard(2) • The API consists of a set of library function for
many of the common types of database access that programmers required, such as connecting to a database, executing SQL, retrieving individual rows of a result table
• One problem with this approach has been lack of interoperability – Programs have to be processed using the DBMS
vendor’s precompiler and linked with this vendor’s API library
– That will produces DBMS-specific code for each DBMS they want to access
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Standard(3) • In an attempt to standardize this approach,
Microsoft produced the Open Database Connectivity (ODBC) standard
• ODBC technology provides a common interface for accessing heterogeneous SQL database, based on SQL as the standard for accessing data
• This interface provides a high degree of interoperatibility: – A single application can access different SQL
DBMSs through a common set of code
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Standard(4)
• ODBC has emerged as a de facto industry standard. One reason for ODBC popularity is its flexibility – Application are not tied to a proprietary vendor API – SQL statements can be explicitly included in source code or
constructed dynamically at runtime; – An application can ignore the underlying data communications
protocols; – ODBC is designed in conjunction with the X/Open and ISO Call-
Level Interface (CLI) standard – There are ODBC database drivers available today for many of most
popular DBMSs
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Architecture(1)
• The ODBC interface defines the following: – A library of function calls that allow an application to
connect to a DBMS, execute SQL statement, and retrieve results;
– A standard way to connect and log on to a DBMS – A standard representation of data types – A standard set of error codes – SQL syntax based on the X/Open and ISO Call-Level
Interface (CLI) specification
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Architecture(2)
• The ODBC architecture has four components: – Application – Driver Manager – Driver and Database Agent – Data Source
数据库系统概论讲义,第8章 编程SQL,2015,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
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Architecture(4)
Application
Source TS
Source TS
Source TS
Source TS
Source TS
Q
Q’ Q’ Q’ Q’ Q’
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Architecture(4)
Application
Source TS
Source TS
Source TS
Source TS
Source TS
Q
Q’ Q’ Q’ Q’ Q’ ODBC Driver
ODBC Driver
ODBC Driver
ODBC Driver
ODBC Driver
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC Conformance Levels • ODBC defines two different conformance levels for
drivers: – ODBC API – ODBC SQL
• ODBC defines a core grammar that corresponds to the – X/Open CAE specification (1992) – ISO CLI specification (1995)
• ODBC 3.0 fully implements both these specifications and adds features commonly needed by developers of screen-based database applications, such as scrollable cursor
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC SQL Conformance Levels(1) • Minimum SQL grammar
– DDL: • CREATE TABLE • DROP TABLE
– DML: • Simple SELECT • INSERT, UPDATE , DELETE
– Expressions: simple ( such as A > B+C ) – Data Type
• CHAR, VARCHAR, LONG VARCHAR
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC SQL Conformance Levels(2) • Core SQL grammar
– Minimum SQL grammar and data types – DDL:
• ALTER TABLE, CREATE INDEX, DROP INDEX, CREATE VIEW, DROP VIEW, GRANT, REVOKE
– DML: • Full SELECT
– Expressions: subquery, set function – Data Type
• DECIMAL, NUMBER, SMALLINT, INTEGER, REAL, FLOAT, DOUBLE PRECISION
数据库系统概论讲义,第8章 编程SQL,2015,3
ODBC SQL Conformance Levels(3) • Extended SQL grammar
– Minimum and core SQL grammar and data types – DML:
• Outer joins, positioned UPDATE, positioned DELETE, SELECT FOR UPDATE, union
– Expressions: scalar functions such as SUBSTRING and ABS, date, time
– Data Type • BIT, TINYBIT, BIGING, BINARY, VARBINARY, LONG
VARBINARY, DATE, TIME, TIMESTAMP – Batch SQL statements – Procedure calls
数据库系统概论讲义,第8章 编程SQL,2015,3
Using ODBC(1) • Allocate an environment handle:
– SQLAllocEnv(): allocates memory for the handle and initialize the ODBC Call-Level Interface for use by the application
• Allocate a connection handle – SQLAllocConnect(): A connection consists of a
driver and a data source. A connection handle identifies each connection and identifies which driver to use and which data source to use with that driver.
数据库系统概论讲义,第8章 编程SQL,2015,3
Using ODBC (2) • Connect to the data source
– SQLConnect():This call loads a driver and establishes a connection to the named data source.
• Allocate a statement handle – SQLAllocStmt(): A statement handle references
statement information such as network information, SQLSTATE values and error messages, cursor name, number of result set columns
• On completion, all handles must be freed and the connection to the data source terminated
数据库系统概论讲义,第8章 编程SQL,2015,3
Using ODBC (3)
• Execute SQL statement – SQLExecdirect – SQLPrepare, SQLExecute
数据库系统概论讲义,第8章 编程SQL,2015,3
Using ODBC (4)
• Result processing – Get information
• SQLNumResultCols: return the col number • SQLDescribeCol, SQLColAttribute: return the coloumn
name, data type, ect.. – Automatically using cursor for a query
• SQLBindCol: • SQLFetch • SQLGetData • SQLClosecursor
数据库系统概论讲义,第8章 编程SQL,2015,3
int Getdata_ODBC(Mo_infor_quad *pdata[ROUTENUMBER],int rmpid)
{ HENV henv; HDBC hdbc; HSTMT hstmt; RETCODE rc; UCHAR selStmt[500]; UCHAR sName[6] SDWORD sNameLen;
数据库系统概论讲义,第8章 编程SQL,2015,3
rc=SQLAllocEnv(&henv); /* allocate an environment handle */ rc=SQLAllocConnect(henv,&hdbc);/* allocate a connection handle
*/ rc=SQLConnect(hdbc, (unsigned char *)"SQL Server Source", SQL_NTS,/* data
source name */ (unsigned char *)"rding", SQL_NTS, /* user identifier */ (unsigned char *)“1234",SQL_NTS); /* password */ /* Note, SQL_NTS directs the driver to determine the length of
the string by locating the null-termination character */ if ( rc==SQL_SUCCESS|| rc == SQL_SUCCESS_WITH_INFO) { rc=SQLAllocStmt(SQL_HANDLE_STMT,hdbc,&hstmt); /* allocate
statement handle */
数据库系统概论讲义,第8章 编程SQL,2015,3
/* Now set up the SELECT statement, execute it, and then bind the columns of the result set */
lstrcp(selStmt, “ SELECT name from students WHERE SSN = ‘2345’”); if ( SQLExecDirect(hStmt, selStmt, SQL_NTS) != SQL_SUCCESS) exit(-1); SQLBindCol(hStmt, 1, SQL_C_CHAR, sName, (SDWORD)sizeof(sName),
&sNameLen); /* Now fetch the result set, row by row */ while ( rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { rc = SQLFetch(hStmt); if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) { ……… } } SQLDisconnect(hstmt); } SQLFreeConnect(hdbc); SQLFreeEnv(henv); }
数据库系统概论讲义,第8章 编程SQL,2015,3
PL/SQL PL/SQL is Oracle's Procedural Language
extension to SQL. • PL/SQL has many programming language
features. • Program units written in PL/SQL can be
stored in compiled form. • PL/SQL code is portable across all operating
systems that support Oracle. • PL/SQL does not support DDL and DCL.
数据库系统概论讲义,第8章 编程SQL,2015,3
PL/SQL Block
A PL/SQL block contains logically related SQL and PL/SQL statements.
Three sections in a typical PL/SQL block: • declaration (optional): declare identifiers
(variables and constants). • execution (required): execute SQL and PL/SQL
statements. • exception (optional): perform error handling.
数据库系统概论讲义,第8章 编程SQL,2015,3
Sample Program 1 (1) declare student_name Students.Name%TYPE; student_dept Students.Dept_name%TYPE;
begin select Name, Dept_name into student_name, student_dept /* no : needed before host variables */ from Students where SSN = `123456789';
数据库系统概论讲义,第8章 编程SQL,2015,3
Sample Program 1 (2) if (student_dept = ‘Computer Science’) then dbms_output.put_line(`This is a CS student.'); else dbms_output.put_line(`This is not a CS student.'); end if; end; / /* end each PL/SQL program with / */
数据库系统概论讲义,第8章 编程SQL,2015,3
Execute PL/SQL Program
• Save the program in a file: sample1.sql • Execute the program in SQL*Plus SQL> start sample1 • Enable output to the screen: SQL> set serveroutput on or place set serveroutput on at the
beginning of the PL/SQL program.
数据库系统概论讲义,第8章 编程SQL,2015,3
Procedure procedure procedure_name [(parameter, parameter, …, parameter)] is [local declarations] begin execution section; [exception section] end; parameter definition: parameter_name [in | out | in out] data_type
数据库系统概论讲义,第8章 编程SQL,2015,3
Procedure • A parameter has a specified name and data
type but can also be designated as: – IN parameter is used as an input value only – OUT parameter is used as an output value only – IN OUT parameter is used as both an input and
an output value
数据库系统概论讲义,第8章 编程SQL,2015,3
Sample Program (1) set serveroutput on declare v_cid customers.cid%type; v_cname customers.cname%type; v_city customers.city%type; status boolean; procedure get_customer( cust_id in customers.cid%type, cust_name out customers.cname%type, cust_city out customers.city%type, status out boolean) is
数据库系统概论讲义,第8章 编程SQL,2015,3
Sample Program (2) begin select cname, city into cust_name, cust_city from customers where cid = cust_id; status := true; exception when no_data_found then status := false; end; begin v_cid := ‘c001’; get_customer(v_cid, v_cname, v_city, status);
数据库系统概论讲义,第8章 编程SQL,2015,3
Sample Program (3) if (status) then dbms_output.put_line(v_cid || ‘ ‘ || v_cname || ‘ ‘ || v_city); else dbms_output.put_line(‘Customer ‘ || v_cid || ‘ not found’); end if; end; /
数据库系统概论讲义,第8章 编程SQL,2015,3
Stored Procedure and Function (1)
• procedure or function definitions can be stored for later use (in SQL and other PL/SQL blocks).
• Stored procedures/functions are stored in compiled form.
• Stored procedures and functions are created by
create or replace procedure proc_name … create or replace function func_name …
– only in parameter allowed for function.
数据库系统概论讲义,第8章 编程SQL,2015,3
An Example set serveroutput on create or replace procedure get_cus_name( v_cust_id in customers.cid%type) is v_cust_name customers.cname%type; begin select cname into v_cust_name from customers where cid = v_cust_id; dbms_output.put_line(‘Customer name: ‘ || v_cust_name); end; / show errors
数据库系统概论讲义,第8章 编程SQL,2015,3
Stored Procedure and Function (2)
• Compile stored procedure in file proc.sql SQL> start proc show errors displays errors detected during
compiling the procedure. • Execute stored procedure get_cus_name SQL> execute get_cus_name(‘c001’);
数据库系统概论讲义,第8章 编程SQL,2015,3
Package • A package is a group of related PL/SQL
objects (variables, …), procedures, and functions.
• Each package definition has two parts: – package specification – package body
• Package specification provides an interface to the users of the package.
• Package body contains actual code.
数据库系统概论讲义,第8章 编程SQL,2015,3
Package Specification (1)
create or replace package banking as function check_balance (account_no in Accounts.acct_no%type) return Accounts.balance%type; procedure deposit (account_no in Accounts.acct_no%type, amount in Accounts.balance%type);
数据库系统概论讲义,第8章 编程SQL,2015,3
Package Specification (2)
procedure withdraw (account_no in Accounts.acct_no%type, amount in Accounts.balance%type); end; / show errors
数据库系统概论讲义,第8章 编程SQL,2015,3
Package Body (1) create or replace package body banking as function check_balance (account_no in Accounts.acct_no%type) return Accounts.balance%type is acct_balance Accounts.balance%type; begin select balance into acct_balance from Accounts where acct_no = account_no; return acct_balance; end;
数据库系统概论讲义,第8章 编程SQL,2015,3
Package Body (2) procedure deposit (account_no in Accounts.acct_no%type, amount in Accounts.balance%type) is begin if (amount <= 0) then dbms_output.put_line(‘Wrong amount.’); else update Accounts set balance = balance + amount where acct_no = account_no; end if; end;
数据库系统概论讲义,第8章 编程SQL,2015,3
Package Body (3)
procedure withdraw (account_no in Accounts.acct_no%type, amount in Accounts.balance%type) is acct_balance Accounts.balance%type;
数据库系统概论讲义,第8章 编程SQL,2015,3
Package Body (4) begin acct_balance := check_balance(account_no); if (amount > acct_balance) then dbms_output.put_line(‘Insufficient fund.’); else update Accounts set balance = balance - amount where acct_no = account_no; end if; end; end; /* end of the package body */ / show errors
数据库系统概论讲义,第8章 编程SQL,2015,3
Cursor in PL/SQL (1) • Consider an SQL query returning multiple
rows. How to save the result of the query? • Save the result into a big array.
– No easy way to estimate the size of the result. – The result could be too large for any memory-based
array.
• Save one-row-at-a-time: This is the SQL approach.
数据库系统概论讲义,第8章 编程SQL,2015,3
Cursor in PL/SQL (2)
• Define a cursor: cursor cursor_name is
select_statement; Example: cursor c1 is
select cid, cname, city from customers;
• The query defining the cursor is not executed at the declaration time.
数据库系统概论讲义,第8章 编程SQL,2015,3
Working with Cursor (1)
• open cursor_name; • fetch cursor_name into record_or_variable-list; • close cursor_name;
Open causes the query defining the cursor
to be executed.
数据库系统概论讲义,第8章 编程SQL,2015,3
Built-in Package: dbms_sql (1)
• dbms_sql can be used to dynamically create and execute SQL statements, including DDL statements.
• Main steps: – Open a handle cursor – Parse the statement – Close the cursor
数据库系统概论讲义,第8章 编程SQL,2015,3
Built-in Package: dbms_sql (2) declare handle integer; stmt varchar2(256); begin stmt := 'create table test (attr1 number(2)’ || ' primary key, attr2 number(4))'; handle := dbms_sql.open_cursor; dbms_sql.parse(handle,stmt,DBMS_SQL.V7); dbms_output.put_line('Table TEST created'); dbms_sql.close_cursor(handle); end; /