+ All Categories
Home > Technology > Stored procedures in Firebird

Stored procedures in Firebird

Date post: 27-Jun-2015
Category:
Upload: mind-the-firebird
View: 1,662 times
Download: 5 times
Share this document with a friend
Description:
Firebird Stored Procedures, presentation by Lucas Franzen, at Firebird Conference 2012
Popular Tags:
35
1 Firebird Conference 2012 • Luxembourg • STORED PROCEDURES • Lucas Franzen About me Lucas 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
Transcript
Page 1: Stored procedures in Firebird

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

Page 2: Stored procedures in Firebird

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

Page 3: Stored procedures in Firebird

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

Page 4: Stored procedures in Firebird

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

Page 5: Stored procedures in Firebird

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.

Page 6: Stored procedures in Firebird

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

Inside the databaseStored procedures in the system tablesRDB$PROCEDURES

RDB$PROCEDURE_PARAMETERS

Page 7: Stored procedures in Firebird

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

Page 8: Stored procedures in Firebird

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 ....

Page 9: Stored procedures in Firebird

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

Page 10: Stored procedures in Firebird

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

Page 11: Stored procedures in Firebird

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.

Page 12: Stored procedures in Firebird

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

Page 13: Stored procedures in Firebird

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

Page 14: Stored procedures in Firebird

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

Page 15: Stored procedures in Firebird

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

Page 16: Stored procedures in Firebird

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

Page 17: Stored procedures in Firebird

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

Page 18: Stored procedures in Firebird

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

Page 19: Stored procedures in Firebird

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

Page 20: Stored procedures in Firebird

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

Page 21: Stored procedures in Firebird

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

Example: Freight calculation

--> Example application

Freightcalculations Services

Countries ShippersLinktable

Page 22: Stored procedures in Firebird

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

Page 23: Stored procedures in Firebird

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

Page 24: Stored procedures in Firebird

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?

Page 25: Stored procedures in Firebird

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

Page 26: Stored procedures in Firebird

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!

Page 27: Stored procedures in Firebird

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

Page 28: Stored procedures in Firebird

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

Page 29: Stored procedures in Firebird

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

Page 30: Stored procedures in Firebird

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)

Page 31: Stored procedures in Firebird

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.

Page 32: Stored procedures in Firebird

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

Page 33: Stored procedures in Firebird

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.

Page 34: Stored procedures in Firebird

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

Page 35: Stored procedures in Firebird

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

The END

ANY QUESTIONS?ANY QUESTIONS?

Feel free to contact me:

[email protected]@frred.de


Recommended