PL/SQL

Last updated

PL/SQL (Procedural Language for SQL) is Oracle Corporation's procedural extension for SQL and the Oracle relational database. PL/SQL is available in Oracle Database (since version 6 - stored PL/SQL procedures/functions/packages/triggers since version 7), TimesTen in-memory database (since version 11.2.1), and IBM Db2 (since version 9.7). [1] Oracle Corporation usually extends PL/SQL functionality with each successive release of the Oracle Database.

Contents

PL/SQL includes procedural language elements such as conditions and loops, and can handle exceptions (run-time errors). It allows the declaration of constants and variables, procedures, functions, packages, types and variables of those types, and triggers. Arrays are supported involving the use of PL/SQL collections. Implementations from version 8 of Oracle Database onwards have included features associated with object-orientation. One can create PL/SQL units such as procedures, functions, packages, types, and triggers, which are stored in the database for reuse by applications that use any of the Oracle Database programmatic interfaces.

The first public version of the PL/SQL definition [2] was in 1995. It implements the ISO SQL/PSM standard. [3]

PL/SQL program unit

The main feature of SQL (non-procedural) is also its drawback: control statements (decision-making or iterative control) cannot be used if only SQL is to be used. PL/SQL provides the functionality of other procedural programming languages, such as decision making, iteration etc. A PL/SQL program unit is one of the following: PL/SQL anonymous block, procedure, function, package specification, package body, trigger, type specification, type body, library. Program units are the PL/SQL source code that is developed, compiled, and ultimately executed on the database. [4]

PL/SQL anonymous block

The basic unit of a PL/SQL source program is the block, which groups together related declarations and statements. A PL/SQL block is defined by the keywords DECLARE, BEGIN, EXCEPTION, and END. These keywords divide the block into a declarative part, an executable part, and an exception-handling part. The declaration section is optional and may be used to define and initialize constants and variables. If a variable is not initialized then it defaults to NULL value. The optional exception-handling part is used to handle run-time errors. Only the executable part is required. A block can have a label. [5]

For example:

<<label>>-- this is optionalDECLARE-- this section is optionalnumber1NUMBER(2);number2number1%TYPE:=17;-- value defaulttext1VARCHAR2(12):='      Hello world       ';text2DATE:=SYSDATE;-- current date and timeBEGIN-- this section is mandatory, must contain at least one executable statementSELECTstreet_numberINTOnumber1FROMaddressWHEREname='INU';EXCEPTION-- this section is optionalWHENOTHERSTHENDBMS_OUTPUT.PUT_LINE('Error Code is '||TO_CHAR(sqlcode));DBMS_OUTPUT.PUT_LINE('Error Message is '||sqlerrm);END;

The symbol := functions as an assignment operator to store a value in a variable.

Blocks can be nested – i.e., because a block is an executable statement, it can appear in another block wherever an executable statement is allowed. A block can be submitted to an interactive tool (such as SQL*Plus) or embedded within an Oracle Precompiler or OCI program. The interactive tool or program runs the block once. The block is not stored in the database, and for that reason, it is called an anonymous block (even if it has a label).

Function

The purpose of a PL/SQL function is generally used to compute and return a single value. This returned value may be a single scalar value (such as a number, date or character string) or a single collection (such as a nested table or array). User-defined functions supplement the built-in functions provided by Oracle Corporation. [6]

The PL/SQL function has the form:

CREATEORREPLACEFUNCTION<function_name>[(input/outputvariabledeclarations)]RETURNreturn_type[AUTHID<CURRENT_USER|DEFINER>]<IS|AS>-- heading partamountnumber;-- declaration blockBEGIN-- executable part<PL/SQLblockwithreturnstatement>RETURN<return_value>;[Exceptionnone]RETURN<return_value>;END;

Pipe-lined table functions return collections [7] and take the form:

