stored procedures in firebird

Post on 27-Jun-2015

1.682 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

Firebird Stored Procedures, presentation by Lucas Franzen, at Firebird Conference 2012

TRANSCRIPT

1Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

About meLucas Franzen

Frred Software GmbH– Packing and shipping software– ERP add-on (SAP, Navision/Dynamics AX/ proAlpha, Baan, etc.)– All installations (~100) with Firebird (1.5)– Started with Interbase 4.0 in 1996– Firebird since the very beginning (Version 0.9)– Founding member oft the Firebird foundation

2Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

About this session● General Overview● How to write stored procedures● How to interact with stored procedures● Debugging / testing● Examples / example applications

3Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

What are STORED PROCEDURES?● Stored procedures are precompiled functions and queries, which are

stored in the database.● They offer a lot of SQL-enhancements in complexity and can speed up

data procession significantly.● In stored procedures there's the whole range of SQL-DML (Data

Manipulation Language) available.● General restrictments: ● No dynamic SQL statements available● No DDL (Data Definition Language) available.● Except using: EXECUTE STATEMENT

4Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Why using Stored Procedures?● Executed on the server● Increased speed ● Lower network traffic● PSQL offers more flexibility through SQL-enhancements● Batch processing within a single call / execution● Using as a Black-Box● Enhancement of permissions● Centralizing business-rules● Posting events● Executable from triggers

5Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Restrictions● Domains (available since FB2)● No DDL statements (Create / alter / drop) unless using

EXECUTE STATEMENT● No dynamic SQL-Statements● Example:

It's not possible to pass in the name of a table as a parameter and use this parameter for dynamic SQL within the stored procedure.

6Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Inside the databaseStored procedures in the system tablesRDB$PROCEDURES

RDB$PROCEDURE_PARAMETERS

7Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

PSQLProcedural Structured Query Language

• PSQL is Standard SQL plus some extensions, like

– declare variable – if .. then .. else ..– while ...– suspend– when ..– do .. begin .. end– for select .. do .. begin .. end– leave– exit – ...

• As it is used within triggers

8Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

PSQLIn procedures the all SQL features can be used

Not only SELECT, UPDATE, DELETE, ... are available

But alsoLIKE, CONTAINING, STARTING WITH, ...This is not restricted to queries within the procedure it's also perfectly valid to use these commands for variable comparisons.

IF ( VARIABLE LIKE '_N_' ) THEN ....IF ( VARIABLE STARTING 'Luc' ) THEN ....IF ( VARIABLE CONTAINING 'ire' ) THEN ....

9Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Writing a Stored ProcedureExample 1:

SET TERM #;CREATE PROCEDURE SP_SUM_UP ( VAL_1 INTEGER, VAL_2 INTEGER) RETURNS ( NEW_SUM INTEGER ) AS BEGIN NEW_SUM = VAL_1 + VAL_2;END #SET TERM ;#

Processing variables

Processing table values

(i.e. data)

Example 2:

SET TERM #; CREATE PROCEDURE SP_GET_COUNTRY_DATA (ID INTEGER )RETURNS ( ISO CHAR(2), CNAME VARCHAR(40), CARPLATE VARCHAR(3)) AS BEGIN SELECT CT_ISO, CT_NAME, CT_CAR FROM COUNTRY WHERE CT_ID = :ID INTO :ISO, :CNAME, :CARPLATE;END #SET TERM ;#

10Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

The COLON :• When does a variable need the colon as a prefix?

There's a lot of confusion about when to add the colon, when not.

• In general:A colon has to be used when the variable is used in a SQL-statement. (Otherwise SQL would try to use it as a fieldname).

... WHERE FIELD1 = :VAR1

UPDATE ... SETFIELD1 = :VAR1 ...

VAR1 = VAR2(Assigning values outside DML)

INSERT INTO .. VALUES (:VAR1, :VAR2)

IF ( VAR1 = SOMEVALUE ) THEN ...(Comparing values)

SELECT .. FROM .. INTO :VAR1, :VAR2

DON'T USE THE COLONUSE THE COLON

11Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

SET TERMSQL statements are terminated by a semicolon (;).In SPs there can be multiple SQL statements, each of these has to be terminated by the semicolon. But since the procedure itself is a SQL (DDL) statement to the database engine it has to be terminated as well. To get this working there's the SET TERM [new terminator] command.

