【问题标题】:Line/Col: 2/10 PLS-00103: Encountered the symbol "JOBS_PKG" when expecting one of the following:行/列:2/10 PLS-00103:在预期以下情况之一时遇到符号“JOBS_PKG”:
【发布时间】:2021-10-25 22:52:56
【问题描述】:

我有这个包规格和正文:

CREATE OR REPLACE PACKAGE jobs_pkg
IS
    PROCEDURE initialize;
    
    FUNCTION get_minsalary(p_jobid VARCHAR2) RETURN NUMBER;
    
    FUNCTION get_maxsalary(p_jobid VARCHAR2) RETURN NUMBER;
    
    PROCEDURE set_minsalary(p_jobid VARCHAR2, pmin_salary NUMBER);
    
    PROCEDURE set_maxsalary(p_jobid VARCHAR2, pmax_salary NUMBER);
    
END jobs_pkg;

------------------------------------------------------------------------------
CREATE OR REPLACE PACKAGE BODY jobs_pkg
IS

    TYPE jobs_tab_type IS TABLE OF jobs%rowtype INDEX BY jobs.job_id%type;
    jobstab jobs_tab_type;

    PROCEDURE initialize
    IS
    BEGIN
        FOR rec IN (SELECT * FROM jobs)
        LOOP
            jobstab(rec.job_id) := rec;
        END LOOP;
    END;
    
    FUNCTION get_minsalary(p_jobid VARCHAR2) 
    RETURN NUMBER
    IS
        vmin_salary jobs.min_salary%type;
    BEGIN
        SELECT min_salary
        INTO vmin_salary
        FROM jobs
        WHERE job_id = jobstab(p_jobid).job_id;
        
        RETURN vmin_salary;
    END get_minsalary;
    
    FUNCTION get_maxsalary(p_jobid VARCHAR2) 
    RETURN NUMBER
    IS  vmax_salary jobs.max_salary%type;
    BEGIN
        SELECT max_salary
        INTO vmax_salary
        FROM jobs
        WHERE job_id =  jobstab(p_jobid).job_id;
        
        RETURN vmax_salary;
    END get_maxsalary;
    
    PROCEDURE set_minsalary(p_jobid VARCHAR2, pmin_salary NUMBER)
    IS
    BEGIN
        UPDATE jobs
        SET min_salary = pmin_salary
        WHERE job_id = jobstab(p_jobid).job_id;
    END set_minsalary;
    
    PROCEDURE set_maxsalary(p_jobid VARCHAR2, pmax_salary NUMBER)
    IS
    BEGIN
        UPDATE jobs
        SET max_salary = pmax_salary
        WHERE job_id = jobstab(p_jobid).job_id;
    END set_maxsalary;
    
END jobs_pkg;

问题是我需要实现一个 before insert 或 update 语句触发器,它使用调用语法来调用 jobs_pkg.initialize 过程,以确保在执行 DML 操作之前打包状态是当前的,但我遇到了这个当我尝试编译我的触发器时出现问题:Line/Col: 2/10 PLS-00103: Encountered the symbol "JOBS_PKG"

这是我的触发器:

CREATE OR REPLACE TRIGGER init_jobpkg_trg
BEFORE UPDATE OR INSERT ON jobs
FOR EACH ROW
BEGIN
    CALL jobs_pkg.initialize;
END init_jobpkg_trg;

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 这样做的目的是什么?为什么每次更新或插入表时都要将整个作业表加载到数组中?看起来真的可以在视图中实现最低/最高工资逻辑,这样你根本不需要触发器。

标签: plsql


【解决方案1】:

要从另一个 pl/sql 块(过程/函数/触发器/匿名块)中调用过程,您不需要 EXECCALL 关键字。只是“package.procedure;”会的。

CREATE OR REPLACE TRIGGER init_jobpkg_trg
BEFORE UPDATE OR INSERT ON jobs
FOR EACH ROW
BEGIN
    jobs_pkg.initialize;
END init_jobpkg_trg;

请注意,您很可能会遇到其他问题。更新表时,触发器处于打开状态,您可能会遇到MUTATING TABLE 错误,因为您进入了无限循环。因为当您在更新时更新表时,该更新将触发触发器......等等。

【讨论】:

    【解决方案2】:

    CALL 不是公认的 PL/SQL 命令。相反,要调用一个过程,您只需按名称引用它。这意味着,本质上,您只需要删除 CALL,如下所示:

    CREATE OR REPLACE TRIGGER init_jobpkg_trg
    BEFORE UPDATE OR INSERT ON jobs
    FOR EACH ROW
    BEGIN
      jobs_pkg.initialize;
    END init_jobpkg_trg;
    /
    

    注意您会注意到我在 PL/SQL 的末尾添加了一个“/”——尽管某些(大多数?)GUI(如 Toad 或 PL/SQL Developer)不需要此字符,但最好始终在后面添加它PL/SQL 块,因为 SQL*Plus 需要它,并且它的缺失会在运行脚本时导致问题。您也应该在 CREATE OR REPLACE package [body] ... 块之后添加一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 2014-09-18
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多