CREATEORREPLACEFUNCTION<function_name>[(input/outputvariabledeclarations)]RETURNreturn_type[AUTHID<CURRENT_USER|DEFINER>][<AGGREGATE|PIPELINED>]<IS|USING>[declarationblock]BEGIN<PL/SQLblockwithreturnstatement>PIPEROW<returntype>;RETURN;[Exceptionexceptionblock]PIPEROW<returntype>;RETURN;END;

A function should only use the default IN type of parameter. The only out value from the function should be the value it returns.

Procedure

Procedures resemble functions in that they are named program units that can be invoked repeatedly. The primary difference is that functions can be used in a SQL statement whereas procedures cannot. Another difference is that the procedure can return multiple values whereas a function should only return a single value. [8]

The procedure begins with a mandatory heading part to hold the procedure name and optionally the procedure parameter list. Next come the declarative, executable and exception-handling parts, as in the PL/SQL Anonymous Block. A simple procedure might look like this:

CREATEPROCEDUREcreate_email_address(-- Procedure heading part beginsname1VARCHAR2,name2VARCHAR2,companyVARCHAR2,emailOUTVARCHAR2)-- Procedure heading part endsAS-- Declarative part begins (optional)error_messageVARCHAR2(30):='Email address is too long.';BEGIN-- Executable part begins (mandatory)email:=name1||'.'||name2||'@'||company;EXCEPTION-- Exception-handling part begins (optional)WHENVALUE_ERRORTHENDBMS_OUTPUT.PUT_LINE(error_message);ENDcreate_email_address;

The example above shows a standalone procedure - this type of procedure is created and stored in a database schema using the CREATE PROCEDURE statement. A procedure may also be created in a PL/SQL package - this is called a Package Procedure. A procedure created in a PL/SQL anonymous block is called a nested procedure. The standalone or package procedures, stored in the database, are referred to as "stored procedures".

Procedures can have three types of parameters: IN, OUT and IN OUT.

  1. An IN parameter is used as input only. An IN parameter is passed by reference, though it can be changed by the inactive program.
  2. An OUT parameter is initially NULL. The program assigns the parameter value and that value is returned to the calling program.
  3. An IN OUT parameter may or may not have an initial value. That initial value may or may not be modified by the called program. Any changes made to the parameter are returned to the calling program by default by copying but - with the NO-COPY hint - may be passed by reference.

PL/SQL also supports external procedures via the Oracle database's standard ext-proc process. [9]

Package

Packages are groups of conceptually linked functions, procedures, variables, PL/SQL table and record TYPE statements, constants, cursors, etc. The use of packages promotes re-use of code. Packages are composed of the package specification and an optional package body. The specification is the interface to the application; it declares the types, variables, constants, exceptions, cursors, and subprograms available. The body fully defines cursors and subprograms, and so implements the specification. Two advantages of packages are: [10]

  1. Modular approach, encapsulation/hiding of business logic, security, performance improvement, re-usability. They support object-oriented programming features like function overloading and encapsulation.
  2. Using package variables one can declare session level (scoped) variables since variables declared in the package specification have a session scope.

Trigger

A database trigger is like a stored procedure that Oracle Database invokes automatically whenever a specified event occurs. It is a named PL/SQL unit that is stored in the database and can be invoked repeatedly. Unlike a stored procedure, you can enable and disable a trigger, but you cannot explicitly invoke it. While a trigger is enabled, the database automatically invokes it—that is, the trigger fires—whenever its triggering event occurs. While a trigger is disabled, it does not fire.

You create a trigger with the CREATE TRIGGER statement. You specify the triggering event in terms of triggering statements, and the item they act on. The trigger is said to be created on or defined on the item—which is either a table, a view, a schema, or the database. You also specify the timing point, which determines whether the trigger fires before or after the triggering statement runs and whether it fires for each row that the triggering statement affects.

If the trigger is created on a table or view, then the triggering event is composed of DML statements, and the trigger is called a DML trigger. If the trigger is created on a schema or the database, then the triggering event is composed of either DDL or database operation statements, and the trigger is called a system trigger.

