How to do a sub procedure in sql / pl - db2

I am doing a procedure migration in pl / sql (oracle) to sql / pl (DB2) and I don't know how to pass a subprocedure to DB2
As I am not a system administrator I cannot change DB2 to be pl / sql compatible
EXAMPLE
create or replace PROCEDURE "SP_NOSTRADAMUS_PRODUTO"
AS
V_EXISTE_TAB NUMBER := 0;
PROCEDURE PR_HIRQ_PRODUTO_OR
AS
BEGIN
END

If your Db2-server runs on Linux/Unix/Windows, in ANSI SQL PL, if you have a local procedure nested within the body of another SQL PL procedure (or compound statement), then you use the DECLARE keyword to define the local procedure. This is supported by Db2-LUW in versions v10.1 and higher.
If you have very many Oracle PL SQL stored procedures, please discuss with your solution architect (if you have one) and your DBA about the possibility of configuring your Db2 server to support Oracle compatibility . This may save you some money.
You can see the Db2 syntax for SQL PL here (be sure to select the correct version of your Db2-server product in the pull down list).
There are some restrictions on local procedures, so study the documentation carefully. But your local procedure can access variables and objects defined in surrounding block(s) that are in scope.
Your example might look like this in ANSI SQL PL:
create or replace PROCEDURE "SP_NOSTRADAMUS_PRODUTO"
begin
declare V_EXISTE_TAB integer default 0;
declare PROCEDURE PR_HIRQ_PRODUTO_OR
BEGIN
-- body of pr_hirq_produto_or procedure
END;
-- body of sp_nostradamus_produto procedure
END
#

