I have a PostgreSQL function that takes one string as parameter/this is dynamic sql query/ and executes that dynamic SQL and I expect the result from the dynamic query.
It seems that in PostgreSQL I should predefine what I will return - but this is impossible since I am executing dynamic statement and sometimes I will return one int column, sometimes I will return 5 varchar columns....
Another thing is that existing jdbc code will call the function-and I cannot change it-I can't define the types dynamically like:
{call execute_dynamic(?) as (a varchar(255),b int)};
The code that will call the procedure is:
{call execute_dynamic(?)}
and cannot be changed....
Is there a way to implement this?
The solution is to use refcursor as return type.
OPEN ref_cursor FOR EXECUTE dynamic_sql;
return ref_cursor;
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'm writing a pretty basic stored procedure that just takes values from the sample DB2 database and computes the standard deviation. I wrote the procedure itself just fine, and I can call it without error. But I can't figure out how to actually display my result or select it in a statement. Everything I try results in a syntax error and I haven't been able to find anyone doing this specific task in my google searches.
This is the gist of my code (snipped for brevity):
CREATE PROCEDURE SAL_STD_DEV
(OUT std_dev real)
LANGUAGE SQL
BEGIN
--do stuff
SET std_dev = 10; --changed for simplicity
END#
CALL SAL_STD_DEV(?)#
All this runs, but just CALL doesn't create any output. What's the syntax to SELECT the out variable? I can't put a DECLARE before the CALL because it's not in a stored procedure, and PRINT doesn't work either.
(# is my terminal character because I'm using ; in the stored procedure)
Edit: Both the create procedure and call statements are made in the same SQL file, the database is connect to through localhost and I'm using DB2 11.1.0.1527 and developing in IBM Data Studio 4.1.2.
From wherever the CALL is being made, that feature might present a Result Set, despite apparently not presenting the result of an OUT parameter. If so, then the stored procedure perhaps could be revised to return the OUT value [instead, or additionally] as a result set, so that the interface that accepts the CALL statement as input, might present that result-set. Regardless:
In a statement processor [e.g. that is not a GUI, but] for which SELECT query output is presented, the following scripted requests should likely suffice:
create variable my_real real
;
call SAL_STD_DEV(my_real)
;
select my_real from sysibm.sysdummy1
;
In a stored procedure, I've to build my own SQL request(because tables names and some properties names are known only at execution time(parameters)).
So Basically I've something like this
EXECUTE IMMEDIATE WITH RESULT SET OFF 'My custom query which select one data'
Usually, I would use the INTO commands, but my parameter is recognized inside the Execute immediate, which seems logic.
(Before you ask: I cannot return this in a result set, the result set is used for another data(and the result of this EXECUTE IMMEDIATE will determine which query I will run(and must be returned)).
How would you approach this problem? I guess it's the same problem on SQL Server-... but I didn't tested on it
You could create a table in compiled Sql and then the dynamic Sql populates it, so that the compiled sql statement after the dynamic part can read the results and update them onto your output params.
This question already has answers here:
What is the difference between function and procedure in PL/SQL?
(7 answers)
Closed 5 years ago.
I tried to looked in to difference between pl/sql procedure and function and found the link http://it.toolbox.com/blogs/oracle-guide/learn-plsql-procedures-and-functions-13030. First let me tell you what a developer generally do with pl/sql procedure and function
1) Wanted to get the some return value. He can acieve it with both function and procedure .With function if he want to return a single value he can use return statement . If he want to return multiple values he can achieve it with inout parameter.Similarily he can get return value with inout parameter from procedure(not with return statement)
But it does not make any difference to developer as long as he is able to achieve its intentention either with return statement or inout parameter.
so here also both can replace each other.
2) He can use DML in both Function and procedure. So here also he can use either of these to change the state of databse.
So i dont get any concrete reasoning which one to use where as both can replace each other in some.
The only reasonable reason i found up to some extent is that Functions can be called from SQL, procedure cannot
Could somebody explain which one to use when and why?
You already found the main difference. You create a function if you want to use it in SQL. You create a procedure, when you want to use it only in PL/SQL.
What I do. Use functions if there aren't side effects, procedures otherwise.
Moreover, only functions may be "pure"(suitable for function indexes) and "pipelined".
There are main two different:
1:Use Procedure to take some action. But use function to return some value.
2:You can call function from sql query but Procedure can't.
3:Best practice to use Procedure then function if possible.
Thanks.
A procedure and a function have the same structure, except that:
A function heading must include a RETURN clause that specifies the data type of the return value. A procedure heading cannot have a RETURN clause.
A function must have at least one RETURN statement in its executable part. In a procedure, the RETURN statement is optional. For details, see RETURN Statement.
For more information refer to:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/subprograms.htm#CHDDCFHD
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/subprograms.htm#i4079
Overview of PL/SQL Subprograms
A PL/SQL subprogram is a named PL/SQL block that can be invoked with a set of parameters. A subprogram can be either a procedure or a function. Typically, you use a procedure to perform an action and a function to compute and return a value.
Does anyone know of a way to append text to a stored procedure from within another stored procedure? I would like to do something like the following in SQL Server 2005:
Declare str as Nvarchar(Max) = ''
set #spStr = dbo.spTest + 'Where testCol1 = ''Test'''
exec(#spStr)
I understand this may open some discussion about SQL injection attacks. I'm simply looking to see if syntax exsists to extend a stored procedure by passing it a where clause dynamically in the above manner.
There is no syntax like this available in Sql Server any version. You've got a couple of options:
You could obviously modify the procedure to include a parameter that the procedure code itself would handle as a filter in the final statement(s) that returned the result set from the procedure call. Though I'd advise against it, you could certainly have a parameter that was just a varchar/nvarchar data type which included the actual 'where' clause you want to add and have the procedure code append it to these final select statement(s) as well
Use the insert/exec syntax to populate a temp table with the results of the stored procedure execution and then simply run a filtered select against that temp table.
There are some options.
You can alter the actual SP using the metadata in INFORMATION_SCHEMA.ROUTINES (not really what I think you are wanting to be doing)
You can parameterize the SP - this should not be vulnerable to injection if the SP uses the variable directly and not to dynamically make SQL.
You might consider using a view or an inline or multi-step table-valued function instead, which can be used like a parameterized view (inline being more efficient) - SELECT * FROM udf_Test WHERE TestCol1 = 'Test'.
You can take the results of the SP and put them in a temporary table or table variable and query against that.