I am using DB2 IBM data studio, and I cannot print logs:
create procedure test_ticket
begin
declare stmt varchar(500);
DECLARE QTY INTEGER;
SET QTY = (select count(*) from test.ticket);
CALL DBMS_OUTPUT.PUT_LINE( QTY );
end
No authorized routine named "DBMS_OUTPUT.PUT_LINE" of type "PROCEDURE"
having compatible arguments was found.. SQLCODE=-440, SQLSTATE=42884,
DRIVER=4.18.60
As #mustaccio surmised, the DBMS_OUTPUT module was not present in DB2 9.5. It was introduced as part of the Oracle compatibility features in DB2 9.7.
You may also want to note that DBMS_OUTPUT.PUT_LINE takes an argument of VARCHAR, not INT.
Related
Creating a procedure including an unnamed parameter will not result in the PG_PROC_INFO.proargnames for that containing an empty string for that parameter.
This does not comply with the description of the proargnames column the in PostgreSQL documentation
https://www.postgresql.org/docs/8.0/catalog-pg-proc.html.
Anyone know if this is intentional or not?
Example
Defining procedure using the following parameters
CREATE PROCEDURE testunnamed (IN INTEGER, IN p2 INTEGER)
gives the following value for proargnames.
PostgreSQL: {"","p2"}
Redshift: {"p2"}
For redshift the same value is in both the View PG_PROC_INFO as well as the Table PG_PROC.
The information Is needed to generate the "(IN INTEGER, IN p2 INTEGER)" from data in PG_PROC_INFO. In postgreSQL there is a function pg_get_function_arguments that is not available in redshift.
CAUSE - Driver issue
As I did begin to suspect this being a driver issue (Running with RedshiftJDBC 01.02.27.1051 )
I did test by running a connection to Redshift using the PostgreSQL driver instead.
That seem to be spot on. I now get the expected output.
SELECT p.proname, p.pronargs, p.proargnames FROM pg_catalog.pg_proc_info p
WHERE p.proname LIKE 'testunnamed%' ;
Driver proname pronargs proargnames
------- ----------- -------- -----------
PostgresSQL testunnamed 2 {"","p2"}
Redshift testunnamed 2 {"p2"}
I'm not able to reproduce your results. Can you provide the queries you used to get {"p2"}?
SELECT version();
-- … Redshift 1.0.7804
CREATE PROCEDURE testunnamed (IN INTEGER, IN p2 INTEGER) language plpgsql as $$ begin null; end; $$;
-- CREATE PROCEDURE
SELECT proargnames FROM pg_proc_info WHERE proname = 'testunnamed';
-- proargnames
-- -------------
-- {"",p2}
SELECT proargnames FROM pg_proc WHERE proname = 'testunnamed';
-- proargnames
-- -------------
-- {"",p2}
The issue with the JDBC driver has been fixed in the latest version of the driver.
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
#
Does someone know how I can create that query below on DB2 database?
FUNCTION GPRS7001(
pe_sTexto VARCHAR2,
pe_sDelimitador VARCHAR2)
RETURN v_ttTabela PIPELINED;
I don't how I create PIPELINED table on DB2 database.
I tried to execute this:
CREATE OR REPLACE FUNCTION GPRS7001( pe_sTexto VARCHAR(300))
RETURNS TABLE( pe_sTexto VARCHAR(300)
,pe_sDelimitador VARCHAR(300)
)
LANGUAGE SQL
RETURNS -- WTF ;
Db2 version 10.5
If you properly configure your Db2 database for Oracle-emulation, then Db2 may run a pipelined function without changes.
Refer to the documentation on V10.5 Knowledge Center for details of PL/SQL support, PL/SQL pipelined functions, and the PIPE statement.
I have a stored procedure that performs inserts and updates in the tables. The need to create it was to try to centralize all the scan functions before inserting or updating records. Today the need arose to return the value of the field ID of the table so that my application can locate the registry and perform other stored procedures.
Stored procedure
SET TERM ^ ;
CREATE OR ALTER procedure sp_insupd (
iaction varchar(3),
iusuario varchar(20),
iip varchar(15),
imodulo varchar(30),
ifieldsvalues varchar(2000),
iwhere varchar(1000),
idesclogs varchar(200))
returns (
oid integer)
as
declare variable vdesc varchar(10000);
begin
if (iaction = 'ins') then
begin
vdesc = idesclogs;
/*** the error is on the line below ***/
execute statement 'insert into '||:imodulo||' '||:ifieldsvalues||' returning ID into '||:oid||';';
end else
if (iaction = 'upd') then
begin
execute statement 'select '||:idesclogs||' from '||:imodulo||' where '||:iwhere into :vdesc;
execute statement 'execute procedure SP_CREATE_AUDIT('''||:imodulo||''');';
execute statement 'update '||:imodulo||' set '||:ifieldsvalues||' where '||:iwhere||';';
end
insert into LOGS(USUARIO, IP, MODULO, TIPO, DESCRICAO) values (
:iusuario, :iip, :imodulo, (case :iaction when 'ins' then 1 when 'upd' then 2 end), :vdesc);
end^
SET TERM ; ^
The error in the above line is occurring due to syntax error. The procedure is compiled normally, that is, the error does not happen in the compilation, since the line in question is executed through the "execute statement". When there was no need to return the value of the ID field, the procedure worked normally with the line like this:
...
execute statement 'insert into '||:imodulo||' '||:ifieldsvalues||';';
...
What would be the correct way for the value of the ID field to be stored in the OID variable?
What is REAL VALUE in ifieldsvalues ?
you can not have BOTH
'insert into '||:imodulo||' '||:ifieldsvalues
'update '||:imodulo||' set '||:ifieldsvalues
because methods to specify column names and column values in INSERT and UPDATE statements is fundamentally different!!! You either would have broken update-stmt or broken insert-stmt!
The error in the above line is occurring due to syntax error
This is not enough. Show the real error text, all of it.
It includes the actual command you generate and it seems you had generated it really wrong way.
all the scan functions before inserting or updating records
Move those functions out of the SQL server and into your application server.
Then you would not have to make insert/update in that "strings splicing" way, which is VERY fragile and "SQL injection" friendly. You stepped into the road to hell here.
the error does not happen in the compilation
Exactly. And that is only for starters. You are removing all the safety checks that should had helped you in applications development.
http://searchsoftwarequality.techtarget.com/definition/3-tier-application
https://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture
http://bobby-tables.com
On modern Firebird versions EXECUTE STATEMENT command can have the same INTO clause as PSQL SELECT command.
https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-psql-coding.html#fblangref25-psql-execstmt
Use http://translate.ru to read http://www.firebirdsql.su/doku.php?id=execute_statement
Or just see SQL examples there. Notice, however, those examples all use SELECT dynamic command, not INSERT. So I am not sure it would work that way.
This works in Firebird 2.5 (but not in Firebird 2.1) PSQL blocks.
execute statement 'insert into Z(payload) values(2) returning id' into :i;
To run it from IBExpert/FlameRobin/iSQL interactive shell add that obvious boilerplate:
execute block returns (i integer) as
begin
execute statement 'insert into Z(payload) values(2) returning id' into :i;
suspend;
end
HOW to resolve this problem ? :
CREATE OR REPLACE FUNCTION "BADIL_PROD"."FCT_UPDATE_POINTAGE" (id_projet in NUMBER)
return NUMBER
is
Results NUMBER;
CURSOR cur_update IS
SELECT distinct t.ID_TACHE,t.id_collaborateur,t.id_ref_rubrique_activite
FROM TACHES t
where t.ID_PROJET =id_projet ;
begin
dbms_output.enable(200000);
FOR cur in cur_update
LOOP
BEGIN
dbms_output.put_line(cur.ID_TACHE || '--' || cur.ID_COLLABORATEUR || '--' || cur.ID_REF_RUBRIQUE_ACTIVITE);
UPDATE POINTAGES p SET p.ID_TACHE_INCIDENT = cur.ID_TACHE
where p.id_projet_tma=id_projet
and p.ID_COLLABORATEUR = cur.ID_COLLABORATEUR
AND p.ID_REF_RUBRIQUE_ACTIVITE = cur.ID_REF_RUBRIQUE_ACTIVITE;
END;
END LOOP;
results:=0;
return(results);
end fct_update_pointage;
So when I want to test this function I get this error in data studio :
(specific name "FCT_UPDATE_POINTAGE") attempted to modify data but was
not defined as MODIFIES SQL DATA.. SQLCODE=-577,
This worked for me with DB2 V11 on Linux:
db2set DB2_COMPATIBILITY_VECTOR=830
db2stop
db2start
db2 create database mydb
db2 connect to mydb
db2 "create table taches(....)"
db2 "create table pointages(...)"
db2 -tvf FCT_UPDATE_POINTAGE.sql
(where FCT_UPDATE_POINTAGE.sql contains your function definition )
However, note the documented restriction in the documentation "Compiled SQL functions (including PL/SQL functions) that MODIFY SQL DATA can only be used as the only element on the right side of an assignment statement that is within a compound SQL (compiled) statement."
DB2 Version 9.7 allowed the "modifies sql data" clause when defining PL/SQL user defined functions, but IBM removed that ability at DB2 Version 10.1 and higher. Maybe you need to convert to an sproc.