Declare cursor is not executing - rpgle

I have converted one RPGLE program to SQLRPGLE, i did that many times. strange issues i am facing this time.
(1) SQLCODE setting up to 077952576 as soon as program executing, not sure why.
(2) when i am running in debug Declare cursor statement is not getting executed, nut other following sql statement getting hit.
Exec Sql
DECLARE My_cursor CURSOR for
select * FROM File1 where FLAG <> 'Y'
Order by Field1, Field2, Field3, Field4, Field5;
Please advise, Thanks

DECLARE CURSOR is not an executable statement. It's a compile time statement.
You shouldn't be checking SQLCODE/SQLSTATE after it...
Take a look at this program...
**FREE
ctl-opt main(mymain);
ctl-opt option(*srcstmt);
ctl-opt datfmt(*ISO) timfmt(*ISO);
ctl-opt cvtopt(*NODATETIME);
dcl-proc MyMain;
dcl-s company char(3);
dcl-s part char(25);
dcl-s desc char(30);
dcl-s msg char(50);
dcl-s selComp char(3);
dcl-s myTimestamp timestamp;
exec sql
set option
datfmt=*ISO, timfmt=*ISO;
selComp = 'A06';
exsr OpenCursor;
exsr FetchData;
exec SQL close C1;
selComp = 'A15';
exsr OpenCursor;
exsr FetchData;
exec SQL close C1;
*INLR = *ON;
return;
begsr DeclareCursor;
exec SQL
declare C1 cursor for
select pmco#, pmpart, pmdesc
from pdpmast
where pmco# = :selComp;
endsr;
begsr OpenCursor;
exec SQL open C1;
endsr;
begsr FetchData;
exec sql fetch next from C1 into :company, :part, :desc;
msg = company + ':' + part + ':' + desc;
dsply msg;
endsr;
end-proc;
Note that this is a working (example) program. But the DeclareCursor subroutine is never actually called! It doesn't need to be, even though a host variable is used in the WHERE clause.
The value of the host variable is use when the OPEN is executed.
Also note that in embedded SQL as shown above, SET OPTION is a compile time statement. In fact, there can only be a single SET OPTION statement in the entire source member and it must be the first SQL statement that the pre-compiler sees.

Related

SAS macro string quoting issues causing IN operation not working?

