包“set serveroutput on”导致编译错误
Posted
技术标签:
【中文标题】包“set serveroutput on”导致编译错误【英文标题】:Package "set serveroutput on" causing compilation error 【发布时间】:2021-05-12 09:55:36 【问题描述】:我正在使用我的类包模板将两个过程收集到包中,在粘贴和格式化所有内容后,我遇到了这个错误:
这是我的包裹代码。头和身是分开的。
CREATE OR REPLACE
PACKAGE PAQEX AS
PROCEDURE EX3 (P_NOMBRE IN VARCHAR2, P_LUGAR IN VARCHAR2, P_NUMERO IN NUMBER);
PROCEDURE EX2(CPN IN VARCHAR2, NUMER OUT NUMBER );
END PAQEX;
CREATE OR REPLACE
PACKAGE BODY PAQEX AS
PROCEDURE EX3 (P_NOMBRE IN VARCHAR2, P_LUGAR IN VARCHAR2, P_NUMERO IN NUMBER) AS
--
V_AEROPUERTO NUMBER;
V_TERMINAL NUMBER;
V_ID_AEROPUERTO AEROPUERTO.ID%TYPE;
BEGIN
-----------
SELECT COUNT(*) INTO V_AEROPUERTO FROM AEROPUERTO WHERE NOMBRE = P_NOMBRE AND LUGAR = P_LUGAR;
IF V_AEROPUERTO = 0 THEN
INSERT INTO AEROPUERTO (NOMBRE, LUGAR) VALUES (P_NOMBRE, P_LUGAR);
DBMS_OUTPUT.PUT_LINE('INSERTANDO AEROPUERTO');
ELSE
DBMS_OUTPUT.PUT_LINE('YA EXISTE EL AEROPUERTO');
END IF;
SELECT ID INTO V_ID_AEROPUERTO FROM AEROPUERTO WHERE NOMBRE = P_NOMBRE AND LUGAR = P_LUGAR;
------------
SELECT COUNT(*) INTO V_TERMINAL FROM TERMINAL WHERE NUMERO = P_NUMERO AND ID_AEROPUERTO = V_ID_AEROPUERTO;
IF V_TERMINAL = 0 THEN
INSERT INTO TERMINAL (NUMERO, ID_AEROPUERTO) VALUES (P_NUMERO, V_ID_AEROPUERTO);
DBMS_OUTPUT.PUT_LINE('INSERTANDO TERMINAL');
ELSE
DBMS_OUTPUT.PUT_LINE('YA EXISTE LA TERMINAL');
END IF;
END EX3;
PROCEDURE EX2(CPN IN VARCHAR2, NUMER OUT NUMBER ) AS
CURSOR CVUELO IS
SELECT CS.NOMBRE AS COMPA,MDEL.NOMBRE AS MODELL,ASA.NOMBRE AS ORIGEN,AL.NOMBRE AS DESTINO
FROM VUELO VU
INNER JOIN AVION AVI
ON VU.ID_AVION = AVI.ID
INNER JOIN COMPAÑIA CS
ON AVI.ID_COMPAÑIA = CS.ID
INNER JOIN MODELO MDEL
ON AVI.ID_MODELO = MDEL.ID
INNER JOIN PUERTA PS
ON VU.id_puerta_salida = PS.ID
INNER JOIN PUERTA PL
ON VU.id_puerta_llegada = PL.ID
INNER JOIN TERMINAL TS
ON PS.ID_TERMINAL = TS.ID
INNER JOIN TERMINAL TL
ON PL.ID_TERMINAL = TL.ID
INNER JOIN AEROPUERTO ASA
ON TL.ID_AEROPUERTO = ASA.ID
INNER JOIN AEROPUERTO AL
ON TS.ID_AEROPUERTO = AL.ID
WHERE CPN = CS.NOMBRE;
BEGIN
NUMER:=0;
FOR RESULTADO IN CVUELO
LOOP
DBMS_OUTPUT.PUT_LINE(RESULTADO.COMPA || ' | ' || RESULTADO.MODELL ||' | ' ||RESULTADO.ORIGEN||' | ' ||RESULTADO.DESTINO);
NUMER := NUMER + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('La compañia ha volado '||numer||' veces');
END EX2;
END PAQEX;
SET SERVEROUTPUT ON;
EXECUTE PAQEX.EX2('AIRBUS',0);
EXECUTE PAQEX.EX3('ADOLFOS','MADRID',3);
我想在创建包后尝试包中的每个过程。由于该错误,它们作为独立程序工作,但不在包中。为什么不接受set serveroutput on
命令?
【问题讨论】:
如果您将所有代码作为一个脚本运行,那么您将在每个END PAQEX
之后的一行中单独缺少一个 /
- 用于规范和正文。 SET
和 EXECUTE
是客户端命令,不是包的一部分,因此请与工作表分开运行。您似乎正在使用 SQL Developer;不知道你为什么也用 PL/SQL Developer 标记?)
这个包分为body和head所以我不知道那是不是一个单独的脚本
如果您现在在包正文编辑器中 - 而不是工作表 - 并单击编译按钮以获取该错误,然后删除 SET 和 EXECUTE 命令。 (并且不要添加斜线)。一切都与上下文有关......
@AlexPoole 所以为了查看我的包的每个过程的输出,我必须同时删除执行和服务器输出?对不起,如果我听起来很愚蠢,但它是我们老师解释的一个新概念,我想,按照模板是我必须做的一切......
【参考方案1】:
有两种方法可以创建这个包;或者来自一个脚本中所有代码的工作表,在这种情况下,它应该看起来像:
CREATE OR REPLACE
PACKAGE PAQEX AS
PROCEDURE EX3 (P_NOMBRE IN VARCHAR2, P_LUGAR IN VARCHAR2, P_NUMERO IN NUMBER);
PROCEDURE EX2(CPN IN VARCHAR2, NUMER OUT NUMBER );
END PAQEX;
/
CREATE OR REPLACE
PACKAGE BODY PAQEX AS
...
END PAQEX;
/
SET SERVEROUTPUT ON;
EXECUTE PAQEX.EX2('AIRBUS',0);
EXECUTE PAQEX.EX3('ADOLFOS','MADRID',3);
在每个 PL/SQL 对象(包规范和包主体)之后有一个斜杠。
或者您可以通过“新建包...”菜单命令创建或修改包,并将规范和主体代码放入相关对象中。架构浏览器将在“包”下显示“PAQEX”,如果单击该选项卡,您将看到一个带有包图标和“PAQEX”的选项卡,其中仅包含:
CREATE OR REPLACE
PACKAGE PAQEX AS
PROCEDURE EX3 (P_NOMBRE IN VARCHAR2, P_LUGAR IN VARCHAR2, P_NUMERO IN NUMBER);
PROCEDURE EX2(CPN IN VARCHAR2, NUMER OUT NUMBER );
END PAQEX;
以及其下的“PAQEX 主体”;如果您单击它,您将看到另一个选项卡,其中包含包图标和仅包含正文代码的“PAQEX 正文”。但是您似乎已将用于测试它的代码包含在正文中:
PACKAGE BODY PAQEX AS
...
END PAQEX;
SET SERVEROUTPUT ON;
EXECUTE PAQEX.EX2('AIRBUS',0);
EXECUTE PAQEX.EX3('ADOLFOS','MADRID',3);
从您包含的错误图像中,您会收到单击编译图标(cogs)时显示的错误。
您需要将测试代码与包代码分开。从包正文选项卡中删除 SET
和 EXECUTE
行,以便:
PACKAGE BODY PAQEX AS
...
END PAQEX;
如果没有其他错误,那么应该可以编译。
然后要测试包,打开一个 SQL 工作表(右键单击连接以在上下文菜单中查看)并只输入这三个语句:
SET SERVEROUTPUT ON;
EXECUTE PAQEX.EX2('AIRBUS',0);
EXECUTE PAQEX.EX3('ADOLFOS','MADRID',3);
然后单击“作为脚本运行”或按 F5。 (如果您单击“运行为语句”或按 control-enter,则它将仅运行光标当前所在的命令。)
SQL Developer EXECUTE
命令只是一个匿名块的包装器,因此您还可以将这两个调用与:
SET SERVEROUTPUT ON;
BEGIN
PAQEX.EX2('AIRBUS',0);
PAQEX.EX3('ADOLFOS','MADRID',3);
END;
/
您还可以在查看包对象编辑器时使用“运行”图标(或按 control-F10)进行测试;它在编译(cogs)图标旁边。这使您可以从包中选择一个过程/函数并设置参数值。 从错误的图像中,您已经从对象列表中打开了包主体,它只显示了您正在单击的 boand 如果您现在在包主体编辑器中 - 而不是工作表 - 并单击编译按钮以获取该错误,然后改为删除 SET 和 EXECUTE 命令。
【讨论】:
谢谢!它只是执行 EX3 程序,但至少是一个很大的进步。我不知道我必须把它放在工作表上 你知道我的其他程序有什么问题吗?它自己工作,但不在这里:( 如果您在工作表中将这三个命令作为脚本 (F5) 而不是作为语句运行 (control-enter),那么它将执行这两个过程;脚本输出窗口将显示这一点,以及两者的输出。 现在我不知道为什么我使用 f5 得到一个未知的命令错误 :( 我也不知道。也许您选择了一个脚本片段,而它只是试图运行该片段?【参考方案2】:用斜线结束程序:
<snip>
END EX2;
END PAQEX;
/ --> this
SET SERVEROUTPUT ON;
EXECUTE PAQEX.EX2('AIRBUS',0);
【讨论】:
现在尝试,但现在错误声称:遇到符号 / 你不应该。基本上,您的所有 PL/SQL 过程都应该以斜线结尾 - 包主体、包规范、独立存储过程、匿名 PL/SQL 块、触发器……一切。因为,如果您将整个代码作为脚本运行,Oracle 将引发错误。 我使用oracle上的新打包工具创建了包,分为head和body。我读过,如果我使用脚本,这段代码不可能出错,但是我该如何解决呢? 不能评论“新打包工具”,我没用。另一方面,我已经创建包超过 25 年了,所以我想我知道如何正确创建它们。因此,做任何你认为合适的事情。以上是关于包“set serveroutput on”导致编译错误的主要内容,如果未能解决你的问题,请参考以下文章
运行pl/sql块显示结果,每次都要加set serveroutput on吗?
为啥我用eclipse 编java 引用 import net.sf.jasperreports.engine.*;包出错呢?