Scalar subqueries

download Scalar subqueries

of 22

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));

    } } }