PL/SQL 语句被忽略

Posted

技术标签:

【中文标题】PL/SQL 语句被忽略【英文标题】:PL/SQL Statment Ignored 【发布时间】:2020-08-07 08:29:02 【问题描述】:

我是PL/SQL 的初学者,我想创建函数来检索 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

【问题讨论】:

另外请检查查询是否在函数之外独立工作,我也看到 Group by 语句有问题。 是的,我对其进行了测试,它工作正常,但是当我将其转换为函数时不起作用! 这看起来有点奇怪u.User_roleID = 1 ( (p.Responsible_person_id = currentUserId OR.. 你确定这个 SQL 有效吗? 这是mysql 查询,我需要转移到PL/SQL 【参考方案1】:

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

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

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>

【讨论】:

还是有问题。错误:PL/SQL:编译单元分析终止错误(1,29):PLS-00201:必须声明标识符“CURRENTUSERID” 应该是CREATE OR REPLACE FUNCTION GETALLPROJECTS (currentUserID in int),反之则不然。 我不知道这里发生了什么,但仍然有错误:/ 我添加了更多信息以及示例。看看有没有帮助。 这是主要问题。我想加速我在 php 和 Oracle 数据库中完成的应用程序。一些查询使用 INNER JOIN 两个或多个表。我现在遇到问题了,因为函数速度较慢,我不知道该怎么做。【参考方案2】:

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

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;

【讨论】:

嗯...不知道你的意思 你的意思是一个变量一列? 是的,如果您选择 10 列,则需要 10 个变量,但如果要返回单个值,则在选择中使用该列并使用一个变量来存储该值。 你能举个例子吗 请指定您希望从查询中返回哪些值,单列或多列,@LITTLEFOOT 已经分享了一个示例,如果需要重新计算多列,那么您必须使用参考光标。请说明您的要求。

以上是关于PL/SQL 语句被忽略的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL: SQL 语句被忽略 - 创建一个过程得到编译错误

自定义 SQL 函数 - PL/SQL:语句被忽略

第 2 行的错误:PL/SQL:语句被忽略

ORACLE:错误错误(6,3):PL/SQL:SQL 语句被忽略和错误(8,3):PL/SQL:ORA-00933:SQL 命令未在过程中正确结束

PLS-00382:表达式类型错误,PL/SQL:语句被忽略

PL/SQL:PLS-00382:表达式类型错误。语句被忽略