An INSTEAD OF trigger is either: A DML trigger created on a view or a system trigger defined on a CREATE statement. The database fires the INSTEAD OF trigger instead of running the triggering statement.

Purpose of triggers

Triggers can be written for the following purposes:

  • Generating some derived column values automatically
  • Enforcing referential integrity
  • Event logging and storing information on table access
  • Auditing
  • Synchronous replication of tables
  • Imposing security authorizations
  • Preventing invalid transactions

Data types

The major datatypes in PL/SQL include NUMBER, CHAR, VARCHAR2, DATE and TIMESTAMP.

Numeric variables

variable_namenumber([P,S]):=0;

To define a numeric variable, the programmer appends the variable type NUMBER to the name definition. To specify the (optional) precision (P) and the (optional) scale (S), one can further append these in round brackets, separated by a comma. ("Precision" in this context refers to the number of digits the variable can hold, and "scale" refers to the number of digits that can follow the decimal point.)

A selection of other data-types for numeric variables would include: binary_float, binary_double, dec, decimal, double precision, float, integer, int, numeric, real, small-int, binary_integer.

Character variables

variable_namevarchar2(20):='Text';-- e.g.: addressvarchar2(20):='lake view road';

To define a character variable, the programmer normally appends the variable type VARCHAR2 to the name definition. There follows in brackets the maximum number of characters the variable can store.

Other datatypes for character variables include: varchar, char, long, raw, long raw, nchar, nchar2, clob, blob, and bfile.

Date variables

variable_namedate:=to_date('01-01-2005 14:20:23','DD-MM-YYYY hh24:mi:ss');

Date variables can contain date and time. The time may be left out, but there is no way to define a variable that only contains the time. There is no DATETIME type. And there is a TIME type. But there is no TIMESTAMP type that can contain fine-grained timestamp up to millisecond or nanosecond. The TO_DATE function can be used to convert strings to date values. The function converts the first quoted string into a date, using as a definition the second quoted string, for example:

to_date('31-12-2004','dd-mm-yyyy')

or

to_date('31-Dec-2004','dd-mon-yyyy','NLS_DATE_LANGUAGE = American')

To convert the dates to strings one uses the function TO_CHAR (date_string, format_string).

PL/SQL also supports the use of ANSI date and interval literals. [11] The following clause gives an 18-month range:

WHEREdateFieldBETWEENDATE'2004-12-30'-INTERVAL'1-6'YEARTOMONTHANDDATE'2004-12-30'

Exceptions

Exceptions—errors during code execution—are of two types: user-defined and predefined.

User-defined exceptions are always raised explicitly by the programmers, using the RAISE or RAISE_APPLICATION_ERROR commands, in any situation where they determine it is impossible for normal execution to continue. The RAISE command has the syntax:

RAISE<exceptionname>;

Oracle Corporation has predefined several exceptions like NO_DATA_FOUND, TOO_MANY_ROWS, etc. Each exception has an SQL error number and SQL error message associated with it. Programmers can access these by using the SQLCODE and SQLERRM functions.

Datatypes for specific columns

Variable_name Table_name.Column_name%type;

This syntax defines a variable of the type of the referenced column on the referenced tables.

Programmers specify user-defined datatypes with the syntax:

typedata_typeisrecord(field_1type_1:=xyz,field_2type_2:=xyz,...,field_ntype_n:=xyz);

For example:

declaretypet_addressisrecord(nameaddress.name%type,streetaddress.street%type,street_numberaddress.street_number%type,postcodeaddress.postcode%type);v_addresst_address;beginselectname,street,street_number,postcodeintov_addressfromaddresswhererownum=1;end;

This sample program defines its own datatype, called t_address, which contains the fields name, street, street_number and postcode.

So according to the example, we are able to copy the data from the database to the fields in the program.

Using this datatype the programmer has defined a variable called v_address and loaded it with data from the ADDRESS table.

