2011-06-07 1 views
4

Pour des raisons de débogage, j'aimerais pouvoir "TO_CHAR" une table Oracle PL/SQL en mémoire. Voici un exemple simplifié, de ce que je voudrais faire:TO_CHAR d'un Oracle TABLE PL/SQL type

DECLARE 
    TYPE T IS TABLE OF MY_TABLE%ROWTYPE INDEX BY PLS_INTEGER; 
    V T; 

BEGIN 
    -- .. 

    -- Here, I'd like to dbms_output V's contents, which of course doesn't compile 
    FOR i IN V.FIRST .. V.LAST LOOP 
    dbms_output.put_line(V(i)); 
    END LOOP; 

    -- I want to omit doing this: 
    FOR i IN V.FIRST .. V.LAST LOOP 
    dbms_output.put_line(V(i).ID || ',' || V(i).AMOUNT ...); 
    END LOOP; 

END; 

Cela peut-il être réalisé simplement? La raison pour laquelle je demande est parce que je suis trop paresseux pour écrire ce code de débogage encore et encore, et je voudrais l'utiliser avec n'importe quel type de table.

+2

pourquoi ne pas écrire une fonction d'aide « print_table » qui encapsule la sortie mise en forme que vous souhaitez, puis utilisez autant de fois que vous le souhaitez ... – tbone

+0

@tbone: Pour tout type de table? Cela peut-il être fait avec le type de données 'ANYTYPE' d'Oracle? –

+0

ne pensait pas la fonction complètement générique pour tous les types, mais c'est une question intéressante ... laissez-moi nouilles dessus, je pense que vous êtes sur la bonne voie avec anydata/anytype – tbone

Répondre

6

ok, désolé ce n'est pas complète, mais son suivi avec @Lukas, voici ce que j'ai jusqu'à présent:

D'abord, au lieu d'essayer de créer des types AnyDATA/de anyType, j'ai essayé d'utiliser XML extrait d'un le curseur ... bizarre, mais son générique:

CREATE OR REPLACE procedure printCur(in_cursor IN sys_refcursor) IS 
begin 

    FOR c IN (SELECT ROWNUM rn, 
        t2.COLUMN_VALUE.getrootelement() NAME, 
        EXTRACTVALUE (t2.COLUMN_VALUE, 'node()') VALUE 
       FROM TABLE (XMLSEQUENCE (in_cursor)) t, 
        TABLE (XMLSEQUENCE (EXTRACT (COLUMN_VALUE, '/ROW/node()'))) t2 
       order by 1) 

    LOOP 
     DBMS_OUTPUT.put_line (c.NAME || ': ' || c.VALUE); 
    END LOOP; 

exception 
    when others then raise; 
end; 
/

maintenant, pour l'appeler, vous avez besoin d'un curseur, alors j'ai essayé coulée de curseur dans pl/sql, quelque chose comme:

open v_cur for select * from table(cast(v_tab as tab_type)); 

mais en fonction de comment v _tab est défini, cela peut ou non causer des problèmes dans pl/sql cast (en utilisant% rowtype dans la table imbriquée def semble donner des problèmes).

De toute façon, vous pouvez construire sur cela ou l'affiner comme vous le souhaitez. (Et peut-être utiliser XMLTable ...)

Hope qui aide

+0

Wow, c'est ce que j'appelle tirer une solution par ses cheveux :) XML, je n'avais pas pensé à ça. Génial, et cela fonctionne pour certains cas. Merci beaucoup! –

+0

C'est vraiment merveilleux! Je continue à l'utiliser tout le temps pour le débogage ... –

+1

[Voici un excellent article] (http://orasql.org/2013/04/02/sqlplus-tips-2/) sur l'utilisation de xmltable pour ce genre d'astuce. Maintenant, grâce à l'auteur, il couvre également un cas où le résultat de la requête a des valeurs nulles (voir dans les commentaires). – AntonLosev