course:
Database Applications (NDBI026) WS2018/19
RNDr. Michal Kopecký, Ph.D. Department of Software Engineering, Faculty of Mathematics and Physics, Charles University in Prague
Views Creating views
Using Views
Procedural Extensions
Motivation
Procedures
Functions
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 2
View ~ named SELECT statement Represents a “virtual” table When querying the view the query is
computed every time Similar to macro definition in C programming
language
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 4
By statement CREATE VIEW view_name [col_name [, …]] AS SELECT … [WITH [{CASCADE | LOCAL} CHECK OPTION]
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 5
DBI026 -DB Aplikace - MFF UK
Example: CREATE VIEW Prague_Citizen AS SELECT * FROM Citizen WHERE City=’Prague’;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 6
Columns can be named explicitly
If they are not, they inherit names from the SELECT statement (where all expressions must be named in this case)
WITH CHECK OPTION ensures, that all inserted and/or updated rows become/remain visible through the view
If this condition should be violated, the actualization is rejected
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 7
Example: CREATE VIEW Prague_Citizen AS SELECT * FROM Citizen WHERE City=’Prague’ WITH CHECK OPTION; -- wrong actualization UPDATE Prague_Citizen SET City=’Pilzen’ WHERE ID=7510151234;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 8
Usage of views
Predefined (and hidden to the user) join of more tables (split by normalization etc.)
Individualization of visible data for different users
▪ Different users can see different rows in the same view according to their definition in the database.
▪ Different users can have defined completely different view in their default schema and so they can see even different structure (different columns)
▪ …
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 9
Example: CREATE VIEW Emp_My_Dept AS SELECT E.Nr, E.Surname, E.Name, E.Job FROM Employee AS E, Employee AS X WHERE X.Login=CURRENT_USER AND E.DeptNr=X.DeptNr;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 10
Some applications can have problems when the order of columns in the view changes (due binding variables to columns by their position instead of by name) can bring problems
When creating vies it is advisable to assure, that future changes in table structures have minimal impact on the view structure Explicitly mention all needed columns in the SELECT
statement ▪ It is useful to qualify all columns in SELECT statement by name/alias
of given source (table/view)
Explicitly name view columns
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 11
How to prevent shift of columns in views, that use the * symbol to show all columns? In the view on more than one table it is
appropriate use * at most once, for columns of one table only, using syntax tab_name.* on the end of the column list in the SELECT clause.
No further columns should be named afterwards.
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 12
Example: CREATE VIEW Emp_Dept AS SELECT E.EmpNr, E.Name, D.* FROM Employee AS E NATURAL RIGHT OUTER JOIN Department AS D;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 13
It is not recommendable to use ORDER BY clause in the view definition
The ORDER BY clause is not necessary every time
Sometimes other ordering is required
Often more views is joined together in the SELECT statement / other view and the ordering can cause the delays
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 14
When creating views, it is advisable to check the query by the Query optimizer, if the query can be and is optimized well
It is not good idea use views containing GROUP BY in another queries and views. Additional conditions can cause complications to optimizer
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 15
Example: CREATE VIEW Citizen_Counts AS SELECT City, COUNT(*) AS Size FROM Citizen GROUP BY City; SELECT * FROM Citizen_Counts WHERE City=’Pilzen’;
Optimizer gets SELECT * FROM ( SELECT City, COUNT(*) AS Size FROM Citizen GROUP BY City ) ASCitizen_Counts WHERE City=’Pilzen’;
Should change it to SELECT City, COUNT(*) AS Size FROM Citizen WHERE City=’Pilzen’ GROUP BY City;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 16
By statement DROP VIEW view_name;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 17
CREATE VIEW vw_name [(column [, …])] AS SELECT … [WITH {CHECK OPTION | READ ONLY}];
List of columns in brackets WITH READ ONLY
disallows any actualization through the view
CREATE VIEW vw_name [(column [, …])] [WITH ENCRYPTION] AS SELECT … [WITH CHECK OPION];
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 18
INFORMATION_SCHEMA.VIEWS
USER_VIEWS USER_TAB_COLUMNS
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 19
In standard SQL the server obtains and evaluates individual SQL statements.
In given example 2n packets is sent to the server and 2n packets is sent back.
for (;;) { FETCH; if (…) break; if (…) INSERT …; else UPDATE …; };
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 21
n x
1
1
1
1
1
1
Using procedural extension it is possible to send complete piece of code including the application logic and process it on the server
In given example only one packed is sent in both ways.
LOOP FETCH; EXIT WHEN (…); IF (…) THEN INSERT …; ELSE UPDATE …; END LOOP;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 22
1
1
Savings of the communication channel Less number of send/received packets
▪ One packet can contain more than one statement
Substantially less amount of data send over the network ▪ Data can be processed locally on the server without
transferring them to the client
Thinner and less expensive client can be used ▪ The code can be stored on the server
▪ The code can be shared by more/all client applications
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 23
Extension of the server capability by other procedures and functions
Extended data protection
Triggers
Allowed data manipulation can be encapsulated in procedures
The application need not have privileges to manipulate data directly
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 24
Significantly less portability than the table (relational schema) definition and DML language usage (INSERT, UPDATE, DELETE)
Standardized in ANSI SQL-99
Lot of proprietary non-compatible solutions
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 25
Blocks of code with fixed structure (based on PL/1)
Statements have to be terminated by semicolons
[DECLARE declarations] BEGIN statements [EXCEPTION exception handling] END;
Sequence of statements (based on C/C#)
Statements need not to be terminated by semicolons
DECLARE sections are understood as statements
BEGIN … END as well
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 26
DECLARE @ratio FLOAT SELECT @ratio = numerator/denominator FROM Fractions WHERE numerator=123 IF @ratio > 0 UPDATE Fractions SET Result = @ratio WHERE numerator=123
DECLARE ratio NUMBER; BEGIN SELECT numerator/denominator INTO ratio FROM Fractions WHERE numerator=123; IF ratio > 0 THEN UPDATE Fractions SET Result=ratio WHERE numerator=123; END IF; END;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 27
name [CONSTANT] type [:= expr];
Basic types
Standard types
BOOLEAN containing TRUE, FALSE, NULL
@name [AS] type
Basic types
Standard types
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 28
Explicitly by name (as in table column definition) X NUMERIC(7,2);
By copying from another variable Y X%Type;
By copying from table column type E EMP.Ename%Type;
By copying from table row type R EMP%RowType;
▪ Record, containing all fields, corresponding to columns
▪ Access using dot notation
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 29
Empty statement NULL;
Assignment var := expr;
SQL statement UPDATE Emp SET Sal = Sal*1.05; DELETE FROM Emp WHERE EmpNo=1;
Assignment SET @var = expr
SQL příkaz UPDATE Emp SET Sal = Sal*1.05; DELETE FROM Emp WHERE EmpNo=1
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 30
SELECT, returning exactly one row SELECT expr1 [, …] INTO var1 [, …] FROM … WHERE …;
SELECT, returning exactly one row SELECT @var1 = expr1 [, …] FROM … WHERE …;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 31
CREATE [OR REPLACE] PROCEDURE procname [(param_declaration [, …])] {AS | IS} block_without_keyword_DECLARE;
Parameter declaration ▪ name [IN] [OUT] type [{:= | DEFAULT} expression]
▪ IN parameter can be read inside the procedure body
▪ OUT parameter can be set inside the procedure body
Procedure call from the SQL console (in PL/SQL simply by name) ▪ EXEC procname[(expression [, …])]
▪ Parameters are assigned by their order
▪ EXEC procname[(param_name=>expression [, …]) ▪ Parameters are assigned by name
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 32
CREATE PROCEDURE UpdEmpSal ( xEmpNo NUMBER, xSal NUMBER, xComm NUMBER DEFAULT NULL ) AS BEGIN UPDATE Emp SET Sal = xSal, Comm = xComm WHERE EmpNo=xEmpNo; END; / EXEC UpdEmpSal(1234,25500) -- without commissions; EXEC UpdEmpSal(4321,24000,1500);
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 33
The size of parameter types is not declared
{CREATE|ALTER} PROCEDURE procname [; number] [param_declaration [, …]] [WITH RECOMPILE] AS statements [;] Parameter declaration
▪ @name type [= expression] [OUT[PUT]] ▪ OUT[PUT] - parameter is an output parameter
number allows creations of more versions of the same procedure
Procedure call ▪ EXEC[UTE] procname [expression [, …]]
▪ Parameters are assigned by their order
▪ EXEC[UTE] jmproc [@name=expression [, …]] ▪ Parameters are assigned by name
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 34
CREATE PROCEDURE UpdEmpSal @xEmpNo INTEGER, @xSal INTEGER, @xComm INTEGER = NULL AS UPDATE Emp SET Sal = @xSal, Comm = @xComm WHERE EmpNo=@xEmpNo; EXEC UpdEmpSal @xEmpNo = 1234, @xSal = 25500; GO EXEC UpdEmpSal 4321, 24000, 1500; GO
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 35
CREATE [OR REPLACE] FUNCTION func_name [(param_declaration [, …])] RETURN type {AS | IS} block_without_keyword_DECLARE; Return of the result
▪ RETURN expression; ▪ Ends the function execution ▪ Function has to return some value, even in case of NULL value. If not, an
exception is thrown.
Function execution the same as in case of any standard function ▪ SELECT func_name[(expression [, …])] FROM …;
▪ Parameters are assigned by their order
▪ SELECT func_name[(name=>expression [, …])] FROM …; ▪ Parameters are assigned by name
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 36
CREATE FUNCTION Polynomial ( x NUMBER, a NUMBER DEFAULT 0, b NUMBER DEFAULT 0, c NUMBER DEFAULT 0 ) RETURN NUMBER AS BEGIN RETURN (a*x+b)*x+c; END; /
SELECT Polynomial(1, b=>2) FROM DUAL; -- 2*x, x=1, i.e. 2
SELECT Polynomial(2, b=>3, c=>5) FROM DUAL; -- 3*x+5, x=2, i.e. 11
SELECT Polynomial(2, 1, 1, 1) FROM DUAL; -- x^2+x+1, x=2, i.e. 7
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 37
{CREATE|ALTER} FUNCTION func_name [(param_declaration [, …])] RETURNS typ [AS] BEGIN … RETURN expression; END [;] Function execution the same as in case of any standard
function, but with explicit schema prefix Brackets are obligatory even if no parameters are declared ▪ SELECT sch_name.func_name([expression [, …]]) FROM …;
▪ Parameters are assigned by their order
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 38
CREATE FUNCTION Polynomial ( @x FLOAT, @a FLOAT = 0, @b FLOAT = 0, @c FLOAT = 0 ) RETURNS FLOAT AS BEGIN RETURN (@a*@x+@b)*@x+@c; END; GO
SELECT sch_name.Polynomial(1, default, 2 , default); -- 2*x, x=1, i.e. 2
SELECT sch_name.Polynomial(2, default, 3, 5); -- 3*x+5, x=2, i.e. 11
SELECT sch_name.Polynomial(2, 1, 1, 1); -- x^2+x+1, x=2, i.e. 7
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 39
CREATE FUNCTION func_name [(param_declaration [, …])] RETURNS TABLE [AS] RETURN [(] SELECT …[)]
Can be used as a view (this time with parameters)
▪ SELECT * FROM sch_name.func_name([expression [, …]]);
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 40
CREATE FUNCTION func_name [(param_declaration [, …])] RETURNS @varname TABLE (table definition) [AS] BEGIN body that inserts data into pseudo-table @varname RETURN END [;]
Can be used as a view (this time with parameters) ▪ SELECT * FROM func_name([expression [, …]]);
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 41
IF condition THEN statementsIF
[ELSIF condition THEN statementsELSIF1
[ELSIF condition THEN statementsELSIF2…]] [ELSE statementsELSE ] END IF;
Condition evaluated as NULL is considered as not met
IF condition statementIF | blockIF
[ELSE statementELSE | blockELSE]
Condition evaluated as NULL is considered as not met
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 42
WHILE condition LOOP … [EXIT WHEN condition] … END LOOP;
While-loop with optional exit in the middle
WHILE condition statementWHILE | blockWHILE
BREAK exits the loop CONTINUE exits the
iteration
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 43
LOOP … [EXIT WHEN condition] … END LOOP;
General loop with exit in the middle
The exit can be written also in form IF condition THEN exit; END IF;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 44
FOR I IN 1..10 LOOP … [EXIT WHEN condition] … END LOOP;
FOR I IN REVERSE 10..1 LOOP … END LOOP;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 45
GOTO label; … <<label>> statement;
The label must be followed by statement, at least by empty statement NULL;
GOTO label … label: …
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 46
Named blocks <<label>> DECLARE … BEGIN … END [label];
Named loops <<label>> LOOP … END LOOP [label];
Allow access to overloaded variables using qualification by block name
Allow exit from more loop levels at once: EXIT label WHEN …
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 47
SELECT expr [, …] INTO varname [, …] FROM … WHERE …;
Has to return exactly one row, otherwise exception
NO_DATA_FOUND
TOO_MANY_ROWS
DECLARE xEmpNo EMP.EmpNo%TYPE; xEName EMP.EName%TYPE; y Emp%ROWTYPE; BEGIN SELECT EmpNo, EName INTO xEmpNo, xEName FROM EMP WHERE EmpNo=1; SELECT * INTO y FROM EMP WHERE EmpNo=2; END;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 48
SELECT @varname=expr [, …] FROM … WHERE …;
Has to return exactly one row, otherwise exception
DECLARE @xEmpNo INT, @xEName VARCHAR(30) SELECT @xEmpNo = EmpNo, @xEName = EName FROM EMP WHERE EmpNo=1
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 49
Multi-row SELECT statements without INTO can be processed only using cursors
Cursors have attributes, accessible by syntax cursorname%attrname IsOpen BOOLEAN
Found BOOLEAN NotFound BOOLEAN
RowCount NUMBER
DECLARE CURSOR C IS SELECT * FROM EMP; R C%RowType; BEGIN OPEN C; LOOP FETCH C INTO R; EXIT WHEN NOT C%Found; … END LOOP; CLOSE C; END;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 50
Multi-row SELECT statements can be processed only using cursors
After each FETCH the @@FETCH_STATUS should be checked 0 … row was successfully
fetched
-1 … fetch after the end of cursor
-2 … row is missing
DECLARE C CURSOR FOR SELECT * FROM EMP; OPEN C; FETCH NEXT FROM C INTO @x, …; WHILE @@FETCH_STATUS=0 BEGIN … FETCH NEXT FROM C INTO @x, …; END; CLOSE C; DEALLOCATE C;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 51
More simple cursor processiong using cursor FOR loops
DECLARE CURSOR C IS SELECT * FROM EMP; R C%RowType; BEGIN FOR R IN C LOOP … END LOOP; END;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 52
Automatically declared variable visible only inside the loop
This variable is not used
The SELECT can be used directly in FOR – LOOP declaration
BEGIN FOR R IN ( SELECT * FROM EMP
) LOOP … END LOOP; END;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 53
Declaration CURSOR C(J VARCHAR2, D NUMBER) IS
SELECT * FROM EMP WHERE Job=J AND DeptNo=D;
Usage OPEN C(’Manager’,10); … CLOSE C;
FOR R IN C(’Manager’,10) LOOP … END LOOP;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 54
Declaration C [SCROLL] CURSOR FOR
SELECT …; Data fetching FETCH
{NEXT | PRIOR | ABSOLUTE n | RELATIVE n | LAST | FIRST} FROM C [INTO @varname [, …]]
IF the cursor is not declared with SCROLL keyword (recommended when not necessary), only NEXT modifier is allowed
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 55
Allows handle exceptional states after SQL statement execution
Exception are very common They have to be handled properly
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 56
Exception types Intended to be handled on the server or in the client
application ▪ Standard named exceptions
▪ Are generated by the server, have assigned a name
▪ Standard unnamed exceptions ▪ Are generated by the server, have not assigned any name
Intended to be handled on the server ▪ User defined internal exceptions
▪ Defined by the user, have name, have no description
Intended to be handled in the client application ▪ User defined application exceptions
▪ Defined by the user, have no name, have description
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 57
Basic exceptions NO_DATA_FOUND TOO_MANY_ROWS DUP_VAL_ON_INDEX INVALID_NUMBER ZERO_DIVIDE
Catching EXCEPTION
WHEN name1 [OR name2 …] THEN statements; [WHEN name3 [OR …] THEN statements;] [WHEN OTHERS THEN statements;]
Block don’t catches exceptions, thrown in the DECLARE section
DECLARE x NUMBER := 0; y NUMBER := 1/x; /* ZERO_DIVIDE !! */
Such exceptions can be handled at leas one level higher
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 58
Catches any not previously handled exception
Can be named by the user and handled as usual DECLARE
X EXCEPTION; PRAGMA EXCEPTION_INIT(X,-54) /* ORA-00054 ~ Resource locked */
Catching EXCEPTION WHEN X THEN …; EXCEPTION WHEN OTHERS THEN …;
Any handled exception can be re-thrown, if it should be handled again in higher levels or in the client application EXCEPTION … WHEN … THEN … RAISE;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 59
BEGIN TRY statements END TRY BEGIN CATCH statement END CATCH
Functions for exception identification ERROR_NUMBER()
ERROR_SEVERITY()
ERROR_STATE()
ERROR_PROCEDURE()
ERROR_LINE()
ERROR_MESSAGE()
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 60
BEGIN TRY statements END TRY BEGIN CATCH statements END CATCH
Not detected are
Warnings with ERROR_SEVERITY<=10
Severe errors with ERROR_SEVERITY>20
that stops the session execution
In higher levels are caught
Compilation errors
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 61
BEGIN TRY SELECT 1/0; -- zero divide … END TRY BEGIN CATCH SELECT @ErrorNumber = ERROR_NUMBER(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(), @ErrorProcedure = ERROR_PROCEDURE(), @ErrorLine = ERROR_LINE(), @ErrorMessage = ERROR_MESSAGE(); … END CATCH; GO
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 62
Declaration DECLARE
X EXCEPTION; …
Throwing RAISE X;
Catching EXCEPTION
[WHEN X THEN …;] WHEN OTHERS …;
Problem with overloading <<Outer>>
DECLARE X EXCEPTION; BEGIN <<Inner>> DECLARE X EXCEPTION; BEGIN RAISE X; END Inner; EXCEPTION WHEN X THEN …; END Outer;
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 63
Other – Outer.X not handles Inner.X
Inner.X not caught, is propagated outside
Throwing
RAISE_APPLICATION_ERROR( -20001, -- exception number <-20100;-20001> ’Description’, -- text that describes the exception cause );
If the third parameter FALSE is added, the exception is only put to the exception stack, but is not thrown. It allows return more exceptions at once, where the lower one is a cause of the upper one
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 64
CREATE PROCEDURE InsEmp ( xEmpNo NUMBER, xEName VARCHAR2, xSal NUMBER DEFAULT NULL) AS xS NUMBER; BEGIN xS := xSal; IF xS IS NULL THEN SELECT MIN(Sal) INTO xS FROM EMP; END IF; INSERT INTO Emp(EmpNo,EName,Sal) VALUES(xEmpNo,xEName,xS); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN RAISE_APPLICATION_ERROR( -20011, ’Employee ’||xEmpNo||’ already exists!’ ); END; /
EXEC InsEmp(1234,’Smith’);
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 65
Throwing RAISERROR({
msg_id -- exception number, >= 50000 | msg_str -- message text | @msg_var -- message text in variable }, severity, state, argument [, …])
Individual messages can be prepared by sp_addmessage procedure and then referenced only by msg_id
msg_str can contain references to parameters, similarly to C-function printf, and the values can be defined in arguments
Severity is the severity of the exception. Severity 19-25 can be thrown only by member of sysadmin group/role.
M. Kopecký Views and Procedural Extension (NDBI026, Lect. 3) 66