一直在搜寻年龄无济于事。在评估的一部分中,它指定我们必须在一个包内声明一个公共变量(因此,请勿尝试告诉我使其成为一个独立的函数...),即来自另一个表的行数(“ SELECT COUNT(* )FROM A2_GUESTS“是提示)
我可以很容易地将公共变量设置为静态数字,但是,如果我尝试添加select语句,则会引发错误。
如果我尝试在程序包主体中分配它,那么它也会引发错误,如果我将其包装在“ begin”和“ end”中,则它会太早终止程序包主体。
CREATE OR REPLACE PACKAGE Beachcomber
AS
v_Guest_Count NUMBER := 0;
END Beachcomber;
/
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS; -- doesn't work
v_Guest_Count NUMBER := SELECT COUNT(*) FROM A2_GUESTS; -- doesn't work
BEGIN
v_Guest_Count NUMBER := SELECT COUNT(*) FROM A2_GUESTS;
END; -- doesn't work - ends the package prematurely
END Beachcomber;
以上示例是我一直在尝试的方法(以及其他方法),而不是同时进行,而是逐一进行。
我们得到了对其进行测试的代码:(一定不要更改此测试代码)
PROMPT
PROMPT TESTING: Initialisation of the v_Guest_Count variable. Expect 81.
BEGIN
DBMS_OUTPUT.PUT_LINE('v_Guest_Count has been initialised to: '||TO_CHAR(BEACHCOMBER.v_Guest_Count));
END;
非常感谢任何帮助,我发现有人在2015年曾在这里提出过此问题,但唯一的答案是使它具有功能性,因此他们调整了测试代码,因此无济于事。
软件包中包含更多具有过程和功能的代码:
CREATE OR REPLACE PACKAGE Beachcomber
IS
v_Guest_Count NUMBER := 0;
PROCEDURE ADD_GUEST
(p_guest_name A2_GUESTS.guest_name%TYPE,
p_guest_address A2_GUESTS.guest_address%TYPE);
END Beachcomber;
/
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
BEGIN
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS;
PROCEDURE ADD_GUEST
(p_guest_name A2_GUESTS.guest_name%TYPE,
p_guest_address A2_GUESTS.guest_address%TYPE)
IS BEGIN
INSERT INTO A2_GUESTS (Guest_ID, Guest_Name, Guest_Address)
VALUES (guest_id_seq.NEXTVAL, p_guest_name, p_guest_address);
v_Guest_Count := v_Guest_Count +1;
END ADD_GUEST;
END Beachcomber;
这将抛出:
5/5 PLS-00103: Encountered the symbol "PROCEDURE" when expecting one of the following: ( begin case declare end exception exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge The symbol "declare" was substituted for "PROCEDURE" to continue.
我通常可以从错误消息中解决它,但是oracle错误消息也可以用荷兰语写给我:/
答案 0 :(得分:2)
我们可以通过将代码放在正文末尾来将初始化代码包含在包中。它采用BEGIN块的形式,并以程序包主体的最后一个END终止。
create or replace package BEACHCOMBER is
v_Guest_Count pls_integer;
function get_cnt return number;
end BEACHCOMBER;
/
create or replace package body BEACHCOMBER is
function get_cnt return number
is
begin
return v_Guest_Count;
end get_cnt;
<< init_block >>
begin
select count(*)
into v_Guest_Count
from A2_GUESTS;
end BEACHCOMBER;
/
标签<< init_block >>
下的代码在第一次调用该程序包时运行。这包括引用公共变量。除非重新编译软件包,否则该代码不会在会话中再次运行,这会丢弃状态。
这是我的测试脚本。我已经将此版本发布为Oracle LiveSQL上的有效演示(因为DBMS_OUTPUT),但是您需要一个免费 Oracle帐户来运行它。 Check it out
测试设置
drop table A2_GUESTS
/
create table A2_GUESTS (id number);
insert into A2_GUESTS select level from dual connect by level <=23;
create or replace package BEACHCOMBER is
v_Guest_Count pls_integer;
function get_cnt return number;
end BEACHCOMBER;
/
create or replace package body BEACHCOMBER is
function get_cnt return number
is
begin
return v_Guest_Count;
end get_cnt;
begin
select count(*)
into v_Guest_Count
from A2_GUESTS;
end BEACHCOMBER;
/
这是测试;
begin
dbms_output.put_line('count = ' || BEACHCOMBER.v_Guest_Count);
end;
/
insert into A2_GUESTS values (42)
/
select BEACHCOMBER.get_cnt
from dual
/
alter package BEACHCOMBER compile body
/
select BEACHCOMBER.get_cnt
from dual
/
答案 1 :(得分:1)
您必须在包主体中设置Package变量。您无需在主体中局部声明另一个变量。
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
BEGIN
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS;
END Beachcomber;
/
然后您可以在任何其他PL / SQL块中访问该变量。
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(Beachcomber.v_Guest_Count);
end;
/
0
PL/SQL procedure successfully completed.
编辑
您应该像在外部调用过程一样将查询放入过程中。
CREATE OR REPLACE PACKAGE BODY beachcomber IS
PROCEDURE add_guest (
p_guest_name a2_guests.guest_name%TYPE,
p_guest_address a2_guests.guest_address%TYPE
)
IS
BEGIN
SELECT COUNT(*)
INTO v_guest_count
FROM a2_guests;
INSERT INTO a2_guests (
guest_id,
guest_name,
guest_address
) VALUES (
guest_id_seq.NEXTVAL,
p_guest_name,
p_guest_address
);
v_guest_count := v_guest_count + 1;
END add_guest;
END beachcomber;
/
EDIT2 :使用主要过程进行初始化。
CREATE OR REPLACE PACKAGE beachcomber IS
v_guest_count NUMBER := 0;
PROCEDURE main;
PROCEDURE add_guest (
p_guest_name a2_guests.guest_name%TYPE,
p_guest_address a2_guests.guest_address%TYPE
);
END beachcomber;
/
CREATE OR REPLACE PACKAGE BODY beachcomber IS
PROCEDURE add_guest (
p_guest_name a2_guests.guest_name%TYPE,
p_guest_address a2_guests.guest_address%TYPE
)
IS
BEGIN
INSERT INTO a2_guests (
guest_id,
guest_name,
guest_address
) VALUES (
guest_id_seq.NEXTVAL,
p_guest_name,
p_guest_address
);
v_guest_count := v_guest_count + 1;
END add_guest;
PROCEDURE main
IS
BEGIN
SELECT COUNT(*)
INTO v_guest_count
FROM a2_guests;
END main;
END beachcomber;
/
执行程序。
BEGIN
beachcomber.main;
beachcomber.add_guest('Sherlock','221b baker street');
END;
/