Ajouter une instruction IF ELSE

Sep 04 2020

J'ai une fonction en PHP quelque chose comme,

if (  $busyUsersIDS ) {
 SELECT statment 
ELSE {
SELECT statment
 }

Jusqu'à présent, je traduis cela pour fonctionner dans Oracle SQL et le principal problème maintenant est d'ajouter IF ELSEqui est pour moi comme un débutant assez difficile, quoi que j'essaye, j'obtiens toujours une erreur

FUNCTION GET_MOMENT_PROJECT_USERS(p_busyUsersID IN INT)
   RETURN SYS_REFCURSOR IS 
    rc  SYS_REFCURSOR;
    /*getBusyUsersIDS*/
 BEGIN
  OPEN rc FOR
    CASE bussyUserID WHEN bussyUserID THEN
        SELECT u.*,
                ur.Roles 
        FROM 
                users u 
        INNER JOIN 
                user_roles ur 
        ON 
                u.User_roleID = ur.id 
        WHERE 
                u.UserID NOT IN (p_busyUsersID) 
        AND 
                u.Surname IS NOT NULL
        AND 
                u.Lastname IS NOT NULL 
        ORDER BY
                u.ProjectPlanSortIndex;

        ELSE  
                            
        SELECT  u.*, 
                ur.Roles 
        FROM 
                users u 
        INNER JOIN 
                user_roles ur 
        ON 
                u.User_roleID = ur.id 
        WHERE 
                u.Surname IS NOT NULL 
        AND 
                u.Lastname IS NOT NULL 
        ORDER BY 
                u.ProjectPlanSortIndex;
     END;
  RETURN rc;
END GET_BUSY_USERS_IDS;

Jusqu'à présent, il y a deux erreurs que j'obtiens

Erreur (524,9): PLS-00103: Le symbole "SELECT" a été rencontré lors de l'attente de l'un des éléments suivants: (- + case mod new not null continue avg count current exists max min before sql stddev sum variance execute for all merge time timestamp interval date pipe <an alternat

Erreur (528,3): PLS-00103: le symbole "INNER" a été rencontré lors de l'attente de l'un des éléments suivants:,; pour un groupe ayant une intersection moins l'ordre démarrer l'union où se connecter

Quelqu'un peut-il me dire où j'ai commis une erreur et ce qui ne va pas ici?

Réponses

WilliamRobertson Sep 04 2020 at 13:28

En ce qui concerne la manière de faire face à ce type de problème de syntaxe en tant que débutant, je vous suggère de vous entraîner à le simplifier jusqu'au plus petit exemple possible, afin de ne pas être distrait par la logique de jointure.

Par exemple, vous pouvez rapidement tester ceci et voir que cela ne fonctionnera pas :

declare
    rc sys_refcursor;
begin
    open rc for
        case
            when 1 = 1 then select * from dual  -- not valid
        end;
end;

qui échoue avec

ORA-06550: line 6, column 29:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the following: ...

car la open rc for selectsyntaxe doit être une seule instruction et ne peut pas être divisée avec une logique conditionnelle.

Remarquez qu'il n'y a pas create function, de paramètres ou de jointures, etc. pour compliquer les choses. Vous pouvez les rajouter une fois que vous avez corrigé la syntaxe. La casesyntaxe de l'instruction est ici . (Notez qu'il existe plusieurs types de case.) Il doit être soit

declare
    rc sys_refcursor;
begin
    case
        when 1 = 1 then
            open rc for select * from dual;
    end case;
end;

ou l'équivalent en utilisant if:

declare
    rc sys_refcursor;
begin
    if 1 = 1 then
        open rc for select * from dual;
    end if;
end;
TonyAndrews Sep 04 2020 at 08:05

Ce n'est pas une syntaxe valide. Vous pouvez le faire (comme Florin Ghita l'a suggéré dans un commentaire):

FUNCTION GET_MOMENT_PROJECT_USERS(p_busyUsersID IN INT)
   RETURN SYS_REFCURSOR IS 
    rc  SYS_REFCURSOR;
    /*getBusyUsersIDS*/
 BEGIN
  CASE bussyUserID WHEN bussyUserID THEN
    OPEN rc FOR
        SELECT u.*,
                ur.Roles 
        FROM 
                users u 
        INNER JOIN 
                user_roles ur 
        ON 
                u.User_roleID = ur.id 
        WHERE 
                u.UserID NOT IN (p_busyUsersID) 
        AND 
                u.Surname IS NOT NULL
        AND 
                u.Lastname IS NOT NULL 
        ORDER BY
                u.ProjectPlanSortIndex;

  ELSE  
     OPEN rc FOR
        SELECT  u.*, 
                ur.Roles 
        FROM 
                users u 
        INNER JOIN 
                user_roles ur 
        ON 
                u.User_roleID = ur.id 
        WHERE 
                u.Surname IS NOT NULL 
        AND 
                u.Lastname IS NOT NULL 
        ORDER BY 
                u.ProjectPlanSortIndex;
  END CASE;
  RETURN rc;
END GET_BUSY_USERS_IDS;

ou vous pouvez déplacer la condition dans la clause WHERE d'une seule requête, quelque chose comme:

FUNCTION GET_MOMENT_PROJECT_USERS(p_busyUsersID IN INT)
   RETURN SYS_REFCURSOR IS 
    rc  SYS_REFCURSOR;
    /*getBusyUsersIDS*/
 BEGIN
  CASE bussyUserID WHEN bussyUserID THEN
    OPEN rc FOR
        SELECT u.*,
                ur.Roles 
        FROM 
                users u 
        INNER JOIN 
                user_roles ur 
        ON 
                u.User_roleID = ur.id 
        WHERE 
                (bussyUserID != bussyUserID
                 OR u.UserID NOT IN (p_busyUsersID))
        AND 
                u.Surname IS NOT NULL
        AND 
                u.Lastname IS NOT NULL 
        ORDER BY
                u.ProjectPlanSortIndex;

  END CASE;
  RETURN rc;
END GET_BUSY_USERS_IDS;

Cependant, si l'un ou l'autre côté de la condition bussyUserID != bussyUserIDpouvait être nul, cela ne fonctionnerait pas sans quelques modifications pour gérer les valeurs nulles.

(Remarque: votre condition n'a pas de sens car vous vous comparez bussyUserIDà elle-même!)