All:
when performing IN operator to match words in a macro string, the quotes are required. But, the results are frustrated, would someone remind me what I have missed.
This macro string is created from proc sql as below
'''
proc sql noprint;
select memname into :domains separated by ' '
from sashelp.vtable
where libname='SDTM';
quit;
'''
Next, I quoted the string using this statement
'''
%let domains_quoted = %nrbquote(')%qsysfunc(prxchange(s/\s+/%nrbquote(',')/oi,-1,&domains))%nrbquote(');
'''
In log, it displayed no issues
SYMBOLGEN: Macro variable DOMAINS_QUOTED resolves to 'AE','CM','DM','DS','EG','EX',...
Then, I wish I can filter the output datasets.
'''
data want;
set have;
if dname in (&domains_quoted);
run;
'''
I got the error message saying:
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been unquoted for printing.
ERROR 22-322: Syntax error, expecting one of the following: a quoted string, a numeric constant, a datetime constant,
a missing value, iterator, (.
Would some one remind me what I have missed in these steps? Great appreciated.
Use the QUOTE() function to avoid the PRX step.
proc sql noprint;
select quote(memname) into :domains separated by ' '
from sashelp.vtable
where libname='SDTM';
quit;
data want;
set have;
if dname in (&domains_quoted);
run;

How to create a complex PL/SQL procedure with Python, cx_Oracle

I have a multi-line PL/SQL procedure, which I have to create.
The SQL procedure is similar to the one below,
CREATE OR REPLACE PROCEDURE HELLO AS
TYPE cur_cur is REF CURSOR;
v_cur_cur cur_cur;
age NUMBER;
day VARCHAR2(10);
date DATE;
BEGIN
<Some Execute Immediate stmts>
<Some insert stmts>
commit;
END;
Currently what I am doing is,
host= "localhost"
port= 1521
sid= "abcbcadacsw.com"
user= "groups"
password= "hello!bye1209"
dsn_tns = oracledb.makedsn(host, port, service_name=sid)
print(dsn_tns)
db_conn = oracledb.connect(user=user, password=password, dsn=dsn_tns)
curs= db_conn.cursor()
curs.execute("""
CREATE OR REPLACE PROCEDURE HELLO AS
TYPE cur_cur is REF CURSOR;
v_cur_cur cur_cur;
age NUMBER;
day VARCHAR2(10);
date DATE;
BEGIN
<Some Execute Immediate stmts>
<Some insert stmts>
commit;
END;
""")
The thing is the code runs without any issues, there are not runtime errors or anything ... but when i log into the DB to check for the created procedure, its not present. When i try to execute the procedure, it says 'identifier must be declared ... '.
I have tried converting it into a single line
curs.execute("""CREATE OR REPLACE PROCEDURE HELLO AS TYPE cur_cur is REF CURSOR; v_cur_cur cur_cur; age NUMBER; day VARCHAR2(10); date DATE; BEGIN <Some Execute Immediate stmts> <Some insert stmts> commit; END;""")
This also does not work.
Please assist, ignore the correctness of the above shown procedure, i cannot put the original here, and i dont know much of SQL, i just need to know how to successfully create it in Python.
The driver doesn't (yet) return Oracle DB's 'success with info' errors so if there is a problem with the PL/SQL code you won't find out about it unless you explicitly query the error view.
In SQL*Plus:
create or replace procedure fred as
begin
f();
end;
/
would give:
Warning: Procedure created with compilation errors.
and a subsequent show errors will give
Errors for PROCEDURE FRED:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/3 PL/SQL: Statement ignored
3/3 PLS-00201: identifier 'F' must be declared
With cx_Oracle (and its new version python-oracledb) you don't get the initial indication there was a problem so you always should do the equivalent of the show errors command to check the error view. Try something like:
with connection.cursor() as cursor:
sql = """create or replace procedure fred as
begin
f();
end;"""
cursor.execute(sql)
sql = """select name, type, line, position, text
from user_errors
order by name, type, line, position"""
for r in cursor.execute(sql):
print(r)
which will show output like:
('FRED', 'PROCEDURE', 3, 20, 'PL/SQL: Statement ignored')
('FRED', 'PROCEDURE', 3, 20, "PLS-00201: identifier 'F' must be declared")
This is shown in the documentation Creating Stored Procedures and Packages.

how can I use '$$' as column data in a db2 update query when running in script

I have to run an update query in shell script
db2 "update tablename set fam=' ' where fam='$$' ";
Even though the table has fam='$$' I'am getting the below message as:
No row found for FETCH,UPDATE or DELETE; or the result of a query is an empty table.
this is because "$$" is considered as PID ie process id. So how can I handle this
Try something like this:
db2 "update tablename set fam=' ' where fam='\$\$' ";
You need to escape special characters.

SYBASE cursor declare as for read only become infinitive

There is a simple cursor, which has 260 records. Inside the loop not only print but update some tables. There is not only code, but explanation
/*Declare cursor for read only*/
DECLARE crsr_one CURSOR FOR
SELECT a,b,c,d
FROM table_name
WHERE a>=100
for read only
OPEN crsr_one /*open cursor*/
DECLARE #a,#b,#c,#d /*declare loop variables*/
while (1=1) /*start while loop*/
BEGIN
FETCH crsr_one into #a,#b,#c,#d /*fetch into variable */
IF (##sqlstatus = 2) /*Break if no more records*/
break
/*some other code with select and update table*/
print "%1! %2! %3! %4!", #a,#b,#c,#d /*Print variables*/
END
The problem is:
In the while loop it became infinitive and brings the same data.
Any idea why and how to correct it?
Your code looks good (except that the syntax for the DECLARE is invalid).
If the loop doesn't break on ##sqlstatus = 2, then the obvious question is: what value does it have? It can also be '1', indicating an error. To find out, print the value.
To be fully correct you should therefor also test for ##sqlstatus = 1. The easiest way to do this is to test for ##sqlstatus != 0 which covers both values 1 and 2.

Delphi/Query component - assign a long string (800 char) to a sql.text property trim the sql to 326 char only

I use Delphi/NexusDB and I build SQL (about 800 char long) at run time then I pass it to the nexusdb query.sql.text property to execute it but I found error of invalid token on execution.
I pass SQL like this
Query.SQL.Text := VarStrSQL; // <<---- string variable holding the SQL
when I traced I found SQL string in the Query.SQL.Text is trimmed to 326 character !!
While the string variable that hold the SQL is complete and fine but when I assign that variable to query.sql.text only 326 character passed and of course this result in an error for invalid SQL syntax
Please advise why the SQL string trimmed like that ?
Update:
*I tried memo1.lines.text := VarStrSQL and the memo component also display the string trimmed !! is it possible a character in my string cause that !! a bug in Delphi 2010 that cause TStrings to trim my string ?*
Thanks
Sounds like a bug in DB provider itself. There is no such limitation in TQuery.
My advice shall be to use small SQL, but bound parameters to set the data.
Instead of
Query.SQL.Text := 'INSERT INTO Store_Information (store_name, Sales, Date)
VALUES ('Los Angeles ... ... ...', 900, '10-Jan-1999')';
code
Query.FieldByName('store').AsString := 'Los Angeles ... ... ...'; // here you should have no limitation
Query.FieldByName('sales').AsInteger := 900;
Query.FIeldByName('Date').AsDAteTime := Now;
Query.SQL.Text := 'INSERT INTO Store_Information (store_name, Sales, Date)
VALUES (:store,:sales,:date)';
And your request will be faster, since the statement could be preparated by the engine, then reused.
I found the problem:
It is nxtChar Fields when they are null they have the value #0 and that cause string trimming
however although I check for null like this varisnull() the char fields was able to skip this trap function !!! which makes me go around myself for hours finally I now check them like this
If <nxtChar field> = #0 then <nxtChar field> = '' (or <nxtChar field> = null)

Resources