Agregar declaración IF ELSE

Sep 04 2020

Tengo una función en PHP algo como,

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

Hasta ahora traduzco esto para que funcione en Oracle SQL y el problema principal ahora es agregar, IF ELSEque es para mí como un principiante bastante difícil, lo que sea que intento siempre obtengo un error

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;

Hasta ahora hay dos errores que obtengo

Error (524,9): PLS-00103: Se encontró el símbolo "SELECCIONAR" cuando se esperaba uno de los siguientes: (- + caso mod nuevo no nulo continuar recuento promedio actual existe máximo mínimo antes sql stddev suma varianza ejecutar para todo el tiempo de fusión intervalo de marca de tiempo tubo de fecha <una alternativa

Error (528,3): PLS-00103: Se encontró el símbolo "INNER" cuando esperaba uno de los siguientes:,; para el grupo que tiene intersección menos orden iniciar unión donde conectar

¿Alguien puede decirme dónde cometí un error y qué está mal aquí?

Respuestas

WilliamRobertson Sep 04 2020 at 13:28

Con respecto a cómo lidiar con este tipo de problema de sintaxis como principiante, le sugiero que practique simplificándolo hasta el ejemplo más pequeño posible, para que no se distraiga con la lógica de combinación.

Por ejemplo, puede probar esto rápidamente y ver que no funcionará :

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

que falla con

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

porque la open rc for selectsintaxis tiene que ser una sola declaración y no se puede dividir con lógica condicional.

Observe cómo no hay create function, parámetros o uniones, etc. para complicar las cosas. Puede volver a agregarlos una vez que haya aclarado la sintaxis. La casesintaxis de la declaración está aquí . (Observe que hay un par de tipos diferentes de case). Debe ser

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

o el equivalente usando 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

Esa no es una sintaxis válida. Puede hacer esto (como sugirió Florin Ghita en un comentario):

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;

o puede mover la condición a la cláusula WHERE de una sola consulta, algo como:

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;

Sin embargo, si cualquier lado de la condición bussyUserID != bussyUserIDpudiera ser nulo, esto no funcionaría sin algún cambio para manejar los nulos.

(Nota: ¡Su condición no tiene sentido ya que se compara bussyUserIDconsigo misma!)