can I use two parameters in db2 cursor and open it using :parm1 :parm2
my cobol source is:
working-storage
01 parm1 pic x(09).
01 parm2 pic x(09).
procedure division.
move '080000' to parm1.
move '090000' to parm2.
move 'select s2p from grp2.arz where s2p > ? and < ?' to st.
and then I prepare it:
exec-sql parepare s1 from :st statement1 end-exec.
exec-sql declare c1 vursor for s1 end-exec.
exec-sql open c1 using :parm1 :parm2 end-exec.
and then I fetch from the cursor.
In run time I got error:
indicator variable parm2 is not smallint type!
The parameters passed in using have to separated by a comma:
exec-sql open c1 using :parm1, :parm2 end-exec.
Without the comma DB2 is interpreting it as a pair of host-variable and null-indicator.
So i have a requirement where I need to read through records of all records of a file and insert them into another file if they meet a set of rules which are described in another table as shown below..
A record after it has been read from the first file has to meet all the sequences of at least one Rule to make it eligible to be written into the Second table.
For example once a record is read from CAR file, the rules below have to be checked till all sequences of atleast one rule set is satisfied. For this I was planning to Create a dynamic SQL program something of this sort. But this does not work as Prepared SQL does not support host variables.
If any body can suggest or provide any guidance on how to create SQL statemtns dynamically and check if records satisfy the required rules for them to be entered into the second file, it would be great
So basically what I am looking for is once I select a field from a table, how do I store it somehere to do further validation and checking.
Update
:
Based on the intelligent advice from Danny117, I have come up with the below code:
H Option(*NoDebugIO:*SrcStmt)
D RULEDS E DS EXTNAME(RULESTABLE)
D MAXRUL S 1 0
D MAXSEQ S 1 0
D STMT S 512
D WHERESTMT S 512 INZ('')
D FullSqlStmt S 512 INZ('')
D RULINDEX S 1 0 INZ(1)
D SEQINDEX S 1 0 INZ(1)
D APOS C CONST('''')
/Free
Exec SQL SELECT MAX(RULENO)INTO :MAXRUL FROM RULESTABLE;
Exec SQL DECLARE RULCRS CURSOR FOR SELECT * FROM RULESTABLE;
Exec SQL OPEN RULCRS;
Exec SQL FETCH RULCRS INTO :RULEDS;
DoW (Sqlcod = 0 AND RULINDEX <= MAXRUL);
Exec SQL SELECT MAX(SEQNO) INTO :MAXSEQ FROM RULESTABLE
WHERE RULENO=:RULINDEX ;
DoW (SEQINDEX <= MAXSEQ);
If (Position <> '');
Field = 'SUBSTR('+%Trim(Field)+','+%Trim(Position)+','
+'1'+')';
EndIf;
WhereStmt = %Trim(WhereStmt) + ' ' + %Trim(field)+ ' ' +
%Trim(condition) + ' ' + APOS + %Trim(Value) + APOS;
If (SeqIndex < MaxSeq);
WhereStmt = %Trim(WhereStmt) + ' AND ';
EndIf;
Exec SQL FETCH NEXT FROM RULCRS INTO :RULEDS;
SeqIndex = SeqIndex + 1;
EndDo;
FullSqlStmt = %Trim('INSERT INTO ITMRVAT SELECT * +
FROM ITMRVA WHERE '+ %Trim(WhereStmt));
Exec SQL Prepare InsertStmt from :FullSqlStmt;
Exec SQL EXECUTE InsertStmt;
RulIndex = RulIndex + 1;
EndDo;
This produces SQL statement as shown below which is what I want. Now let me go ahead and look at the other parts of the code.
> EVAL FullSqlStmt
FULLSQLSTMT =
....5...10...15...20...25...30...35...40...45...50...55...60
1 'INSERT INTO ITMRVAT SELECT * FROM ITMRVA WHERE STID = 'PLD' '
61 'AND ENGNO LIKE '%415015%' AND SUBSTR(ENGNO,1,1) = 'R' AND SU'
121 'BSTR(ENGNO,5,1) = 'Y' '
181 ' '
241 ' '
301 ' '
361 ' '
421 ' '
481 ' '
But the issue is now as I mentioned in my comment to Danny, how to handle if a new rule involving second table is specified..
Embedded SQL does allow for 'dynamic statements' in ILE languages. You are able to have a query within a character field and then pass it into the Embedded SQL.
Dcl-S lQuery Varchar(100);
lQuery = 'SELECT * FROM CUST';
EXEC SQL
PREPARE SCust FROM :lQuery;
EXEC SQL
DECLARE SearchCust CURSOR FOR SCust;
//Continue working with cursor..
You may want to just prepare, execute and return a result set:
lQuery = 'SELECT * FROM CUST WHERE ID = ' + %Char(CustID);
EXEC SQL
PREPARE SCust FROM :lQuery;
DECLARE c1 CURSOR FOR SCust;
OPEN c1;
FETCH c1 INTO :CustDS;
CLOSE c1;
Optional extra: You may also want to use field markers (?) in your query.
//'SELECT * FROM CUST WHERE CUSTID = ?';
EXEC SQL OPEN SearchCust USING :CustID;
//'INSERT INTO CUST VALUES(?,?)';
EXEC SQL EXECUTE CUST USING :CustID;
You have to translate the rules into a join statement or a where clause. The join statement is more complex so go that route.
If you were smart (and you are) consider saving the rules as a SQL clause that you can join or use in a where clause. Its infinitely flexible this way a more modern design.
rule 1 / car.year = 1990 and car.engno like '%43243%' and substring(car.vin,12,1) = 'X'
eval statement =
insert into sometable
Select car.* from car
join sysibm.sysdummy1
on car.year = 1990
and car.engno lile '%43243%'
...etc on to rule 2 starting with "OR"
or car.year = PLD
and car.engno like '%1234%'
...etc other rules starting with "OR"
exec immediate statement
I have some Stored Procedure in DB2. Some lines of code (INSERT, UPDATE etc). After some operations I have IF condition that opening/not opening CURSOR. For some reason the CURSOR is not opened even if IF condition is TRUE. All the code before the CURSOR works fine. If I'll remove it, so the CURSOR will works fine. If I'll put the CURSOR in separate SP, it works fine (calling for another SP from this SP). But together for some reason it not works. I can't understand why. I need this code for the IF condition.
That's how it looks (only 1 row with INSERT left outside the CURSOR):
DECLARE C1 CURSOR WITH HOLD FOR
SELECT s.KEY, s.CODE, s.PRODUCT, s.AMOUNT
FROM DB2ADMIN.SALES s, DB2ADMIN.PRODUCTS p
WHERE s.DATE_KEY = CDC AND s.PRODUCT_KEY = p.PRODUCT_KEY;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET EOF = 1;
INSERT INTO DB2ADMIN.IA_BASE_SALES_TMP (SOME_FIELD) VALUES (SOME_VALUE);
IF true THEN
OPEN C1;
WHILE EOF = 0 DO
FETCH FROM C1 INTO SP_KEY, SP_CODE, SP_KEY, SP_PRODUCT, SP_AMOUNT;
MERGE INTO DB2ADMIN.IA_BASE_SALES_TMP t
USING (
SELECT POS, p.KEY, s.TELLER, s.TYPE, s.AMOUNT, s.CDC
FROM DB2ADMIN.COMMISSIONS s, DB2ADMIN.PRODUCTS p
WHERE TELLER = SP_TELLER AND TYPE = SP_TYPE
) e ON t.TELLER_KEY = e.TELLER_ID
WHEN matched
THEN UPDATE SET t.KEY = e.KEY, t.UPD = 0;
END WHILE;
CLOSE C1;
END IF;
Thanks to Jean.
Replacing the cursor with FOR loop and everything works OK.
Please i need help.
(I SEARCHED A lot and get more confused . )
I use Toad 9.7.25 and i made this procedure (in a package)
PROCEDURE ReportaCC(pfcorte IN DATE, lcursor IN OUT SYS_REFCURSOR)
IS
BEGIN
OPEN lcursor FOR
select c1, c3, c3 from table1 where hdate = pfcorte;
close lcursor;
END;
In toad's sql editor i´d like execute that procedure and show the cursor results in toad's datagrid:
--- I WANT THIS CODE CAN EXECUTE IN TOAD'S SQL EDITOR.
DECLARE
PFCORTE DATE;
LCURSOR SYS_REFCURSOR;
BEGIN
PFCORTE := '31/08/2012';
-- LCURSOR := NULL; -- Modify the code to initialize this parameter
mypaq.REPORTACC( TO_DATE(PFCORTE,'DD/MM/YYYY') , LCURSOR );
:to_grid := LCURSOR;
COMMIT;
END;
When i execute the script (F9), and set the variable :to_grid type cursor,
i get the next error:
"ORA-24338: statement handle not executed"
What can be the problem
Thanks in advance.
Thanks four your posts... worked fine!
But now have another question...
If i replace the simple query (select c1, c2, c3 from table...) for a mor complex like this:
PROCEDURE ReportaCC(pfcorte IN DATE, lcursor OUT SYS_REFCURSOR)
IS
BEGIN
OPEN lcursor FOR
SELECT ENC.CVEOTORGANTE, ENC.NOMBREOTORGANTE, ENC.IDENDINTIFICADORDEMEDIO, TO_CHAR(SYSDATE, 'YYYYMMDD') AS FECHAEXT, ENC.NOTAOTORGANTE,
CIRCRED.valida_cc.QUITASIGNOS(VCL.APELLIDOPATERNO) AS VAL_APELLIDOPATERNO,
CIRCRED.valida_cc.QUITASIGNOS(VCL.APELLIDOMATERNO) AS VAL_APMATERNO,
CIRCRED.valida_cc.QUITASIGNOS(VCL.APELLIDOADICIONAL) AS APELLIDOADICIONAL ,
CIRCRED.valida_cc.QUITASIGNOS(VCL.NOMBRES) AS NOMBRES,
VCL.FECHANACIMIENTO,
circred.valida_cc.valida_rfc(Vcl.rfc,'CORRIGE') AS VALRFC,
circred.valida_cc.valida_curp(VCL.CURP,'CORRIGE') AS VALCURP, VCL.NACIONALIDAD,
circred.valida_cc.valida_RESIDENCIA('ESIACOM', SC.TIPOVIV ) AS VAL_RESIDENCIA, VCL.NUMEROLICENCIACONDUCIR,
circred.valida_cc.valida_EDOCIVIL('ESIACOM', VCL.ESTADOCIVIL) AS VAL_ESTADOCIVIL, VCL.SEXO,
circred.valida_cc.valida_IFE(VCL.CLAVEELECTORIFE,'CORRIGE') AS CLAVEELECTORIFE,
VCL.NUMERODEPENDIENTES,
VCL.FECHADEFUNCION, VCL.INDICADORDEFUNCION, VCL.TIPOPERSONA,
CIRCRED.valida_cc.QUITASIGNOS(VCL.DIRECCION) AS DIRECCION,
CIRCRED.valida_cc.QUITASIGNOS(VCL.COLONIAPOBLACION) AS COLONIAPOBLACION,
CIRCRED.valida_cc.QUITASIGNOS(VCL.DELEGACIONMUNICIPIO) AS DELEGACIONMUNICIPIO,
CIRCRED.valida_cc.QUITASIGNOS(VCL.CIUDAD) AS CIUDAD,
VCL.ESTADO, circred.valida_cc.valida_cp(VCL.CP, VCL.CDGEF) AS VAL_CP, VCL.FECHARESIDENCIA,
circred.valida_cc.valida_TEL(VCL.NUMEROTELEFONO,'CORRIGE') AS VAL_TEL, circred.valida_cc.valida_TIPODOMICILIO('ESIACOM', 'C') AS VAL_TIPODOMICILIO, VCL.TIPOASENTAMIENTO,
EMP.*,
ENC.CVEOTORGANTE CVEACTUAL, ENC.NOMBREOTORGANTE, SAL.CUENTAACTUAL, SAL.TIPORESPONSABILIDAD, SAL.TIPOCUENTA, SAL.TIPOCONTRA, SAL.CLAVEUNIDADMONETARIA, SAL.VALORACTIVOVALUACION,
SAL.NUMPAGOS, SAL.FREQPAGOS,SAL.PAGOPACCL, SAL.FECHAAPERTURACUENTA,
TO_CHAR(circred.valida_cc.FUN_FULTDEPCL(sal.CLNS, sal.CDGNS, sal.CDGNS, sal.CDGCL, sal.CICLO, SAL.INICICLO, SAL.FREQPAGOS, pfcorte ), 'YYYYMMDD') AS FULTPAGO,
SAL.FECHAULTIMACOMPRA, SAL.FECHACIERRECUENTA, SAL.FECHACORTE, SAL.GARANTIA, SAL.CREDITOMAXIMO,
SAL.SALDOCL, SAL.limitecredito, SAL.SDOVENCL, SAL.NUMPAGVEN, SAL.pagoactual, SAL.HISTORICOPAG, SAL.CLAVEPREVENCION, SAL.TOTPAGREP, SAL.CLAVEANTERIOROTORGANTE,
SAL.NOMBREANTERIOROTORGANTE, SAL.NUMEROCUENTAANTERIOR,
SAL.SUMSALDO, SAL.sumsdoven, SAL.numcred, SAL.numdirecc, SAL.numempleo, SAL.numctas, ENC.NOMBREOTORGANTE, NULL AS DOMDEVOL
FROM
CIRCRED.VW_ENCABEZADO ENC,
circred.VW_DATOSPERDOM VCL,
ICARO.VW_PROYINVE SC,
CIRCRED.EMPLEO EMP,
CIRCRED.VW_SALDOINCOB SAL
WHERE SAL.FUENTEBD = 'ESIACOM'
AND SAL.CDGCL = VCL.CDGCL
AND SAL.CDGCL = SC.CDGCL(+) AND SAL.CICLO = SC.CICLO(+) and SAL.INICICLO = SC.INICIO(+)
AND SAL.FCORTE = pfcorte
AND SAL.STATUSCC IN ('INCOB', 'CIERR', 'CEROS') ;
END ReportaCC;
Why cant display the results?
(The query works fine if i execute it directly in a TOAD SQL editor)
Thanks again....!!!
After you hit F9 the "Variables" dialog appears and you select Type=Cursor from the dropdown list then press OK:
The reason you are getting the "ORA-24338: statement handle not executed" error is because you are closing your cursor before it is accessed.
This is the process that is happening:
Execute procedure
OPEN statement returns a pointer to the result set in memory (but does not return any data)
CLOSE statement discards the results before they are accessed
Procedure call ends
The client caller (in this case TOAD) attempts to access the result stream, but the pointer is invalid, so nothing can be read and the error is thrown
Solution: Remove the close lcursor; statement.
As your procedure is doing only a select statement better use a function like
CREATE or REPLACE function ReportaCC(pfcorte IN DATE)
RETURN SYS_REFCURSOR
AS
lcursor SYS_REFCURSOR;
BEGIN
OPEN lcursor FOR
select c1, c3, c3 from table1 where hdate = pfcorte;
RETURN lcursor ;
END;
/
Do not close lcursor here, close from your calling statement because if you close lcursor then you wouldn't be able to see any results.
And execute as
select ReportaCC(<>) from dual
from toad, double click cursor in datagrid to see the results.
I have a column that I'm looking to extract but am having issues! The column is stored as type ntext and contains an RTF document so looks something like this:
{\rtf1\ansi\ansicpg1252\uc1\deff0{\fonttbl {\f0\fnil\fcharset0\fprq2 Arial;} {\f1\fswiss\fcharset0\fprq2 Arial;} {\f2\froman\fcharset2\fprq2 Symbol;}} {\colortbl;\red0\green0\blue0;\red255\green255\blue255;} {\stylesheet{\s0\itap0\nowidctlpar\f0\fs24 [Normal];}{\*\cs10\additive Default Paragraph Font;}} {\*\generator TX_RTF32 15.0.530.502;} \deftab1134\paperw11909\paperh16834\margl1138\margt1138\margr1138\margb1138\widowctrl\formshade\sectd \headery720\footery720\pgwsxn11909\pghsxn16834\marglsxn1134\margtsxn1134\margrsxn1134\margbsxn1134\pard\itap0\nowidctlpar\plain\f1\fs20 Stephan Bos 28/11/2011 11:19:55\par\par Sold in guy. He likes him, feedback this afternoon.\par Will send him the CV and also our terms.\par Made him aware of our fees.\par }
But I'm looking to extract this back into (rtf or txt I don't really mind)
I've tried using BCP which has had success in extracting the documents but they end up exactly the same as the column but with spaces between each character rather than as I'd expect (example above would end up reading something like:
Stephan Bos 28/11/2011 11:19:55
Sold in guy. He likes him, feedback this afternoon.
Will send him the CV and also our terms.
Made him aware of our fees.
The BCP extract that I'm using (which is extracting) is as follows:
set nocount on;
Declare #sql varchar(1000);
declare #noteid int;
declare xx1 cursor for select nic.NotebookItemId from NotebookItemContent nic
inner join NotebookLinks nl on nl.NotebookItemId = nic.NotebookItemId
inner join NotebookItems ni on ni.NotebookItemId = nic.NotebookItemId
where nl.clientid = 1235074
AND ni.NotebookTypeId = 56;
open xx1;
fetch xx1 into #noteid;
while (##fetch_status = 0)
begin
set #sql = 'BCP "SELECT memo FROM Monarch_Pronet_ITOIL.dbo.notebookitemcontent where notebookitemid=' + cast(#noteid as varchar) +
'" QUERYOUT \\bhamws475\docs\' + cast(#noteid as varchar) + '.rtf -T -f \\bhamws475\docs\bcp.fmt -S ' + ##SERVERNAME
EXEC master.dbo.xp_CmdShell #sql
fetch xx1 into #noteid;
end;
close xx1;
deallocate xx1;
Can anyone point me in the right direction?
I think I understood now - the problem is that the RTF saved by BCP is not recognized as an RTF file by Word - it is opened as a plain text file.
This is due to the fact that the exported file is in Unicode (you see that by the fact that each character is followed by an empty space in the screen-shot).
The solution is to tell bcp to save not in Unicode - that I think can be done either with the -c switch or specifying the desired character set in the format file.