Db2 does not have subprocedures, not even sure why oracle would. In db2 you just create the 'sub' procedures as regular procedures and then 'CALL' them.
create procedure a( ....
create procedure b ....
create procedure main(...)
begin
call a(...);
call b(...);
end

Related

Stored procedure return value Db2

CREATE PROCEDURE A()
LANGUAGE SQL
RESULT SETS 1
BEGIN
DECLARE C1 CURSOR WITH RETURN FOR
SELECT id, name, dept, job FROM staff;
OPEN C1;
END
CREATE PROCEDURE B()
LANGUAGE SQL
BEGIN
Call a ;
END
In programming, they don't use stored procedure for returning value (they use function). Why does DB2 support that way?
In my above case, how does the stored procedure B know c1 cursor from stored procedure A? If I declare a cursor (c2 cursor) in stored procedure B and send to stored procedure A. Stored procedure A has a parameter (OUT c2 cursor), so why must I write 'RESULT SETS 1' (Can't I omit that phrase), because I don't return any cursor from stored procedure A (I return by parameter).
You might benefit from some education and training about SQL PL.
If you prefer a paper book, get "Db2 SQL Procedural Language for Linux, Unix, and Windows" by Paul Yip, Drew Bradstock and others. ISBN 0-13-100772-6.
Stackoverflow is not a substitute for training and education.
You should ask separate questions for different topics.
Research Db2 'table functions' to learn how to return a table from a function.
Research Db2 'strongly typed cursors', and Db2 'weakly typed cursors' and pipelined functions, to learn how to exploit cursor parameters in routines. Understand the many restrictions and rules associated with these things, which cannot be conveyed by one example in one question. In particular, realise that SQL PL cursor parameters can only be fully manipulated by SQL PL and cannot currently be passed to other languages for processing (except jdbc which has support for consuming such cursors). So if your front end client is using C, C++, Python, Javascript, .Net, PHP etc, then you won't use SQL PL cursor parameters currently. You might use them inside Db2 SQL PL code however, depending on your skills and needs.
To consume a result set from a nested stored procedure, you need extra syntax. When returning a result-set from a stored-procedure the dynamic result sets clause is required when defining the procedure. Returning a result set in this manner is understood by many different programming languages and frameworks, and by other RDBMS tools, so is the most general purpose method for returning data from an RDBMS to a 3rd Generation programming language. Other mechanisms can be built based on this technique.
All of this syntax is documented in the Db2 Knowledge Centre for your version and platform. One example cannot convey all possible syntax.
Here is an example, you will find many others online if you are competent with search.
--#SET TERMINATOR #
CREATE or replace PROCEDURE procA()
LANGUAGE SQL
RESULT SETS 1
BEGIN
DECLARE C1 CURSOR WITH RETURN TO CALLER FOR
SELECT id, name, dept, job FROM staff;
OPEN C1;
END
#
set serveroutput on#
CREATE or replace PROCEDURE B()
LANGUAGE SQL
BEGIN
declare sqlstate char(5) default '00000';
declare v_rs result_set_locator varying;
declare v_id smallint;
declare v_dept smallint;
declare v_name varchar(9);
declare v_job char(5);
Call procA() ;
associate result set locator (v_rs) with procedure procA;
allocate v_rscur cursor for result set v_rs;
fetch from v_rscur into v_id, v_name, v_dept, v_job;
while ( sqlstate = '00000') do
-- do something with the values just fetched...
-- i.e. process the data in the current row of the result-set
call dbms_output.put_line('id:'||varchar(v_id)||' name: '||v_name||' dept: '||varchar(v_dept)||' job: '||v_job);
-- in this example just write the data to the output stream
fetch from v_rscur into v_id, v_name, v_dept, v_job;
end while;
return;
END
#

How to use DO in postgres

I am attempting to get a better understanding of the DO command in postgreSQL 9.1
I have following code block,
DO
$do$
BEGIN
IF 1=1 THEN
SELECT 'foo';
ELSE
SELECT 'bar';
END IF;
END
$do$
However it returns the following error:
[42601] ERROR: query has no destination for result data Hint: If you want to discard the results of a SELECT, use PERFORM instead. Where: PL/pgSQL function "inline_code_block" line 4 at SQL statement
PostgreSQL DO command creates and executes some specific short life function. This function has not any interface, and then it cannot to return any output other then changes data in tables and some debug output.
Your example has more than one issues:
Only PostgreSQL table functions can returns some tabular data. But the mechanism is significantly different than MSSQL. PostgreSQL user's should to use RETURN NEXT or RETURN QUERY commands.
CREATE OR REPLACE FUNCTION foo(a int)
RETURNS TABLE(b int, c int) AS $$
BEGIN
RETURN QUERY SELECT i, i + 1 FROM generate_series(1,a) g(i);
END;
$$ LANGUAGE plpgsql;
SELECT * FROM foo(10);
DO anonymous functions are not table functions - so no output is allowed.
PostgreSQL 9.1 is not supported version, please upgrade
If you have some experience only from MSSQL, then forget it. A concept of stored procedures of PostgreSQL is very similar to Oracle or DB2, and it is significantly different to MSSQL does. T-SQL integrates procedural and SQL constructs to one set. Oracle, PostgreSQL, ... procedural functionality can embedded SQL, but procedural functionality is not integrated to SQL.
Please, read PostgreSQL PLpgSQL documentation for better imagine about this technology.

Temp table for user defined functions

I am trying to use temp table in user defined function for DB2. I am trying to do this in data studio but the code below is not working. How can I make this work?
Thanks.
CREATE FUNCTION BELSIZE.TEST (aSTRING VARCHAR(50))
RETURNS TABLE(
column1 INTEGER
)
F1: BEGIN ATOMIC
DECLARE c1 CURSOR WITH RETURN TO CLIENT FOR stmt;
SET v_dynStmt = 'SELECT 1 column1 from sysibm.sysdummy1';
PREPARE stmt FROM v_dynStmt;
OPEN c1;
RETURN
END
You have syntax errors in your code, more details below.
Apart from syntax errors, your title mentions temp table but your code does not, so your question is poor.
Never write "...is not working", instead write the exact SQLCODE and SQLSTATE and message that you see.
When asking for help with Db2, always write in the question the Db2-version and the operating-system (Z/OS, i-Series, Linux/Unix/Windows) on which the Db2-server runs, because the answer can depend on those facts. Different versions of Db2 for different operating systems have different capabilities and different syntax.
If you want to use cursors for result-sets then use SQL PL stored-procedures, because there are fewer restrictions.
SQL table functions are suitable when you don't need to declare a cursor for result-set.
Db2-LUW prevents you from declaring a cursor in an SQL table function when you use BEGIN ATOMIC.
If you are not using BEGIN ATOMIC, Db2-LUW (current versions, i.e. v11.1) lets you declare a cursor in an SQL UDF but you cannot use that cursor directly to return the result-set, as you can do inside SQL PL stored procedures.
For your example, the syntax below is valid and also useless, so consider using an SQL PL procedure instead:
--#SET TERMINATOR #
CREATE or replace FUNCTION BELSIZE.TEST (aSTRING VARCHAR(50))
RETURNS TABLE( column1 INTEGER)
language sql
specific belsize.test
BEGIN atomic
RETURN select 1 as column1 from sysibm.sysdummy1 ;
END
#
select * from table(belsize.test('a')) as t
#

call procedure which is inside a package in oracle 10g

how to call procedure which is inside a package in oracle 10g.
i have a two procedure called "area" which is of one parameter and other is also "area" but with 3 parameters. in short procedures are overloaded inside a package "shapearea".
create or replace package shapearea is
procedure area(l in number);
procedure area(l in number,b in number,h in number);
end;
create or replace package body shapearea is
procedure area (l in number) is
begin
dbms_output.put_line('Area of '||'l'||' lengh circle is'||l*l);
end;
procedure area (l in number,b in number,h in number) is
begin
dbms_output.put_line('Area of '||'l'||' lengh ractangle is'||l*b*h);
end;
end;
i tried
execute shapearea.area(5);
exec shapearea.area(5);
call shapearea.area(5);
shapearea.area(5);
but it did not work in oracle 10g.
If you are using SQL*Plus then try:
set serveroutput on
Begin
shapearea.area(5);
end;
/
If you are using SQL Developer you need to show the DBMS_Output window and enable it for the connection you are using.
DBMS_OUTPUT does not actually write to your display on its own. In reality it just buffers the output to some internal data structures, and then in the case of SQL*Plus, the SET SERVEROUTPUT ON enables client side routines to retrieve the output. In the case of SQL Developer showing the DBMS Output window and enabling it for the connection you are using enables it's client side display routines.
For other environments you may need to programatically read out the buffered results with the GET_LINE and/or GET_LINES DBMS_OUTPUT functions.

DB2 compound statement using ADO.NET

I want to execute multiple statements from my data access layer using C# dan IBM's DB2 data provider.
(environment: DB2/AS400 os version: V5R4)
eg in TSQL:
declare varA integer;
select varA= count(*) from tableA;
select * from tableB where col1 <= varA
with SQL server ; I can concatenate those 3 statements into a string
and assign the text to DBCommand.CommandText.
How to execute multiple statements(compound statement) against DB2 database via DBCommand (using IBM DB2 data provider)
I tried using begin and end block but still failed
BEGIN
statement1;
statement2;
statement3;
END
Thank you
I do not think it's possible.
I had already tried something similar some time ago, and the only solution I found is to dynamically create a stored procedure, calling it, and finally delete it.