Scalar subqueries
-
Upload
jaseme7579 -
Category
Documents
-
view
235 -
download
0
Transcript of Scalar subqueries
-
8/7/2019 Scalar subqueries
1/22
Fall 2001 Database Systems 1
Scalar subqueries
A scalar subquery is any expression that produces a
single value (single tuple/ single column)
Examples:
SELECT max(amount) FROM bidsSELECT count(*) FROM items
Scalar subqueries can be used as if they were
constants
in expressions in the WHERE clause, and
to output values in the SELECT clause
-
8/7/2019 Scalar subqueries
2/22
Fall 2001 Database Systems 2
Scalar subqueries
Find items with average bid 60 or more. Print the
name of the item and the average bid.
SELECT I.name, avg(B.amount)
FROM Items I, Bids B
WHERE I.iid=B.iid
GROUP BY I.iid, I.name
HAVING avg(B.amount) > 60
-
8/7/2019 Scalar subqueries
3/22
Fall 2001 Database Systems 3
Scalar subqueries
Find items with average bid 60 or more. Print the name
of the item and the average bid.
SELECT I.name,
FROM Items I
WHERE 60 < (SELECT avg(B.amount)
FROM bids BWHERE B.iid = I.iid)
(SELECT avg(B2.amount)
FROM Bids B2
WHERE B2.iid = I.iid) avgAmount
Return a single
value for each tuple
Check the boolean condition
for each tuple
-
8/7/2019 Scalar subqueries
4/22
Fall 2001 Database Systems 4
What cant you do with SQL
or can you?
You are limited by the functions implemented in the
database
Not allowed: SELECT median(salary)
You can add new functions to the database engine andimplement new types in a native programming language like
C,C++ (support varies)
You can have subselects in FROM and WHERE that
return a set of values, but not in SELECT
Allowed: SELECT * FROM (SELECT b.bid FROM bids bWHERE b.amount>20)
Not allowed: SELECT avg(SELECT b.amount FROM .. ) FROM
..
-
8/7/2019 Scalar subqueries
5/22
Fall 2001 Database Systems 5
What cant you do with SQL
or can you?
You cannot ask transitive queries
Given a relation emp(A,B) for immediate managers B or A, you cannotfind all managers of a person A.
SQL3 includes a recursive query definition construct not implementedin Oracle.
WITH RECURSIVE manages(emp, mgr) AS
(SELECT E1.emp, E1.mgr FROM employee E1)
UNION
(SELECT M.emp, E2.mgr FROM manages M, employee E2
WHERE M.mgr = E.id)
SELECT M2.empFROM manages M2
WHERE M2.emp = M2.mgr ;
Recursive queries may produce infinite loops and it is best left to programmerswith solid logic background.
-
8/7/2019 Scalar subqueries
6/22
Fall 2001 Database Systems 6
Embedded SQL
You can embed SQL statements into many programming
languages procedural power (loops, variables, etc.)
The main components of embedded SQL programming:
Regular program blocks SQL code
Methods to connect to the database, invoke the SQL code and
retrieve results
Methods to pass data from program variables to the SQL code
Methods to retrieve data from the result of queries to programvariables
-
8/7/2019 Scalar subqueries
7/22
Fall 2001 Database Systems 7
#include
exec sql include sqlca;
char user_prompt[] = "Please enter username and password: ";
char cid_prompt[] = "Please enter customer ID: ";
int main()
{
exec sql begin declare section; /* declare SQL host variables */
char cust_id[5];
char cust_name[14];
float cust_discnt; /* host var for discnt value */
char user_name[20], user_pwd[20];
exec sql end declare section;
exec sql whenever sqlerror goto report_error; /* error trap condition */
exec sql whenever not found goto notfound; /* not found condition */
exec sql connect :user_name
identified by :user_pwd; /* ORACLE format: connect */
while (prompt(cid_prompt, 1, cust_id, 4) >= 0) {exec sql select cname,
discnt into :cust_name, :cust_discnt /* retrieve cname, discnt */
from customers where cid = :cust_id;
exec sql commit work; /* release read lock on row */
printf("CUSTOMER'S NAME IS %s AND DISCNT IS %5.1f\n",
cust_name, cust_discnt); /* NOTE, (:) not used here */
continue;
-
8/7/2019 Scalar subqueries
8/22
Fall 2001 Database Systems 8
ProC
Each ESQL statement starts with EXEC SQL keyword
and ends with a semicolon ;
A pre-compiler will scan a program file and only read the
statements enclosed within EXEC SQL statements anddisregard everything else.
SQLCA is a specific data structure for storing status
codes of all SQL operations
/* always have this for error handling*/exec sql include sqlca ;
-
8/7/2019 Scalar subqueries
9/22
Fall 2001 Database Systems 9
Program.pc
Program.c
-
8/7/2019 Scalar subqueries
10/22
Fall 2001 Database Systems 10
Variables in ESQL
All variables that will be used in an SQL statement must be declared
using an ESQL declaration and data type
exec sql begin declare section ;
VARCHAR e_name[30], username[30], passwd[30] ;
INTEGER e_ssn, e_dept_id ;exec sql end declare section ;
You can use almost any SQL command in ESQL as long as proper
input to these commands are provided in the form of program
variables.
To execute any command, you must first connect to a database inwhich all your tables reside.
exec sql connect :username identified by :passwd ;
-
8/7/2019 Scalar subqueries
11/22
Fall 2001 Database Systems 11
Executing SQL commands
Suppose we want to find the name of an employee given his/herSSN (input by the user of the program):
exec sql select name, dept_id into :e_name, :e_dept_idfrom employee
where ssn = :e_ssn ;
Read the value of the variable e_ssn and execute the SQLstatement using this value, store the returned values of columnsname and dept_id in the program variables e_name and
e_dept_id.
Compare the above query with the expression below. What is the difference?
exec sql select name, dept_id
from employee where ssn = e_ssn ;
Program variables arepreceded by :
-
8/7/2019 Scalar subqueries
12/22
Fall 2001 Database Systems 12
Dealing with Strings
There is a mismatch between the definition of a string in Oracle and
in C/C++.
In C, the end of a string is identified by the null character \0. Hence,
Sibel would be stored as characters S,i,b,e,l,\0.
In Oracle, the length of a string is stored together with the string andthere is no special end of string character.
If you convert a data string from Oracle to C, you must pad it with \0
manually!
The data type VARCHAR e_name[30] is translated by the pre-
compiler to the following structure:
struct {
unsigned short len
unsigned char arr[30]
} e_name ;
-
8/7/2019 Scalar subqueries
13/22
Fall 2001 Database Systems 13
More on strings
Putting the pieces together:
strcpy(username.arr, Sibel Adali) ;username.len = strlen(Sibel Adali) ;strcpy(passwd.arr, tweety-bird) ;
passwd.len = strlen(tweety-bird) ;exec sql connect :username identified by :passwd ;scanf(%d, &e_ssn) ;
exec sql select name, dept_id into :e_name, :e_dept_idfrom employee where ssn = :e_ssn ;
e_name.arr[e_name.len] = \0 ; /* so can use string in C*/printf(%s, e_name.arr) ;
exec sql commit work ; /* make any changes permanent */exec sql disconnect ; /* disconnect from the database */
-
8/7/2019 Scalar subqueries
14/22
Fall 2001 Database Systems 14
ESQL - Cursors
When a select statement returns a set of tuples, then the
tuples (rows) can only be retrieved one by one.
programming language variables can contain only one
value at a time
this is sometimes called an impedance mismatch Cursor operations
declare a cursor using a regular SQL query (no into).
exec sql declare emps_dept cursor for
select ssn, name from employee
where dept_id = :e_dept_id ;
-
8/7/2019 Scalar subqueries
15/22
-
8/7/2019 Scalar subqueries
16/22
Fall 2001 Database Systems 16
How do we know when we
reach the end of a cursor?
Each SQL statement executed in a program produces
a status code that can be retrieved from the SQL
Communication Area (SQLCA) variables.
Check the sqlcode to see if the end of a cursor is
reached (its expected value depends on the system).if (sqlca.sqlcode == -1) { }
Error handling statements
exec sql whenever sqlerror
{continue, stop, goto label, call function} exec sql whenever is a trap condition, it hold for all
exec sql statements unless a new trap condition
overrides the current one.
-
8/7/2019 Scalar subqueries
17/22
-
8/7/2019 Scalar subqueries
18/22
Fall 2001 Database Systems 18
Dynamic SQL
In Dynamic SQL, embedded SQL statements are created on the fly
using strings!
these strings are fed to an exec sql statement
exec sql execute immediate :sql_string
Since dynamic SQL statements are not known to the pre-compiler atcompile time, they must be optimized at run time!
Create a query once using a prepare statement and run it multiple
times using the execute statement.
strcopy(sqltext.arr, delete from employee where ssn = ?) ;
sqltext.len=str.len(sqltext.arr) ;exec sql prepare del_emp from :sqltext ;
exec sql execute del_emp using :cust_id ;
-
8/7/2019 Scalar subqueries
19/22
Fall 2001 Database Systems 19
SQLDA
When we execute a dynamic SQL statement, we do not know which
columns will be returned and how many columns will be returned.
The SQLDA descriptor definition allows us to find the number of
columns and the value for each column.
exec sql include sqlda ;
exec sql declare sel_curs cursor for sel_emps ;
exec sql prepare sel_emps from :sqltext ;
exec sql describe sel_emps into sqlda ;
exec sql open sel_curs ;
exec sql fetch sel_curs using descriptor sqlda ;
-
8/7/2019 Scalar subqueries
20/22
Fall 2001 Database Systems 20
JDBC Dynamic SQL
Driver is a piece of software that enables
communication between a program and a
database system (DMBS specific packages).
It implements a number of main classes: Connection (opening, closing, committing)
Statement (executing queries)
Result set (going through cursors, extracting
information)
-
8/7/2019 Scalar subqueries
21/22
Fall 2001 Database Systems 21
import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.driver.*;
class Employee{
public static void main (String args []) throws SQLException
{//Set your user name and the password
String userName = "dummy" ;
String passWord = "dummy" ;
// Load the Oracle JDBC driver
DriverManager.registerDriver(neworacle.jdbc.driver.OracleDriver());
Connection conn =
DriverManager.getConnection
("jdbc:oracle:thin:@vcmr-57.server.rpi.edu:1521:ora8",userName,passWord);
-
8/7/2019 Scalar subqueries
22/22
Fall 2001 Database Systems 22
// Create a statement which will return a cursor that will allowyou to
// scroll the result set using both "next" and "previous"methods
Statement stmt = conn.createStatement
(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rset = stmt.executeQuery
("SELECT name, oid FROM items ");
// Iterate through the result and print the item nameswhile (rset.next ()) {
//Get item name, which is the first column
System.out.println (rset.getString (1));
PreparedStatement pstmt = conn.prepareStatement
("SELECT name FROM owners WHERE oid = ?") ;
//Feed the owner id retrieved from rset into pstmt
pstmt.setInt(1, rset.getInt (2));
ResultSet dset = pstmt.executeQuery() ;
if (dset.next())
System.out.println(dset.getString (1));
} } }