Dodaj stwierdzenie IF ELSE

Sep 04 2020

Mam funkcję w PHP w stylu,

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

Jak dotąd tłumaczę to na działanie w Oracle SQL, a głównym problemem jest teraz dodanie, IF ELSEktóre jest dla mnie jak początkujący dość trudne, cokolwiek próbuję, zawsze otrzymuję błąd

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;

Jak dotąd są dwa błędy, które otrzymuję

Błąd (524,9): PLS-00103: Napotkano symbol "WYBIERZ", gdy spodziewano się jednego z następujących zdarzeń: (- + wielkość liter mod nowy nie null kontynuuj średnia licznik aktualny istnieje max min przed sql stddev suma wariancji wykonaj dla każdego interwału znacznika czasu łączenia kreska daty <alternat

Błąd (528,3): PLS-00103: Napotkano symbol „INNER” przy oczekiwaniu jednej z następujących sytuacji:,; dla grupy mającej przecięcie minus kolejność początku sumy, w której łączy się

Czy ktoś może mi powiedzieć, gdzie popełniłem błąd i co tu jest nie tak?

Odpowiedzi

WilliamRobertson Sep 04 2020 at 13:28

Jeśli chodzi o to, jak radzić sobie z tego rodzaju problemem składni jako początkujący, proponuję przećwiczyć uproszczenie go do najmniejszego możliwego przykładu, aby nie rozpraszała Cię logika złączeń.

Na przykład możesz szybko to przetestować i zobaczyć, że to nie zadziała :

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

co zawodzi

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

ponieważ open rc for selectskładnia musi być pojedynczą instrukcją i nie można jej rozdzielić za pomocą logiki warunkowej.

Zwróć uwagę, jak nie ma create functionparametrów, połączeń itp., Aby skomplikować rzeczy. Możesz dodać je wszystkie z powrotem, gdy już uporządkujesz składnię. caseSkładnia oświadczenie jest tutaj . (Zauważ, że jest kilka różnych rodzajów case)

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

lub odpowiednik przy użyciu 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

To nie jest prawidłowa składnia. Możesz to zrobić (jak zasugerował Florin Ghita w komentarzu):

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;

lub możesz przenieść warunek do klauzuli WHERE pojedynczego zapytania, na przykład:

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;

Jeśli jednak po którejkolwiek stronie warunku bussyUserID != bussyUserIDmoże być zerowa, to nie zadziałaby bez pewnych zmian w obsłudze wartości null.

(Uwaga: Twój stan nie ma sensu, gdy porównujesz się bussyUserIDze sobą!)