忽略PL / SQL语句

时间:2020-08-07 08:29:02

标签: oracle function plsql

我是PL/SQL的乞gg,我想创建函数来检索AllProject。 到目前为止,我创建的是

          CREATE OR REPLACE FUNCTION GETALLPROJECTS(currentUserID in INT)
   RETURN SYS_REFCURSOR
IS 
   rc  SYS_REFCURSOR;
BEGIN
OPEN rc FOR
        SELECT p.*
        FROM projects p
        LEFT JOIN project_users_schedule_dates pusd
ON     
      pusd.ProjectID = p.ProjectID
AND 
      pusd.UserID = currentUserID
LEFT JOIN responsible_persons rp
ON
   rp.ProjectID = p.ProjectID
AND 
   rp.UserID = currentUserID
LEFT JOIN users u ON u.UserID = currentUserID
WHERE    
     u.User_roleID = 1
(
    (p.Responsible_person_id = currentUserId OR 
    p.Delivery_contact = currentUserId OR 
    rp.UserID = currentUserId OR 
    (pusd.ProjectID = p.ProjectID AND                         
    pusd.UserID = currentUserId AND NOW() BETWEEN pusd.StartDate AND pusd.EndDate + INTERVAL 1 DAY 
    AND
    NOW() BETWEEN p.StartDate AND p.EndDate + INTERVAL 1 DAY)
    AND p.status = 2)
)
 ORDER BY p.ProjectID;
RETURN rc;
END GETALLPROJECTS;

我编译时遇到两个错误,我不明白是什么错误:

第一个错误是:

Error(6,1): PL/SQL: SQL Statement ignored

第二个错误是:

Error(27,24): PL/SQL: ORA-00933: SQL command not properly ended

2 个答案:

答案 0 :(得分:1)

多余的逗号应该是=而不是:=,缺少分号,缺少INTERVAL的单引号。

此外,您不能在单个VARCHAR2变量中选择那么多列,也不能GROUP BY单个列。考虑改为返回一个引用游标:

CREATE OR REPLACE FUNCTION GETALLPROJECTS (currentUserID IN INT)
   RETURN SYS_REFCURSOR
IS
   rc  SYS_REFCURSOR;
BEGIN
   OPEN rc FOR
        SELECT p.*
          FROM projects p
               LEFT JOIN project_users_schedule_dates pusd
                  ON     pusd.ProjectID = p.ProjectID
                     AND pusd.UserID = currentUserID
               LEFT JOIN responsible_persons rp
                  ON     rp.ProjectID = p.ProjectID
                     AND rp.UserID = currentUserID
               LEFT JOIN users u ON u.UserID = currentUserID
         WHERE    u.User_roleID = 1
               OR ( (   p.Responsible_person_id = currentUserID
                     OR p.Delivery_contact = currentUserID
                     OR rp.UserID = currentUserID
                     OR     (    pusd.ProjectID = p.ProjectID
                             AND pusd.UserID = currentUserID
                             AND NOW () BETWEEN pusd.StartDate
                                            AND pusd.EndDate + INTERVAL '1' DAY
                             AND NOW () BETWEEN p.StartDate
                                            AND p.EndDate + INTERVAL '1' DAY)
                        AND p.status = 2))
      ORDER BY p.ProjectID;

   RETURN rc;
END GETALLPROJECTS;

由于我没有您的表,因此以下是在Scott的示例模式下创建的示例,目的只是为了说明您可能会做的事情:

SQL> create or replace function getallemp (par_deptno in number)
  2    return sys_refcursor
  3  is
  4    rc sys_refcursor;
  5  begin
  6    open rc for
  7      select e.*
  8      from emp e
  9      where e.deptno = par_deptno
 10      order by e.ename;
 11    return rc;
 12  end;
 13  /

Function created.

SQL>
SQL> select getallemp(10) from dual;

GETALLEMP(10)
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
      7782 CLARK      MANAGER         7839 09.06.81       2450                    10
      7839 KING       PRESIDENT            17.11.81      10000                    10
      7934 MILLER     CLERK           7782 23.01.82       1300                    10


SQL>

答案 1 :(得分:0)

使用此查询,并首先通过在查询中传递硬编码值来检查查询是否独立运行:

CREATE OR REPLACE FUNCTION GETALLPROJECTS(currentUserID in INT)
   RETURN SYS_REFCURSOR
IS 
   rc  SYS_REFCURSOR;
BEGIN
OPEN rc FOR
        SELECT p.ProjectID,
            p.CustomName,
            p.Name,
            p.Responsible_person_id,
            p.Delivery_contact,
            p.StartDate,
            p.EndDate,
            p.TehnicReview,
            p.status
        FROM projects p
        LEFT JOIN project_users_schedule_dates pusd
ON     
      pusd.ProjectID = p.ProjectID
AND 
      pusd.UserID = currentUserID
LEFT JOIN responsible_persons rp
ON
   rp.ProjectID = p.ProjectID
AND 
   rp.UserID = currentUserID
LEFT JOIN users u ON u.UserID = currentUserID
WHERE    
     u.User_roleID = 1
(
    (p.Responsible_person_id = currentUserId OR 
    p.Delivery_contact = currentUserId OR 
    rp.UserID = currentUserId OR 
    (pusd.ProjectID = p.ProjectID AND                         
    pusd.UserID = currentUserId AND NOW() BETWEEN pusd.StartDate AND pusd.EndDate + INTERVAL 1 DAY 
    AND
    NOW() BETWEEN p.StartDate AND p.EndDate + INTERVAL 1 DAY)
    AND p.status = 2)
)
 ORDER BY p.ProjectID;
RETURN rc;
END GETALLPROJECTS;