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:"