How to display a sys_refcursor data in TOAD's DataGrid - sql

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.

Related

PL/SQL and SQL Developer different results from each other

I am executing a query in PL / SQL in version 7 and version 14, with a function created by me, and both bring me some results, the rest bring 0.
However, when executing the same query in Oracle SQL Developer, the query brings all the results correctly.
I executed the procedure through PL / SQL and Oracle SQL Developer as well, but then none brought me the right result, all the lines were left as "0".
I can't find the problem at all, even on Google.
Basically, the function multiplies the number of rows by columns that start with "ID_", as shown below.
Function:
CREATE OR REPLACE FUNCTION DS_FUNCESP.FNBIGB_CheckDataCells
(pOwn IN VARCHAR2,
pTab IN VARCHAR2)
RETURN NUMBER
IS
v_Qtd NUMBER;
v_str VARCHAR2(2000);
BEGIN
v_Qtd := 1;
v_str := ' SELECT
SUM((SELECT COUNT(1) AS QTY_ROWS FROM ' || pOwn || '.' || pTab || ' d WHERE d.LINORIGEM <> ''CARGA MANUAL'')) AS QTY_DATA
FROM DW_FUNCESP.D_BI_COLUMNS a
LEFT JOIN
DW_FUNCESP.D_BI_TABLES b
ON a.ID_TABLE = b.ID_TABLE
AND a.ID_OWNER = b.ID_OWNER
LEFT JOIN DW_FUNCESP.D_BI_OWNERS c
ON a.ID_OWNER = c.ID_OWNER
WHERE b.NM_TABLE = ''' || pTab || '''
AND a.IN_PRIMARYKEY = ''NAO''
AND SUBSTR(a.NM_COLUMN,1,3) = ''ID_'' ';
DBMS_OUTPUT.put_line(v_str);
EXECUTE IMMEDIATE v_str into v_Qtd ;
return (v_Qtd);
EXCEPTION WHEN OTHERS THEN
RETURN 0;
END FNBIGB_CheckDataCells;
Select statement:
SELECT
c.NM_OWNER ,
b.NM_TABLE ,
DS_FUNCESP.FNBIGB_CHECKDATACELLS(c.NM_OWNER, b.NM_TABLE) AS QTY_DATA
FROM DW_FUNCESP.D_BI_TABLES b
LEFT JOIN DW_FUNCESP.D_BI_OWNERS c
ON b.ID_OWNER = c.ID_OWNER;
Results from PL/SQL:
Results from Oracle SQL Developer:
Clearly we can see the difference from any row, the right one is the Oracle SQL Developer. So I'd like to know what is the problem, how to fix, because the procedure is adding "0" to all the rows, no matter where I run.
Reading those examples from WHEN OTHERS - A Bug, thanks to #Lalit Kumar B for that, I changed:
EXCEPTION WHEN OTHERS THEN
RETURN 0;
To:
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLCODE: '||SQLCODE);
DBMS_OUTPUT.PUT_LINE('Message: '||SQLERRM);
RAISE;
To find out the problem, and thanks for that I found that it was trying to count from a table where it doesn't exist anymore.
So I using an error handling as below, from #Jeffrey Kemp
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
Also, thanks for #Belayer, my code was the problem, agreed on that. Also, executing on both softwares, made me even more confused. I'll read also that documentation for sure.

Running update from SQL Developer with different results as from package

I tried to run an update within an cursor ('cur_palettenkosten') operation in an plsql procedure.
I narrowed down, that the enclosing cursor has data and that the update does not affect any rows (output sql%rowcount)
PROCEDURE p_ref_lschein_rueckstellungen AS
for cur_palettenkosten in (
select land, spediteur_nr, plz_von, plz_bis, preis, gueltig_von, geultig_bis, gzp.behaelter_nr
from spediteur_fahrtkosten sp,gutschrift_zuord_pal gzp
where sp.behaelter_nr = 1
)
LOOP
UPDATE lschein_rueckstellungen
SET preis = cur_palettenkosten.preis
WHERE to_number(sped_nr) = to_number(cur_palettenkosten.spediteur_nr)
AND to_number(lhm_typ) = to_number(cur_palettenkosten.behaelter_nr)
AND to_char(kst) = to_char(cur_palettenkosten.land);
dbms_output.put_line (cur_palettenkosten.spediteur_nr || ' '||cur_palettenkosten.behaelter_nr|| ' '|| cur_palettenkosten.land || sql%rowcount);
END LOOP;
COMMIT;
END p_ref_lschein_rueckstellungen;
Running the script from the editor this way:
BEGIN
p_ref_lschein_rueckstellungen;
END
does have any effect on the table 'lschein_rueckstellungen' which I wanted to update.
Running it from the same editor window like this:
BEGIN
<procedure content copied here>
END
updates the data as desired.
Are the any ideas, what I did wrong?
Could it be that you open a new session per tab? Then of course you have to commit the update!