SET TERM assigns a new terminating symbol to SQL, replacing the semicolon. After executing the SQL it has to be reset to the original value.Example:

SET TERM #; the new terminating symbol is now #CREATE PROCEDURE ... .... code here, including ; ....END # # = end of procedure codeSET TERM ;# resetting terminating symbol to the original ;

Note: Some tools might automatically do this job for you !!!When receiving the error message (-104: Unexpected end of command) the termination is missing.When receiving the error message (-104: Token unknown - line n, char 5. TERM) the terminators where already added by the tool.

12Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Executable or selectable?• Stored procedures can be invoked in two separate ways.

– EXECUTE PROCEDURE (<INPUT_PARAMS>)An executable procedure returns ONE set of its output params.

– SELECT <FIELD_LIST>FROM PROCEDURE<WHERE> <ORDER BY>

A selectable procedure returns 0..n sets of its output parameters as FIELDS. Such a procedure has to be queried like a TABLE.The resultset of a selectable procedure can be limited / sorted by WHERE / ORDER BY / GROUP BY clauses, though this slows down execution. But there are situations and complex queries where this can be very help- and powerful (i.e. ordering a resultset by a value that's calculated and returned by the SP itself).

13Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Executable or selectable?• Executable Procedure

• Selectable Procedure

Example 3:

CREATE PROCEDURE SP_SUM_UP ( VAL_1 INTEGER, VAL_2 INTEGER,) RETURNS ( NEW_SUM INTEGER ) AS BEGIN NEW_SUM = VAL_1 + VAL_2;END

Example 4:

CREATE PROCEDURE SEL_CUSTOMER_IN_CITY ( CITY_NAME VARCHAR(40) ) RETURNS ( CUST_NAME VARCHAR(40), CUST_NO VARCHAR(10)) AS BEGIN FOR SELECT CUST_NAME, CUST_NO FROM CUSTOMERS WHERE CUST_CITY = :CITY_NAME INTO :CUST_NAME, :CUST_NO DO BEGIN SUSPEND; ENDEND

14Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Writing and compiling pitfalls● Do ALWAYS initialize your variables!

Note: Since FB1.5 the variable can be initialized within the declaration!

DECLARE VARIABLE ABC VARCHAR(3) = 'ABC';

When a variable is used within a loop (FOR SELECT ... DO , WHILE ( ) DO ...) always re-initialize variables within this loop!

● Why is that?

If there's a select within a loop which doesn't return anything (keep in mind: nothing <> NULL) then the current variable values aren't touched at all...

So this might lead to interesting (but unwanted) results...

--> Example application

15Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Writing and compiling pitfalls● Most common errors caused in / from procedures:

– Arithmetic exception string truncation or overflow fill all the table fields to their maximum!( Example, next page)

– Multiple rows in singleton selectWill occur whenever a SELECT FROM .. INTO –will return more than one record and is not within a FOR..SELECT loop.Be sure to have selects like this using an UNIQUE INDEX (caution: NULL can be used within an unique index since FB1.5) or other means of limitation (MIN, FIRST 1)

--> Example application

16Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

The Black Box● Use procedures as a black box,

for example– Between different databases

– Within a database, when different teams are working at different tasks

– Complex tasks can be executed within the database and the result is published by a stored procedure

17Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

The Black Box● Example

Frred Package System

Scan delivery note

Search in FrredDatabase

ERP System Database

Request

18Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Permission and access control● Use procedures to give access to just some tables / fields

SET TERM #;CREATE PROCEDURE SEL_CUSTOMERS returns ( CUSTOMER_ID BigInt, CUSTOMER_NAME VarChar(40))ASBEGIN FOR SELECT CUST_ID, CUST_NAME FROM CUSTOMERS INTO :CUSTOMER_ID, :CUSTOMER_NAME DO BEGIN SUSPEND;ENDEND #SET TERM ;#

/* grant the execution of the procedure to PUBLIC */GRANT EXECUTE ON PROCEDURE SEL_CUSTOMERS TO PUBLIC;/* grant SELECT on the table CUSTOMERS to the procedure */GRANT SELECT ON CUSTOMERS TO PROCEDURE SEL_CUSTOMERS;

--> Example application

19Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Calling procedures within procedures

● Every procedure can invoke another procedure.Which way this is happening depends if it's an

executableorselectable procedure

● Calling an executable procedure– EXECUTE PROCEDURE <PROCNAME> [Params]

RETURNING VALUES [OUTPUT PARAMS]● Calling a selectabe procedure

– SELECT [Fieldlist] FROM <PROCNAME> INTO :Field1...:Fieldn

20Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Recursive procedures● Since procedures can call procedures a procedure can call itself, too● With this recursion you can build trees● Watch for maximum depth!

--> Example application

21Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Example: Freight calculation

--> Example application

Freightcalculations Services

Countries ShippersLinktable

22Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Example: Freight calculation● STEP 1

– Select all matching services for● The destination country● The shipper● Service type

SELECT * FROM SP_GET_SERVICES_AND_SHIPPERSSELECT * FROM SP_GET_SERVICES_AND_SHIPPERS

● STEP 2– If the shipper is not initialized / given:

● Get a list of all shippers which are linked to the destination country– Now get a list of every active service for the shipper

SELECT * FROM SP_GET_ACTIVE_SERVICESSELECT * FROM SP_GET_ACTIVE_SERVICES

23Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Example: Freight calculation● STEP 3

– Store all these informations in objects on the client side.

● STEP 4– Now iterate / loop through all these objects and call the calculation

procedure for every service

SELECT * FROM SP_CALCULATE_SERVICESELECT * FROM SP_CALCULATE_SERVICE

24Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Example: Freight calculation● INSIDE THE PROCEDURE

– Select the basic settings for this service– Check the general settings– Depending on the settings in the service just call the appropriate

procedure to calculate the freight● Calculation is based on zip-codes

– Procedure SEL_ZIPCODE_IDENT– Procedure SEL_ZIPCODE_LEFT– Procedure SEL_ZIPCODE_NORMALIZED

● Based on distances or city names– Select directly from CALCULATION TABLE

● Based on cities● Not based on zones at all?

25Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Example: Freight calculation● INSIDE THE PROCEDURE (continued)

– Is the service still valid so far?

– No? Exit and return error– Yes? CALCULATE!

Call the procedure SELECT * FROM SEL_FREIGHTCHARGESSELECT * FROM SEL_FREIGHTCHARGES● Within this procedure the kind of calculation will be examined and according

to that the reuslt will be calculated by– SP_CALC_DIRETLY– SP_CALC_BY_WEIGHT– SP_CALC_BY_DISTANCE

...– Calculate extra costs (Diesel surcharge)

--> Example application

26Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Execute statement● Remember:

No DDL-statements / dynamic SQL within procedures● Use EXECUTE STATEMENT to bypass these restrictions● EXECUTE STATEMENT is potentially unsafe:

– No possibilty to check the syntax.– No check of dependencies! – Operations are slow, since embedded statements have to be prepared

before every execution.– Datatypes of the return-values are strictly checked to avoid typecasting-

errors. For example the string „1234“ could usually be converted to the Integer 1234; The string „abc“ would cause an converting error.

– When the procedure has certain privileges on some objects, these will not be inherited to the execute statement! The privileges are restricted to the ones the user that's executing the procedure has got in general!

27Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Execute statement● Since FB1.5 there's Execute Statement, which offers the possibility

to use dynamic SQL and even DDL-Statements within procedures.

The syntax:– Executes <string> as SQL-Operation, not returnign anything-->

INSERT, UPDATE, DELETE, EXECUTE PROCEDURE or any DDL operation, BUT CREATE/DROP DATABASE.EXECUTE STATEMENT <string>;

– Executes <string> as SQL-Operation, returning a single record. Of course only singleton SELECT Operatoren qualify for this use of EXECUTE STATEMENT.EXECUTE STATEMENT <string> INTO :var1, […, :varn] ;

– Executes <string> as SQL-Operation, returning a any number of records. Every SELECT Operator can be used with this kind of EXECUTE STATEMENT FOR EXECUTE STATEMENT <string> INTO :var1, …, :varn DO <compound-statement>;

28Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Reporting● Stored procedures can be very useful for reporting● Remember:

Selectable procedure can be accessed like any table● For rather „unstructured“ formulas where master/detail areas are not

perfectly separated you can process the data in a stored procedure and return it in a form the report can handle

● Ordering / Grouping that's basing on complex calculations and data manipulation sometimes cannot be done with SQL.The stored procedure can return these calculated fields and you can order /group on that resultset

29Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Data transfer● Stored procedures are perfect for database-internal datatransfer.

– Transferring data from one/more table(s) to (an)other table(s)– Copying records

● If using this keep in mind:– If a table the procedure is based on is being altered the procedure might

be altered as well

30Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Testing stored procedures● Before taking a procedure into production test it thoroughly as well as

every program part that's using it.

● Most common errors by SPs:– Arithmetic exception string truncation or overflow

Fill all the table fields to their maximum!

– Multiple rows in singleton selectWill occur whenever a SELECT FROM .. INTO –will return more than one record and is not within a FOR..SELECT loop.Be sure to have selects like this using an UNIQUE INDEX (caution: NULL can be used within an unique index since FB1.5) or other means of limitation (MIN, FIRST 1)

31Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Debugging Stored Procedures● Use Tools

– IB Expert– Database Workbench– ...

● On your own:Catch an exceptionby using WHEN ANY – Use

INSERT STATEMENTS to store information fromwith the procedure in atable

– Use variables to identify wherethe problem occured

BEISPIEL:

SET TERM #;CREATE PROCEDURE SEL_PROCEDURE RETURNS ( FIELD_1 VARCHAR(40), ... ERROR_AT INTEGER)AS BEGIN ERROR_AT = 0; /* Step 1 */ ERROR_AT = 1; ... CODE ... /* Step 2 */ ERROR_AT = 2; ... CODE ... /* End of Code */ WHEN ANY DO BEGIN /* Return Variable ERROR_AT */ SUSPEND; ENDEND #SET TERM ;#

On exception the WHEN ANY will be executed: by looking at ERROR_AT variable you'll find out where it occured.

32Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Transactions● Stored Procedures always run in the context of the invoking

application!

● Stored Procedures can't use COMMIT or ROLLBACK within their body.

● So what's happening when there's an error with a procedureDo a Rollback or a Commit?

– WITHOUT EXCEPTION HANDLINGAll changes will be lost

– WITH EXCEPTION HANDLINGAll changes can be committed

33Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

Changing existing procedures● CAUTION

when changing procedures that are used by other procedures!

If such a SP is changed always keep the follwoing in mind:– When changing the input parameters:

Do change all other procedures which use it in advance. This can be done by dropping, altering to an empty body or just removing the calling reference.

– When changing the output parameters:do the same, when:

● the changed procedure is invoked as an executable procedure and the return parameters are defined by RETURNING_VALUES

● The changed procedure is invoked as a selectable procedure and SELECT * FROM ... INTO... is used.

● Thus you can be sure that the database is not in a (temporary?) state where Metadata are not cosistent.

34Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

HELP!● If a stored procedure cannot be altered or deleted any longer,

and even backup / restore / gfix is of no avail:– Kill the procedure-Source in the database!

UPDATE RDB$PROCEDURES SET RDB$PROCEDURE_BLR = NULLWHERE RDB$PROCEDURE_NAME = <PROCEDURE_NAME>

SYSTEM TABLE: RDB$PROCEDURES:

CREATE TABLE RDB$PROCEDURES ( RDB$PROCEDURE_NAME CHAR (31), RDB$PROCEDURE_ID SMALLINT, RDB$PROCEDURE_INPUTS SMALLINT, RDB$PROCEDURE_OUTPUTS SMALLINT, RDB$DESCRIPTION BLOB, RDB$PROCEDURE_SOURCE BLOB, RDB$PROCEDURE_BLR BLOB, RDB$SECURITY_CLASS CHAR (31), RDB$OWNER_NAME CHAR (31), RDB$RUNTIME BLOB, RDB$SYSTEM_FLAG SMALLINT);

35Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen

The END

ANY QUESTIONS?ANY QUESTIONS?

Feel free to contact me:

lucas.franzen@frred.deluc@frred.de

top related