Добавить статус IF ELSE

Sep 04 2020

У меня есть функция в PHP, например,

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

До сих пор я перевожу это на функцию в Oracle SQL, и теперь основная проблема заключается в добавлении, IF ELSEкоторое для меня, как для новичка, довольно сложно, что бы я ни пытался, я всегда получаю ошибку

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;

Пока есть две ошибки, которые я получаю

Ошибка (524,9): PLS-00103: Обнаружен символ «ВЫБРАТЬ» при ожидании одного из следующих событий: (- + case mod new not null continue avg count current exists max min previous sql stddev sum variance выполнить для всех интервалов времени слияния timestamp свидание трубка <альтернатива

Ошибка (528,3): PLS-00103: обнаружен символ «ВНУТРЕННИЙ» при ожидании одного из следующих событий:,; для группы, имеющей пересечение минус порядок начальное объединение, где соединение

Кто-нибудь может сказать мне, где я ошибся и что здесь не так?

Ответы

WilliamRobertson Sep 04 2020 at 13:28

Что касается того, как справиться с такого рода синтаксической проблемой как новичок, я предлагаю вам попрактиковаться в упрощении ее до наименьшего возможного примера, чтобы вас не отвлекала логика соединения.

Например, вы можете быстро проверить это и убедиться, что это не сработает :

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

который терпит неудачу с

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

потому что open rc for selectсинтаксис должен быть одним оператором и не может быть разделен с помощью условной логики.

Обратите внимание на отсутствие create functionпараметров, объединений и т. Д., Которые усложняют ситуацию. Вы можете добавить все это обратно, как только вы исправите синтаксис. caseСинтаксис утверждения здесь . (Обратите внимание, что есть несколько разных типов case.) Это должно быть либо

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

или эквивалент, используя 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

Это неверный синтаксис. Вы можете сделать это (как предложил Флорин Гита в комментарии):

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;

или вы можете переместить условие в предложение WHERE одного запроса, например:

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;

Однако, если любая из сторон условия bussyUserID != bussyUserIDможет иметь значение NULL, это не сработает без некоторых изменений для обработки значений NULL.

(Примечание: ваше состояние не имеет смысла, когда вы сравниваете bussyUserIDсебя!)