opening a cursor after some code

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.

Using ACCEPT, CASE to create CURSOR in pl/sql

I am trying to create a script that will allow the user to select which CASE population to use from an ACCEPT when gathering student contact info.
PROMPT 'Select a popluation for emails'
PROMPT '1. Currently registered'
PROMPT '2. New Applicants'
PROMPT
ACCEPT cnt number PROMPT 'Selection: ';
...
CURSOR stu_lst IS
CASE &cnt
WHEN 1 THEN -- Current registered students.
select distinct SFRSTCA_PIDM pidm
from SFRSTCA
where SFRSTCA_TERM_CODE = '201403' and
SFRSTCA_LEVL_CODE = '01' and
SFRSTCA_RSTS_CODE = 'RE';
WHEN 2 THEN -- New applicants
select app_pidm pidm
from app
where app_term = 'Fall 2014';
ELSE
-- Incorrect selection.
DBMS_OUTPUT.PUT_LINE('Incorrect selection made.');
exit;
END;
END;
Assuming the two queries return the same data type, you could use a union with a filter that checks the variable in each part; something like:
DECLARE
CURSOR stu_lst IS
-- Current registered students.
select distinct SFRSTCA_PIDM pidm
from SFRSTCA
where &cnt = 1 and
SFRSTCA_TERM_CODE = '201403' and
SFRSTCA_LEVL_CODE = '01' and
SFRSTCA_RSTS_CODE = 'RE';
UNION ALL
-- New applicants
select app_pidm
from app
where &cnt = 2 and
app_term = 'Fall 2014';
invalid_argument EXCEPTION;
...
BEGIN
IF &cnt NOT IN (1, 2) THEN
RAISE invalid_argument;
END IF
FOR rec IN stu_lst LOOP
h_pidm := rec.pidm;
...
END LOOP;
EXCEPTION
WHEN invalid_argument THEN
dbms_output.put_line('Incorrect selection made.');
END;
/
You could also declare a cursor variable and open that with the appropriate query, inside a case statement within the main body of the block. This sticks with your explicit cursor syntax though.

declare bind variables in script

I have script that uses this variables
with
TIME_DATA as ( select $$D:=:DA$$ td from dual),
GROUP_INFO as (select $$N:=:GR_ID$$ gr_id_number from dual),
and uses them like this
A_PLUS_TEK as(select point_id, ml_id, ml_name, val a_plus_month, DA
from VALUE_DATA, TIME_DATA
where ml_id = 381 and DA = trunc(td, 'MM'))
I want to know how to initialize this variables, now when I run script I have this ouput:
Bind Variable "DA$$" is NOT DECLARED
EDIT: Usually users enter this values on website, I have access only to database, where I got script from reports table. Also I want to know how to initialize this variables from c#.
EIDT2: I took this for example (How do I use variables in Oracle SQL Developer?). It works.
variable v_count number;
variable v_emp_id number;
exec :v_emp_id := 1234;
exec select count(1) into :v_count from emp;
select *
from emp
where empno = :v_emp_id
exec print :v_count;
my code:
declare
variable DA$$ VARCHAR2(80);
variable gr_id$$ number;
begin
exec :DA$$ := to_date('2011-09-13 09:00:00', 'YYYY-MM-DD HH24:MI:SS');
exec :gr_id$$ := '1341';
BEGIN
and then with statement :
WITH
TIME_DATA as ( select $$D:=:DA$$ td from dual),
GROUP_INFO as (select $$N:=:GR_ID$$ gr_id_number from dual),
....
END;
But still have this
Bind Variable "DA$$" is NOT DECLARED
anonymous block completed
This also change nothing
exec :DA$$ := '2011-09-13 09:00:00';
I think that DA$$ is date, because it used in trunc() DA = trunc(td, 'MM'))
When I select Run Statement(trl+Enter), Sql Developer offers to enter bind variables, but I don't know how to enter date.
EDIT3: Finally I do this without Declare, Begin, End and it works :
variable DA$$ VARCHAR2(80);
variable gr_id$$ number;
exec :DA$$ := to_date('2011-09-13 09:00:00', 'YYYY-MM-DD HH24:MI:SS');
exec DBMS_OUTPUT.PUT_LINE(:DA$$);
exec :gr_id$$ := '1341';
with
TIME_DATA as ( select $$D:=DA$$; td from dual),
GROUP_INFO as (select $$N:=:GR_ID$$ gr_id_number from dual),
...
From C# you can do this:
// using Oracle.DataAccess.Client
using(OracleCommand command = new OracleCommand(commandText, dbConnection))
{
command.CommandType = CommandType.Text;
command.Parameters.Add("DA$$", OracleDbType.Int32, valueDA, ParameterDirection.Input);
command.Parameters.Add("GR_ID$$", OracleDbType.Int32, valueGR_ID, ParameterDirection.Input);
}
But review your comand text. Because you will probably face syntax errors due to "$$D:" and "$$N:"