Programmers can address individual attributes in such a structure by means of the dot-notation, thus:

v_address.street := 'High Street';

Conditional statements

The following code segment shows the IF-THEN-ELSIF-ELSE construct. The ELSIF and ELSE parts are optional so it is possible to create simpler IF-THEN or, IF-THEN-ELSE constructs.

IFx=1THENsequence_of_statements_1;ELSIFx=2THENsequence_of_statements_2;ELSIFx=3THENsequence_of_statements_3;ELSIFx=4THENsequence_of_statements_4;ELSIFx=5THENsequence_of_statements_5;ELSEsequence_of_statements_N;ENDIF;

The CASE statement simplifies some large IF-THEN-ELSIF-ELSE structures.

CASEWHENx=1THENsequence_of_statements_1;WHENx=2THENsequence_of_statements_2;WHENx=3THENsequence_of_statements_3;WHENx=4THENsequence_of_statements_4;WHENx=5THENsequence_of_statements_5;ELSEsequence_of_statements_N;ENDCASE;

CASE statement can be used with predefined selector:

CASExWHEN1THENsequence_of_statements_1;WHEN2THENsequence_of_statements_2;WHEN3THENsequence_of_statements_3;WHEN4THENsequence_of_statements_4;WHEN5THENsequence_of_statements_5;ELSEsequence_of_statements_N;ENDCASE;

Array handling

PL/SQL refers to arrays as "collections". The language offers three types of collections:

  1. Associative arrays (Index-by tables)
  2. Nested tables
  3. Varrays (variable-size arrays)

Programmers must specify an upper limit for varrays, but need not for index-by tables or for nested tables. The language includes several collection methods used to manipulate collection elements: for example FIRST, LAST, NEXT, PRIOR, EXTEND, TRIM, DELETE, etc. Index-by tables can be used to simulate associative arrays, as in this example of a memo function for Ackermann's function in PL/SQL.

Associative arrays (index-by tables)

With index-by tables, the array can be indexed by numbers or strings. It parallels a Java map, which comprises key-value pairs. There is only one dimension and it is unbounded.

Nested tables

With nested tables the programmer needs to understand what is nested. Here, a new type is created that may be composed of a number of components. That type can then be used to make a column in a table, and nested within that column are those components.

Varrays (variable-size arrays)

With Varrays you need to understand that the word "variable" in the phrase "variable-size arrays" doesn't apply to the size of the array in the way you might think that it would. The size the array is declared with is in fact fixed. The number of elements in the array is variable up to the declared size. Arguably then, variable-sized arrays aren't that variable in size.

Cursors

A cursor is a pointer to a private SQL area that stores information coming from a SELECT or data manipulation language (DML) statement (INSERT, UPDATE, DELETE, or MERGE). A cursor holds the rows (one or more) returned by a SQL statement. The set of rows the cursor holds is referred to as the active set. [12]

A cursor can be explicit or implicit. In a FOR loop, an explicit cursor shall be used if the query will be reused, otherwise an implicit cursor is preferred. If using a cursor inside a loop, use a FETCH is recommended when needing to bulk collect or when needing dynamic SQL.

Looping

As a procedural language by definition, PL/SQL provides several iteration constructs, including basic LOOP statements, WHILE loops, FOR loops, and Cursor FOR loops. Since Oracle 7.3 the REF CURSOR type was introduced to allow recordsets to be returned from stored procedures and functions. Oracle 9i introduced the predefined SYS_REFCURSOR type, meaning we no longer have to define our own REF CURSOR types.

LOOP statements

<<parent_loop>>LOOPstatements<<child_loop>>loopstatementsexitparent_loopwhen<condition>;-- Terminates both loopsexitwhen<condition>;-- Returns control to parent_loopendloopchild_loop;if<condition>thencontinue;-- continue to next iterationendif;exitwhen<condition>;ENDLOOPparent_loop;

[13]

Loops can be terminated by using the EXIT keyword, or by raising an exception.

FOR loops

