0
votes

Comment attribuer plusieurs valeurs à une variable à l'aide de la clause de la requête Oracle?

J'ai une procédure stockée Oracle comme celle-ci xxx

Maintenant, comment dois-je créer cette variable v_out afin qu'elle puisse contenir toutes les valeurs provenant de la requête? Je fais cela dans oracle12c.


0 commentaires

3 Réponses :


0
votes

Vous ne mettez pas la clause dans la requête du curseur. Et même si vous l'avez fait, vous l'avez au mauvais endroit de la déclaration SQL.

Vous faites face à cela lorsque vous récupérez une ligne de la requête: xxx

mais que le problème est que nous continuons simplement à superposer la valeur précédente, de sorte que lorsque votre procédure Exits réellement, la seule valeur de v_out est que la dernière attribution est attribuée. Si vous avez vraiment besoin d'une collection de valeurs, vous devez déclarer votre variable de sortie d'être un curseur REF et ajuster le code en conséquence. Je n'ai jamais travaillé avec eux, alors peut-être que quelqu'un d'autre choisira.


5 commentaires

Quand j'essaie ceci, cela me donne une erreur en disant PSL-0032: le nom de la composante doit être déclaré. Y a-t-il une condition préalable à définir pour le serveur pour reconnaître que "nom"


Essayez d'aloriasser la colonne «distincte» - Sélectionnez Distinct (Nom) comme nom de nom. Puis référence cela comme élément.my_name, au lieu de l'élément.name


Oui, ça marche, merci. Mais la variable lorsqu'elle est accessible hors de la boucle n'a que la valeur du dernier élément. Y a-t-il un moyen de le faire globalement?


Voir mon édition à ma réponse. On dirait que vous aurez besoin de retourner un Refcurseur. Ou peut-être, s'il n'y a pas trop de valeurs, construisez une chaîne délimitée par des virgules et renvoyez cela. Vous devez en donner à quel point la valeur de retour doit être consommée par l'appelant.


En fait, tout ce que nous devons faire ici est de concaténer le v_out. "V_out: = v_out || item.my_name" et nous sommes terminés. Merci pour votre réponse. Vous pouvez modifier cela comme une réponse finale car c'est le moyen le plus simple d'atteindre la sortie.



0
votes

Vous pouvez travailler avec des collections, comme ceci:

--declare the pakage type
CREATE OR REPLACE PACKAGE PKG_TYPES AS        
  TYPE LIST_VARCHAR        IS TABLE OF VARCHAR2(2000);                        
END;

--create the proc that will assemble the value list
CREATE OR REPLACE PROCEDURE DEMO ( V_IN IN  varchar2, V_OUT IN OUT PKG_TYPES.LIST_VARCHAR) IS
  BEGIN
    FOR ITEM IN ( 
      SELECT DISTINCT (NAME) name 
        FROM (SELECT 'X' ID, 'A' name FROM dual
              UNION 
              SELECT 'X' ID, 'b' name FROM dual
              UNION
              SELECT 'y' ID, 'c' name FROM dual
              ) TABLE1 
        WHERE ID= V_IN 
        )
    LOOP
      V_OUT.EXTEND;
      V_OUT(V_OUT.LAST) := item.name;
      --CODE TO PRINT V_OUT
    END LOOP;
  END;

--use the list. I separated this step but it can be in the demo proc as well
DECLARE 
  names PKG_TYPES.LIST_VARCHAR := PKG_TYPES.LIST_VARCHAR();
BEGIN
  demo('X',names) ;
  FOR i IN names.first..names.last LOOP
    Dbms_Output.put_line(i); 
  END LOOP;
END;


0 commentaires

0
votes

Si vous avez besoin d'une variable de collecte - vous pouvez utiliser une table imbriquée et une collecte en vrac bloquée comme ci-dessous. Pour pouvoir renvoyer la valeur de la procédure, vous devez déclarer le type de table imbriqué dans un package ou sur le niveau de schéma de la base de données.

declare
    test_str varchar2(4000);
begin
    select listagg(name, ', ') within group(order by 1)
    into test_str
    from (
        select distinct name
        from (
            select 1 id, 'AAA' name from dual
            union all
            select 1 id, 'BBB' name from dual
            union all
            select 1 id, 'AAA' name from dual
            union all
            select 2 id, 'CCC' name from dual
        )
        where id = 1
    );

    dbms_output.put_line(test_str);
end;
/


0 commentaires