# Database

notes

Relational Model

12 August 2022

In his seminal 1970 paper “A Relational Model of Data for Large Shared Data Banks,” E. F. Codd defined a relational model based on mathematical set theory. Today, the most widely accepted database model is the relational model.

A relational database is a database that conforms to the relational model. The relational model has the following major aspects:

  • Structures
    Well-defined objects store or access the data of a database.

  • Operations
    Clearly defined actions enable applications to manipulate the data and structures of a database.

  • Integrity rules
    Integrity rules govern operations on the data and structures of a database.

A relational database stores data in a set of simple relations. A relation is a set of tuples (rows). A tuple is an unordered set of attribute (columns) values.

A table is a two-dimensional representation of a relation in the form of rows (tuples) and columns (attributes). Each row in a table has the same set of columns. A relational database is a database that stores data in relations (tables). For example, a relational database could store information about company employees in an employee table, a department table, and a salary table.

References

Oracle

notes

PL/SQL Pseudocolumns

27 July 2022

A pseudocolumn behaves like a table column, but is not actually stored in the table. You can select from pseudocolumns, but you cannot insert, update, or delete their values. A pseudocolumn is also similar to a function without arguments. However, functions without arguments typically return the same value for every row in the result set, whereas pseudocolumns typically return a different value for each row.

Rownum is an example for pseudocolumns.

References

Oracle Docs

notes

PL/SQL ROWNUM

25 July 2022

ROWNUM is a pseudocolumn (not a real column) that is available in a query. ROWNUM will be assigned the numbers 1, 2, 3, 4, … N , where N is the number of rows in the set ROWNUM is used with. A ROWNUM value is not assigned permanently to a row. A row in a table does not have a number; you cannot ask for row 5 from a table—there is no such thing.

ROWNUM value is actually assigned. A ROWNUM value is assigned to a row after it passes the predicate phase of the query but before the query does any sorting or aggregation. Also, a ROWNUM value is incremented only after it is assigned, which is why the following query will never return a row:

select * from t 
where ROWNUM > 1;

Below query will give you the wrong results,

select *   from emp 
where ROWNUM <= 5 
order by sal desc;

To understand the above, check the below query with this structure:

select ..., ROWNUM
from t
where <where clause>
group by <columns>
having <having clause>
order by <columns>;

Think of it as being processed in this order:

  • The FROM/WHERE clause goes first.
  • ROWNUM is assigned and incremented to each output row from the FROM/WHERE clause.
  • SELECT is applied.
  • GROUP BY is applied.
  • HAVING is applied.
  • ORDER BY is applied.

Below is the way ti use the rownum

select *   from  
( select * from emp 
order by sal desc ) 
where ROWNUM <= 5;
References

Oracle Blog

notes

Validate Conversion

24 July 2022

VALIDATE_CONVERSION determines whether expr can be converted to the specified data type. If expr can be successfully converted, then this function returns 1; otherwise, this function returns 0. If expr evaluates to null, then this function returns 1. If an error occurs while evaluating expr, then this function returns the error.

SELECT VALIDATE_CONVERSION(1000 AS BINARY_DOUBLE)
FROM DUAL;

SELECT VALIDATE_CONVERSION('1234.56' AS BINARY_FLOAT)
FROM DUAL;

SELECT VALIDATE_CONVERSION('July 20, 1969, 20:18' AS DATE,
    'Month dd, YYYY, HH24:MI', 'NLS_DATE_LANGUAGE = American')
FROM DUAL;

SELECT VALIDATE_CONVERSION('200 00:00:00' AS INTERVAL DAY TO SECOND)
FROM DUAL;

SELECT VALIDATE_CONVERSION('P1Y2M' AS INTERVAL YEAR TO MONTH)
FROM DUAL;

SELECT VALIDATE_CONVERSION('$100,00' AS NUMBER,
    '$999D99', 'NLS_NUMERIC_CHARACTERS = '',.''')
FROM DUAL;

SELECT VALIDATE_CONVERSION('29-Jan-02 17:24:00' AS TIMESTAMP,
    'DD-MON-YY HH24:MI:SS')
FROM DUAL;

SELECT VALIDATE_CONVERSION('1999-12-01 11:00:00 -8:00'
    AS TIMESTAMP WITH TIME ZONE, 'YYYY-MM-DD HH:MI:SS TZH:TZM')
FROM DUAL;

SELECT VALIDATE_CONVERSION('11-May-16 17:30:00'
    AS TIMESTAMP WITH LOCAL TIME ZONE, 'DD-MON-YY HH24:MI:SS')
FROM DUAL;
References

Oracle Docs

notes

PL/SQL SELECT INTO Clause

20 July 2022

The SELECT INTO is actually a standard SQL query where the SELECT INTO clause is used to place the returned data into predefined variables.

create or replace function auth_Name
( v_auth_state IN author.author_state%type)
return varchar2

as
    v_authName author.author_last_name%type;
    
    begin
    select author_last_name into v_authName
    from author
    where author_state = v_auth_state;

    return v_authName;

    exception

    when TOO_MANY_ROWS
    then return 'Too Many Authors in that State';

    when NO_DATA_FOUND
    then return 'No Authors in that State';

    when others
    then raise_application_error(-20011,'Unknown Exception in authName Function');

end;
References

dba-Oracle

notes

Count(*) is unsafe

19 July 2022

SELECT COUNT(*) INTO var WHERE CONDITION;

IF var > 0 THEN
SELECT NEEDED_FIELD INTO otherVar WHERE CONDITION;

In PLSQL method with count(*) is unsafe in above code. If another session deletes the row that met the condition after the line with the count(*), and before the line with the select ... into, the code will throw an exception that will not get handled.

Use the below insted,

SELECT NEEDED_FIELD INTO var WHERE CONDITION;
EXCEPTION
WHEN NO_DATA_FOUND
References

Stack Overflow

notes

Set Define OFF

18 July 2022

The SET DEFINE command changes the prefix character used to mark substitution variables. You can use SET DEFINE to turn variable substitution off.

SET DEF[INE] {OFF | ON | prefix_char}

Define is a SQL*Plus client variable. It is NOT a database level setting.

When you start SQL*Plus, variable substitution will be on by default, and the default prefix character is an ampersand. If you are running a script that uses ampersands in text strings, you may want to change the prefix character to something else. If your script doesn’t use substitution variables, you may find it easiest to turn the feature off.

References

Oreilly

notes

TYPE Attribute

2 March 2022

The %TYPE attribute lets use the datatype of a field, record, nested table, database column, or variable in your own declarations, rather than hardcoding the type names.

You can use the %TYPE attribute as a datatype specifier when declaring constants, variables, fields, and parameters. If the types that you reference change, your declarations are automatically updated.

This technique saves you from making code changes when, for example, the length of a VARCHAR2 column is increased. Note that column constraints, such as the NOT NULL and check constraint, or default values are not inherited by items declared using %TYPE.

essay

PL/SQL - Explicit Cursors

31 January 2022

As discussed earlier, there are two types of cursors: Implicit cursors and explicit cursors. In this section, we will focus on explicit cursors and their functionality...