DECLAREvarNUMBER;BEGIN/* N.B. for loop variables in PL/SQL are new declarations, with scope only inside the loop */FORvarIN0..10LOOPDBMS_OUTPUT.PUT_LINE(var);ENDLOOP;IFvarISNULLTHENDBMS_OUTPUT.PUT_LINE('var is null');ELSEDBMS_OUTPUT.PUT_LINE('var is not null');ENDIF;END;

Output:

 0  1  2  3  4  5  6  7  8  9  10  var is null

Cursor FOR loops

FORRecordIndexIN(SELECTperson_codeFROMpeople_table)LOOPDBMS_OUTPUT.PUT_LINE(RecordIndex.person_code);ENDLOOP;

Cursor-for loops automatically open a cursor, read in their data and close the cursor again.

As an alternative, the PL/SQL programmer can pre-define the cursor's SELECT-statement in advance to (for example) allow re-use or make the code more understandable (especially useful in the case of long or complex queries).

DECLARECURSORcursor_personISSELECTperson_codeFROMpeople_table;BEGINFORRecordIndexINcursor_personLOOPDBMS_OUTPUT.PUT_LINE(recordIndex.person_code);ENDLOOP;END;

The concept of the person_code within the FOR-loop gets expressed with dot-notation ("."):

RecordIndex.person_code

Dynamic SQL

While programmers can readily embed Data Manipulation Language (DML) statements directly into PL/SQL code using straightforward SQL statements, Data Definition Language (DDL) requires more complex "Dynamic SQL" statements in the PL/SQL code. However, DML statements underpin the majority of PL/SQL code in typical software applications.

In the case of PL/SQL dynamic SQL, early versions of the Oracle Database required the use of a complicated Oracle DBMS_SQL package library. More recent versions have however introduced a simpler "Native Dynamic SQL", along with an associated EXECUTE IMMEDIATE syntax.

Similar languages

PL/SQL works analogously to the embedded procedural languages associated with other relational databases. For example, Sybase ASE and Microsoft SQL Server have Transact-SQL, PostgreSQL has PL/pgSQL (which emulates PL/SQL to an extent), MariaDB includes a PL/SQL compatibility parser, [14] and IBM Db2 includes SQL Procedural Language, [15] which conforms to the ISO SQL’s SQL/PSM standard.

The designers of PL/SQL modeled its syntax on that of Ada. Both Ada and PL/SQL have Pascal as a common ancestor, and so PL/SQL also resembles Pascal in most aspects. However, the structure of a PL/SQL package does not resemble the basic Object Pascal program structure as implemented by a Borland Delphi or Free Pascal unit. Programmers can define public and private global data-types, constants, and static variables in a PL/SQL package. [16]

PL/SQL also allows for the definition of classes and instantiating these as objects in PL/SQL code. This resembles usage in object-oriented programming languages like Object Pascal, C++ and Java. PL/SQL refers to a class as an "Abstract Data Type" (ADT) or "User Defined Type" (UDT), and defines it as an Oracle SQL data-type as opposed to a PL/SQL user-defined type, allowing its use in both the Oracle SQL Engine and the Oracle PL/SQL engine. The constructor and methods of an Abstract Data Type are written in PL/SQL. The resulting Abstract Data Type can operate as an object class in PL/SQL. Such objects can also persist as column values in Oracle database tables.

PL/SQL is fundamentally distinct from Transact-SQL, despite superficial similarities. Porting code from one to the other usually involves non-trivial work, not only due to the differences in the feature sets of the two languages, [17] but also due to the very significant differences in the way Oracle and SQL Server deal with concurrency and locking.

The StepSqlite product is a PL/SQL compiler for the popular small database SQLite which supports a subset of PL/SQL syntax. Oracle's Berkeley DB 11g R2 release added support for SQL based on the popular SQLite API by including a version of SQLite in Berkeley DB. [18] Consequently, StepSqlite can also be used as a third-party tool to run PL/SQL code on Berkeley DB. [19]

