In class we were asked to name several PL/SQL functions and state their use. Someone mentioned CREATE FUNCTION and I noted that Oracle labeled this as a statement and not a function.
I am unable to give a very good answer on the difference between the two. I am thinking that a statement is more of a declarative tool that specifies what the program is to accomplish whereas a function seems more procedural, we define the procedure for a new function in the CREATE FUNCTION statement.
The distinction seems clearer for something like a SELECT statement, can someone help with a clear delimitation between the two?
A statement is a piece of code that executes. It is a command. It does something. Example:
print "Hello World"
A function is a block of code that you call with parameters and it returns a value (even if that value is undefined). Example:
function(a) { return a * 2 }
The word "statement" has two different meanings in SQL and PL/SQL.
In a narrow technical sense, CREATE FUNCTION is a type of SQL statement, and CREATE FUNCTION contains PL/SQL statements.
In the more general sense, a SQL statement is declarative code that tells the database "what is true" or "what has to be done", without detailed instructions on "how to do it". A function, or any PL/SQL block, is imperative code that tells the database exactly "what to do". Declarative SQL is usually simpler and faster than imperative PL/SQL so it's usually best to do most of the work in SQL and just glue it together with PL/SQL.
SQL has about 170 commands (as defined by V$SQLCOMMAND), organized into about 31 statement types, organized into the below 6 categories. The CREATE FUNCTION command is a CREATE statement type in the DDL category. That classification scheme is not 100% clear from the database and manuals, but I've used it to thoroughly classify all SQL statements.
Data Definition Language (DDL) Statements
Data Manipulation Language (DML) Statements
Transaction Control Statements
Session Control Statements
System Control Statement
Embedded SQL Statements
In PL/SQL, most blocks are a sequence of statements. These statements could be an assignment, loop, fetch, block, etc.
To make things more confusing, in 12c a SQL statement can contain PL/SQL statements:
with function f return number is begin return 1; end; select f from dual;
CREATE FUNCTION is a statement. The function itself is a FUNCTION. Running the statement that creates the function allows you to access the function.
In general, if you're creating anything in the database, you are using a statement (in particular, a data-definition language (DDL) statement). The item you create, be it a table, function, package, etc., can then be referenced in future statements.
Related
If we have only Out parameter in our PLSQL procedure.Then can we use function instead of procedure as function is also able to return the value.
And if we still using procedure then we use this instead of function.
I hope I am able to convey the right question which I want to ask?
Some important difference between both are as following:
Function:
It can be called from the SQL statement (SELECT, UPDATE, DELETE)
Can return only one value
DML operations are not allowed in it
Best for selecting the value for some common complex logic.
Procedure:
It cannot be called from the SQL statement. You must need the PL/SQL block to call it.
Can return multiple values (OUT parameters)
All DML operations are allowed within procedures.
Best for doing some complex logic and updating the table data accordingly.
It depends on what the procedure does.
For example, if it (along with returning some value) uses DML operations (e.g. inserts rows into some table), then function can't do that - you'll have to use a procedure.
Procedure's drawback is that you can't use it in a SELECT statement, such as
select proc_name(out_param) from dual;
You'll have to use a function in such cases.
Also, OUT parameter has to be stored somewhere, and that's usually a locally declared variable, but that means that you need another PL/SQL block to call the procedure and see its result.
If everything your current procedure does is to find & return some value, then yes - a function might be a better choice.
I know we can call the function from SQL if it doesn't contain out parameter or DML(except autonomous). But we can't call the procedure from SQL in any condition.
What is the reason for it?
Why can't we call the procedure from SQL? Any specific reason.
The reason is that the SQL ANSII standard specifies that only functions can be used in the SQL query.
ISO committee members did not define the use of procedures in SQL queries.
You can:
call dbms_output.put_line('Hello')
CALL is part of the SQL language.
Or we can embed a procedure in an inline function:
with function f (p varchar2)
return varchar2
as
begin
dbms_output.put_line('Hello');
return p;
end f;
select f('Demo')
from dual
If you mean a SELECT statement specifically, I can't see how you expect that to work. What result set would you expect a query like this to return?
select dbms_output.put_line('Hello')
from dual
or
select dbms_stats.gather_table_stats(user, table_name)
from user_tables
This isn't an arbitrary restriction by some standards committee. It just doesn't make any sense semantically.
You can call or execute a procedure easily in SQL. Both parametrized or non can be called.
EXEC dbo.procedure_name
I'm assuming, that you are asking about calling procedures from within other SQL statements (not just call a procedure on its own, which is obviously possible).
Why? That's a matter of opinion, and you would have to ask Oracle DB architects for a real cause.
It would seem, that introducing procedure calls into all possible SQL statements, would bring both syntax and implementation complexity, while not necessarily bringing much more value. Usually there are alternatives, which are not much harder to use, while allowing the same outcome.
In case of a query (a SELECT statement), the result should be a data set, and no changes in the database state (data or structure) should be done. A PL/SQL procedure does not return a data set, and can change the database state.
If you are in a situation, where the procedure call is needed to prepare the data, you'd like to query, then you have the possibility to call the procedure first, and then query the database.
You can also write a procedure, which will have an output parameter of a cursor reference, which will effectively give you a query result. (For an ad hoc case, you could use parameterized anonymous PL/SQL block.)
You can also write a tabular function, where you can do complex data processing, using PL/SQL, and return a data set. Such function can be used in a query.
If you are asking also about other types of SQL statements, then you can always call DML (INSERT / UPDATE / DELETE / MERGE), DDL (CREATE / ALTER / DROP) or DCL (GRANT / REVOKE) from a procedure or an anonymous PL/SQ block, that does those and allows you to mix PL/SQL logic in. No need to do this the other way (introducing PL/SQL into DML / DDL / DCL).
Am very new in Database development so I have some doubts regarding my following example:
Function f1() - language sql
create or replace function f1(istr varchar)
returns text as $$
select 'hello! '::varchar || istr;
$$ language sql;
Function f2() - language plpgsql
create or replace function f2(istr varchar)
returns text as $$
begin select 'hello! '::varchar || istr; end;
$$ language plpgsql;
Both functions can be called like select f1('world') or select f2('world').
If I call select f1('world') the output will be:
`hello! world`
And output for select f2('world'):
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function f11(character varying) line 2 at SQL statement
********** Error **********
I wish to know the difference and in which situations I should use language sql or language plpgsql.
Any useful link or answers regarding functions will much appreciated.
SQL functions
... are the better choice:
For simple scalar queries. Not much to plan, better save any overhead.
For single (or very few) calls per session. Nothing to gain from plan caching via prepared statements that PL/pgSQL has to offer. See below.
If they are typically called in the context of bigger queries and are simple enough to be inlined.
For lack of experience with any procedural language like PL/pgSQL. Many know SQL well and that's about all you need for SQL functions. Few can say the same about PL/pgSQL. (Though it's rather simple.)
A bit shorter code. No block overhead.
PL/pgSQL functions
... are the better choice:
When you need any procedural elements or variables that are not available in SQL functions, obviously.
For any kind of dynamic SQL, where you build and EXECUTE statements dynamically. Special care is needed to avoid SQL injection. More details:
Postgres functions vs prepared queries
When you have computations that can be reused in several places and a CTE can't be stretched for the purpose. In an SQL function you don't have variables and would be forced to compute repeatedly or write to a table. This related answer on dba.SE has side-by-side code examples for solving the same problem using an SQL function / a plpgsql function / a query with CTEs:
How to pass a parameter into a function
Assignments are somewhat more expensive than in other procedural languages. Adapt a programming style that doesn't use more assignments than necessary.
When a function cannot be inlined and is called repeatedly. Unlike with SQL functions, query plans can be cached for all SQL statements inside a PL/pgSQL functions; they are treated like prepared statements, the plan is cached for repeated calls within the same session (if Postgres expects the cached (generic) plan to perform better than re-planning every time. That's the reason why PL/pgSQL functions are typically faster after the first couple of calls in such cases.
Here is a thread on pgsql-performance discussing some of these items:
Re: pl/pgsql functions outperforming sql ones?
When you need to trap errors.
For trigger functions.
When including DDL statements changing objects or altering system catalogs in any way relevant to subsequent commands - because all statements in SQL functions are parsed at once while PL/pgSQL functions plan and execute each statement sequentially (like a prepared statement). See:
Why can PL/pgSQL functions have side effect, while SQL functions can't?
Also consider:
PostgreSQL Stored Procedure Performance
To actually return from a PL/pgSQL function, you could write:
CREATE FUNCTION f2(istr varchar)
RETURNS text AS
$func$
BEGIN
RETURN 'hello! '; -- defaults to type text anyway
END
$func$ LANGUAGE plpgsql;
There are other ways:
Can I make a plpgsql function return an integer without using a variable?
The manual on "Returning From a Function"
PL/PgSQL is a PostgreSQL-specific procedural language based on SQL. It has loops, variables, error/exception handling, etc. Not all SQL is valid PL/PgSQL - as you discovered, for example, you can't use SELECT without INTO or RETURN QUERY. PL/PgSQL may also be used in DO blocks for one-shot procedures.
sql functions can only use pure SQL, but they're often more efficient and they're simpler to write because you don't need a BEGIN ... END; block, etc. SQL functions may be inlined, which is not true for PL/PgSQL.
People often use PL/PgSQL where plain SQL would be sufficient, because they're used to thinking procedurally. In most cases when you think you need PL/PgSQL you probably actually don't. Recursive CTEs, lateral queries, etc generally meet most needs.
For more info ... see the manual.
just make the select query you wrote inside the function as the returned value:
create or replace function f2(istr varchar)
returns text as $$
begin return(select 'hello! '::varchar || istr); end;
$$ language plpgsql;
Which approach is better to use if I need a member (sp or func) returning 2 parameters:
CREATE PROCEDURE Test
#in INT,
#outID INT OUT,
#amount DECIMAL OUT
AS
BEGIN
...
END
or
CREATE FUNCTION Test
(
#in INT
)
RETURNS #ret TABLE (outID INT, amount DECIMAL)
AS
BEGIN
...
END
What are pros and cons of each approach considering that the result will passed to another stored procedure:
EXEC Foobar #outID, #outAmount
A table valued function can only be used within a scope of a single SELECT statement. It cannot perform DML, catch exceptions etc.
On the other hand, it can return a set which can immediately be joined with another recordset in the same query.
If you use DML or don't need to use the output parameters in the set-based statements, use a stored proc; otherwise create a TVF.
A stored procedure that calls a function :-) I think either will suite you... if your app uses stored procedures for querying the database, then it may be best to be consistent... if you use an ORM, it may not recognize the function... I don't think you can go wrong with either.
In one of my apps, we preferred using the function approach, to throw in another perspective.
HTH.
With the stored procedure using output parameters you will only be able to return the two values: #outID and #amount.
With the table-valued function, you will be able to return a whole set of (outID, amount) tuples. In addition, a table-valued function can be used wherever table or view expressions are allowed in queries, such as:
SELECT dbo.Test(1) AS TestValues
I would argue The output parameter approach is most desirable. This makes it more self documenting that not more than one tuple is expected and I would assume is likely to be more efficient.
I would only use a table-valued function if I needed to obtain a table of values.
If there is only one "row" in your output then it would be preferable to use output parameters in a Stored Procedure.
One exception to this is if your SP/UDF can be written as a single SELECT statement - i.e. an Inline Function - because SQL Server can make better optimizations if you ever need to do something like join it to the output of another query. You may not be doing that now, but writing an inline UDF means you won't be caught off-guard with slow-as-molasses queries and timeout reports if somebody starts using it that way in the future.
If none of that applies to you then I would use a Stored Procedure for the reasons outlined; you don't want to create the illusion of set-based semantics when you aren't actually supporting them.
Output parameters.
Multi-statement table value functions are difficult to trace and tune. Stick with the stored procedure which is easier to troubleshoot.
Also, you are limited to what you can do in a udf. Say you need to add logging, or call an extended stored proc later... you can't use a udf for this.
I think your better bet would be the SP because with the TBF (table value function) you'd have to iterate through the table to get your value.
Bear in mind that if you iterate through the table in SQL, then you'll need to use a CURSOR (which aren't too bad, but can be a little tricky to use).
could you point me to a good place to start with Oracle stored procedures syntax/usage? I can't seem to find any good place there. I'm fairly proficient in (java, C/C++) programming and I do know enough SQL for my needs right now, but I've been suggested to use stored procedures to do my business, which is:
Take results from a query (2 columns) and insert them, row by row, in another table, along with an incrementing key whose value is taken from a third table. And of course this last value must be incremented once for every row.
I have the query to do the first part (extract data to be inserted) and the second part (insert data into table with incrementing key, then increment key on keygenerator table), all I need now is combine both so I can batch-insert the 6000 or so rows I have.
Thanks everyone.
Oracle uses PL/SQL programming language for their stored procedures. Here is an info about PL/SQL in wiki
This is a good source too.
Oracles provides a lot of tools to make the programmer's life easier, but my advice is to start as simple as you can to get familiar with the language..
and... Stored Procedures in PL/SQL
What you want looks pretty simple.This looks like a nice place to start.
http://www.devshed.com/c/a/Oracle/Oracle-Stored-Procedures/
As beginner, you can go through below link, it contains all basics related to procedure.
link
Regarding stored procedures, the basic syntax is:
-- The REPLACE keyword is optional. Without it the CREATE statement
-- will fail if there there is already a procedure with the same name
CREATE [OR REPLACE] PROCEDURE procedure_name AS|IS
-- Variable declarations
BEGIN
-- Stored procedure body
-- Optional exception block
[EXCEPTION]
-- Exception handlers
END [procedure_name];
/
-- The procedure_name after the END statement is optional, used
-- mostly for readability
The programing language is PL/SQL by default, but Oracle also allows you to write stored procedures in java. You can also call external C code (or any language that can generate C linkage object libraries) by creating external procedures that refer to shared libraries in the operating system.
PL/SQL resembles pascal and Delphi. It is based in the Ada language that is based in pascal. PL stands for "procedural language", but it also allows the object oriented programming paradigm.
For a more complete syntax reference, I'm particularly fond of the PSOUG (http://psoug.org) reference library for syntax and usage tips. Here are two links good for starters:
http://psoug.org/definition/procedure.htm
http://psoug.org/reference/procedures.html