web-dev-qa-db-fra.com

Comment déclarer et utiliser des variables dans PL / SQL comme dans T-SQL?

Dans SQL Server, souvent lorsque je teste le corps d'une procédure stockée, je le copie dans SSMS, DÉCLARE les variables en haut de la page, leur attribue des valeurs d'exemple et les exécute tel quel.

Par exemple, si mon proc est

CREATE PROC MySampleProc
    @Name   VARCHAR(20)
AS
    SELECT @Name

Ensuite, mon test SQL serait

DECLARE @Name VARCHAR(20)
SET     @Name = 'Tom'

    SELECT @Name

Quel est l'équivalent Oracle PL/SQL?

C’est le cas le plus proche que j’ai trouvé, mais j’obtiens "PLS-00428: une clause INTO est attendue dans cette instruction SELECT"

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     select myname from DUAL;
END;

C'est un meilleur exemple de ce que j'essaie vraiment de faire:

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     SELECT *
     FROM   Customers
     WHERE  Name = myname;
END;

Mais encore une fois, il veut un 'INTO' alors que je veux juste que les enregistrements soient imprimés à l'écran et non stockés dans un autre tableau ....

RÉSOLU:

Grâce à @Allan, ça marche assez bien. Oracle SQL Developer se souvient apparemment des valeurs de paramètre que vous lui avez fournies. Le développeur PL/SQL, cependant, ne veut rien avoir à faire avec cela ....

enter image description here

Si vous "Exécuter en tant que script", vos valeurs par défaut seront respectées, mais les résultats ne seront renvoyés que sous forme de texte ASCI, pas dans une grille/une feuille de calcul.

enter image description here

24
Tom Halladay

Réponse révisée

Si vous n'appelez pas ce code depuis un autre programme, une option consiste à ignorer PL/SQL et à le faire strictement en SQL à l'aide de variables de liaison:

var myname varchar2(20);

exec :myname := 'Tom';

SELECT *
FROM   Customers
WHERE  Name = :myname;

Dans de nombreux outils (tels que Toad et SQL Developer), l'omission des instructions var et exec fera que le programme vous demande de saisir la valeur.


Réponse originale

Une grosse différence entre T-SQL et PL/SQL est qu'Oracle ne vous permet pas de renvoyer implicitement le résultat d'une requête. Le résultat doit toujours être explicitement renvoyé d'une manière ou d'une autre. Le moyen le plus simple consiste à utiliser DBMS_OUTPUT (approximativement équivalent à print) pour afficher la variable:

DECLARE
   myname varchar2(20);
BEGIN
     myname := 'Tom';

     dbms_output.print_line(myname);
END;

Ce n'est toutefois pas très utile si vous essayez de renvoyer un jeu de résultats. Dans ce cas, vous voudrez peut-être renvoyer une collection ou un refcursor. Toutefois, l'utilisation de l'une de ces solutions nécessiterait d'intégrer votre code dans une fonction ou une procédure et d'exécuter la fonction/procédure à partir de quelque chose capable de consommer les résultats. Une fonction qui fonctionne de cette manière pourrait ressembler à ceci:

CREATE FUNCTION my_function (myname in varchar2)
     my_refcursor out sys_refcursor
BEGIN
     open my_refcursor for
     SELECT *
     FROM   Customers
     WHERE  Name = myname;

     return my_refcursor;
END my_function;
20
Allan

Dans Oracle PL/SQL, si vous exécutez une requête pouvant renvoyer plusieurs lignes, vous devez disposer d'un curseur pour parcourir les résultats. Le moyen le plus simple consiste à utiliser une boucle for, par exemple:

declare
  myname varchar2(20) := 'tom';
begin
  for result_cursor in (select * from mytable where first_name = myname) loop
    dbms_output.put_line(result_cursor.first_name);
    dbms_output.put_line(result_cursor.other_field);
  end loop;
end;

Si vous avez une requête qui retourne exactement une ligne, vous pouvez utiliser le select...into... syntaxe, par exemple:

declare 
  myname varchar2(20);
begin
  select first_name into myname 
    from mytable 
    where person_id = 123;
end;
4
GriffeyDog
1
rkosegi