See also

Related Research Articles

PL/I is a procedural, imperative computer programming language initially developed by IBM. It is designed for scientific, engineering, business and system programming. It has been in continuous use by academic, commercial and industrial organizations since it was introduced in the 1960s.

<span class="mw-page-title-main">PostgreSQL</span> Free and open-source object relational database management system

PostgreSQL, also known as Postgres, is a free and open-source relational database management system (RDBMS) emphasizing extensibility and SQL compliance. PostgreSQL features transactions with atomicity, consistency, isolation, durability (ACID) properties, automatically updatable views, materialized views, triggers, foreign keys, and stored procedures. It is supported on all major operating systems, including Linux, FreeBSD, OpenBSD, macOS, and Windows, and handles a range of workloads from single machines to data warehouses or web services with many concurrent users.

In computer science, control flow is the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated. The emphasis on explicit control flow distinguishes an imperative programming language from a declarative programming language.

<span class="mw-page-title-main">Ingres (database)</span> Database software

Ingres Database is a proprietary SQL relational database management system intended to support large commercial and government applications.

A stored procedure is a subroutine available to applications that access a relational database management system (RDBMS). Such procedures are stored in the database data dictionary.

Transact-SQL (T-SQL) is Microsoft's and Sybase's proprietary extension to the SQL used to interact with relational databases. T-SQL expands on the SQL standard to include procedural programming, local variables, various support functions for string processing, date processing, mathematics, etc. and changes to the DELETE and UPDATE statements.

In computer programming, a directive or pragma is a language construct that specifies how a compiler should process its input. Depending on the programming language, directives may or may not be part of the grammar of the language and may vary from compiler to compiler. They can be processed by a preprocessor to specify compiler behavior, or function as a form of in-band parameterization.

A database trigger is procedural code that is automatically executed in response to certain events on a particular table or view in a database. The trigger is mostly used for maintaining the integrity of the information on the database. For example, when a new record is added to the employees table, new records should also be created in the tables of the taxes, vacations and salaries. Triggers can also be used to log historical data, for example to keep track of employees' previous salaries.

A user-defined function (UDF) is a function provided by the user of a program or environment, in a context where the usual assumption is that functions are built into the program or environment. UDFs are usually written for the requirement of its creator.

Harbour is a computer programming language, primarily used to create database/business programs. It is a modernised, open source and cross-platform version of the older Clipper system, which in turn developed from the dBase database market of the 1980s and 1990s.

In computer science, a database cursor is a mechanism that enables traversal over the records in a database. Cursors facilitate subsequent processing in conjunction with the traversal, such as retrieval, addition and removal of database records. The database cursor characteristic of traversal makes cursors akin to the programming language concept of iterator.

SQL Plus is the most basic Oracle Database utility, with a basic command-line interface, commonly used by users, administrators, and programmers.

In ADO.NET, a DataReader is a broad category of objects used to sequentially read data from a data source. DataReaders provide a very efficient way to access data, and can be thought of as a Firehose cursor from ASP Classic, except that no server-side cursor is used. A DataReader parses a Tabular Data Stream from Microsoft SQL Server, and other methods of retrieving data from other sources.

Database activity monitoring is a database security technology for monitoring and analyzing database activity. DAM may combine data from network-based monitoring and native audit information to provide a comprehensive picture of database activity. The data gathered by DAM is used to analyze and report on database activity, support breach investigations, and alert on anomalies. DAM is typically performed continuously and in real-time.

Java Database Connectivity (JDBC) is an application programming interface (API) for the Java programming language which defines how a client may access a database. It is a Java-based data access technology used for Java database connectivity. It is part of the Java Standard Edition platform, from Oracle Corporation. It provides methods to query and update data in a database, and is oriented toward relational databases. A JDBC-to-ODBC bridge enables connections to any ODBC-accessible data source in the Java virtual machine (JVM) host environment.

