Adicionar declaração IF ELSE

Sep 04 2020

Eu tenho uma função em PHP algo como,

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

Até agora eu traduzo isso para funcionar em Oracle SQL e o principal problema agora é adicionar, o IF ELSEque para mim é como um iniciante muito difícil, o que quer que eu tente sempre recebo erro

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;

Até agora, há dois erros que recebo

Erro (524,9): PLS-00103: Encontrado o símbolo "SELECT" ao esperar um dos seguintes: (- + case mod novo não nulo continue avg contagem atual existe max min anterior sql stddev soma variância executar forall tempo de fusão intervalo de registro de tempo tubo de data <um alternativo

Erro (528,3): PLS-00103: Encontrado o símbolo "INNER" ao esperar um dos seguintes:,; para o grupo tendo intersecção menos ordem iniciar união onde conectar

Alguém pode me dizer onde cometi um erro e o que está errado aqui?

Respostas

WilliamRobertson Sep 04 2020 at 13:28

Em relação a como lidar com esse tipo de problema de sintaxe como um iniciante, sugiro que você pratique simplificando até o menor exemplo possível, para que não se distraia com a lógica de junção.

Por exemplo, você pode testar isso rapidamente e ver se não funcionará :

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

que falha com

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

porque a open rc for selectsintaxe deve ser uma única instrução e não pode ser dividida com a lógica condicional.

Observe como não há create functionparâmetros ou junções etc. para complicar as coisas. Você pode adicionar tudo isso de volta assim que tiver a sintaxe correta. A casesintaxe da instrução está aqui . (Observe que existem alguns tipos diferentes de case.) Precisa ser

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

ou o 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

Essa sintaxe não é válida. Você pode fazer isso (como Florin Ghita sugeriu em um comentário):

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 você pode mover a condição para a cláusula WHERE de uma única 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;

No entanto, se qualquer um dos lados da condição bussyUserID != bussyUserIDpudesse ser nulo, isso não funcionaria sem alguma alteração para lidar com nulos.

(Observação: sua condição não faz sentido, pois você está comparando bussyUserIDa si mesma!)