In computer programming, a function, procedure, method, subroutine, routine, or subprogram is a callable unit of software logic that has a well-defined interface and behavior and can be invoked multiple times.

In database management systems (DBMS), a prepared statement, parameterized statement, or parameterized query is a feature where the database pre-compiles SQL code and stores the results, separating it from data. Benefits of prepared statements are:

<span class="mw-page-title-main">Snake case</span> Words joined with underscores

Snake case is the naming convention in which each space is replaced with an underscore (_) character, and words are written in lowercase. It is a commonly used naming convention in computing, for example for variable and subroutine names, and for filenames. One study has found that readers can recognize snake case values more quickly than camel case. However, "subjects were trained mainly in the underscore style", so the possibility of bias cannot be eliminated.

Object-PL/SQL is a methodology of using the Oracle Corporation's procedural extension language for SQL and the Oracle relational database. The additional features from version 7 and other improvements, lead to one of the large-scale environment implementations of the object-oriented database paradigm.

References

  1. Serge Rielau (srielau@ca.ibm.com), SQL Architect, STSM, IBM. "DB2 10: Run Oracle applications on DB2 10 for Linux, UNIX, and Windows". Ibm.com. Retrieved 2012-07-26.{{cite web}}: CS1 maint: multiple names: authors list (link)
  2. Steven Feuerstein (1995), "Oracle PL/SQL Programming", 1st, First Edition.
  3. "Oracle Compliance with SQL/PSM".
  4. "Oracle Server Features". Oracle. Retrieved 2020-09-21.
  5. "PL/SQL Anonymous Blocks". Oracle. Retrieved 2020-09-21.
  6. "Database SQL Reference". Oracle. Retrieved 2020-09-21.
  7. Nanda, Arup; Feuerstein, Steven (2005). Oracle PL/SQL for DBAs. O'Reilly Series. O'Reilly Media, Inc. pp. 122, 429. ISBN   978-0-596-00587-0 . Retrieved 2011-01-11. A pipelined table function [...] returns a result set as a collection [...] iteratively. [... A]s each row is ready to be assigned to the collection, it is 'piped out' of the function.
  8. "Database SQL Reference". Oracle. Retrieved 2020-09-21.
  9. Gupta, Saurabh K. (2012). "5: Using Advanced Interface Methods". Advanced Oracle PL/SQL Developer's Guide. Professional experience distilled (2 ed.). Birmingham: Packt Publishing Ltd (published 2016). p. 143. ISBN   9781785282522 . Retrieved 2017-06-08. Whenever the PL/SQL runtime engine encounters an external procedure call, the Oracle Database starts the extproc process. The database passes on the information received from the call specification to the extproc process, which helps it to locate the external procedure within the library and execute it using the supplied parameters. The extproc process loads the dynamic linked library, executes the external procedure, and returns the result back to the database.
  10. "Coding PL/SQL Procedures and Packages". Oracle. Retrieved 2020-09-21.
  11. "Literals". Oracle iSQL Reference 10g Release 2 (10.2). Oracle. Retrieved 2009-03-20.
  12. Feuerstein, Steven. "Working with Cursors". oracle.com.
  13. "Database PL/SQL User's Guide and Reference". download.oracle.com.
  14. "What's New in MariaDB Server 10.3" (PDF). MariaDB. Retrieved 2018-08-21.
  15. "SQL PL". Publib.boulder.ibm.com. Retrieved 2012-07-26.
  16. Oracle documentation "Private and public items in PL/SQL"
  17. "Migrating from Oracle to SQL Server - T-SQL, PL/SQL differences: Narayana Vyas Kondreddi's home page". vyaskn.tripod.com.
  18. Burd, Gregory (March 24, 2010). "@humanications We didn't re-implement the SQLite API, we include a version of SQLite which uses Berkeley DB for storage (replacing btree.c)".
  19. "Official Berkeley DB FAQ". Oracle Corporation . Retrieved March 30, 2010. Does Berkeley DB support PL/SQL?

Further reading