Oracle Packages and using a select statement in a public variable
Have been searching for ages to no avail. Part of an assessment it specifies that we must declare a public variable WITHIN a package (so don't try telling me to make it a stand alone function...) that is the number of rows from another table ("SELECT COUNT(*) FROM A2_GUESTS" is the hint)
I can set a public variable easily enough as a static number, however if i try to add the select statement it throws an error.
If I try to assign it in the package body then it also throws an error, if I wrap it within "begin" and "end" it terminates the package body too early.
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;
the above example are the ways i've been trying (amongst others), not at the same time but individually.
We get given the code to test it: (must not change this testing code)
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;
any help is greatly appreciated, i found someone asked this here once back in 2015 but the only answer was given as make it a function and they adjusted the testing code so thats less than helpful.
there is more code within the package with procedures and functions:
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;
this will throw:
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.
im normally alright with working it out from the error messages but oracle error messages may as well be written in dutch to me :/
oracle plsql package
add a comment |
Have been searching for ages to no avail. Part of an assessment it specifies that we must declare a public variable WITHIN a package (so don't try telling me to make it a stand alone function...) that is the number of rows from another table ("SELECT COUNT(*) FROM A2_GUESTS" is the hint)
I can set a public variable easily enough as a static number, however if i try to add the select statement it throws an error.
If I try to assign it in the package body then it also throws an error, if I wrap it within "begin" and "end" it terminates the package body too early.
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;
the above example are the ways i've been trying (amongst others), not at the same time but individually.
We get given the code to test it: (must not change this testing code)
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;
any help is greatly appreciated, i found someone asked this here once back in 2015 but the only answer was given as make it a function and they adjusted the testing code so thats less than helpful.
there is more code within the package with procedures and functions:
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;
this will throw:
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.
im normally alright with working it out from the error messages but oracle error messages may as well be written in dutch to me :/
oracle plsql package
add a comment |
Have been searching for ages to no avail. Part of an assessment it specifies that we must declare a public variable WITHIN a package (so don't try telling me to make it a stand alone function...) that is the number of rows from another table ("SELECT COUNT(*) FROM A2_GUESTS" is the hint)
I can set a public variable easily enough as a static number, however if i try to add the select statement it throws an error.
If I try to assign it in the package body then it also throws an error, if I wrap it within "begin" and "end" it terminates the package body too early.
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;
the above example are the ways i've been trying (amongst others), not at the same time but individually.
We get given the code to test it: (must not change this testing code)
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;
any help is greatly appreciated, i found someone asked this here once back in 2015 but the only answer was given as make it a function and they adjusted the testing code so thats less than helpful.
there is more code within the package with procedures and functions:
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;
this will throw:
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.
im normally alright with working it out from the error messages but oracle error messages may as well be written in dutch to me :/
oracle plsql package
Have been searching for ages to no avail. Part of an assessment it specifies that we must declare a public variable WITHIN a package (so don't try telling me to make it a stand alone function...) that is the number of rows from another table ("SELECT COUNT(*) FROM A2_GUESTS" is the hint)
I can set a public variable easily enough as a static number, however if i try to add the select statement it throws an error.
If I try to assign it in the package body then it also throws an error, if I wrap it within "begin" and "end" it terminates the package body too early.
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;
the above example are the ways i've been trying (amongst others), not at the same time but individually.
We get given the code to test it: (must not change this testing code)
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;
any help is greatly appreciated, i found someone asked this here once back in 2015 but the only answer was given as make it a function and they adjusted the testing code so thats less than helpful.
there is more code within the package with procedures and functions:
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;
this will throw:
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.
im normally alright with working it out from the error messages but oracle error messages may as well be written in dutch to me :/
oracle plsql package
oracle plsql package
edited Nov 12 '18 at 6:06
Craig B
asked Nov 12 '18 at 4:56
Craig BCraig B
422311
422311
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
We can include initialising code in a package by putting it at the end of the body. It takes the form of a BEGIN block which is terminated by the final END of the package body.
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;
/
The code under the label << init_block >>
is run the first time the package is invoked. This includes referencing the public variable. This code not run again in the session, unless the package is recompiled, which discards state.
Here is my test script. I have published this as a working demo on Oracle LiveSQL (because DBMS_OUTPUT) but you need a free Oracle account to run it. Check it out
Test set up
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;
/
Here are the tests;
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
/
That's better +1. But, without an invocation toBEACHCOMBER.v_Guest_Count
orBEACHCOMBER.get_cnt
, there's no other way to have it "automatically initialised" as OP is referring to.Looks like the teacher just worded it wrongly
– Kaushik Nayak
Nov 12 '18 at 9:45
Thanks APC, figured it out last night by sheer luck that I tried it, but this was exactly what I did, moving the begin and select into at the bottom was the fix. many thanks
– Craig B
Nov 12 '18 at 21:34
add a comment |
You have to set the Package variable in the package body. You need not declare another variable locally in the body.
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
BEGIN
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS;
END Beachcomber;
/
You may then access that variable in any other PL/SQL block.
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(Beachcomber.v_Guest_Count);
end;
/
0
PL/SQL procedure successfully completed.
EDIT
You should put the queries inside the procedure as you would be calling the procedure externally.
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 : using a main procedure for initialisation.
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;
/
Execution of procedure.
BEGIN
beachcomber.main;
beachcomber.add_guest('Sherlock','221b baker street');
END;
/
theres other procedures in the package, it reports an error on them if I do what you've done.
– Craig B
Nov 12 '18 at 5:55
LINE/COL ERROR --------- ------------------------------------------------------------- 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.
– Craig B
Nov 12 '18 at 5:58
@CraigB : I don't know what they are so can't help you on that. You'll have to debug that.This question answers your original question and the errors are not directly related. If you think it helped you please accept it. Ask a new question if you have further problems.
– Kaushik Nayak
Nov 12 '18 at 5:58
kaushik this answer is all well and good IF there is nothing else in the package, the rest of the stuff works perfectly fine in the package when I comment out the bits for the count, it just spits the above error whenever it sees anything AFTER the above and before the end, (if that makes sense)
– Craig B
Nov 12 '18 at 6:03
see edits above
– Craig B
Nov 12 '18 at 6:07
|
show 5 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53256160%2foracle-packages-and-using-a-select-statement-in-a-public-variable%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
We can include initialising code in a package by putting it at the end of the body. It takes the form of a BEGIN block which is terminated by the final END of the package body.
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;
/
The code under the label << init_block >>
is run the first time the package is invoked. This includes referencing the public variable. This code not run again in the session, unless the package is recompiled, which discards state.
Here is my test script. I have published this as a working demo on Oracle LiveSQL (because DBMS_OUTPUT) but you need a free Oracle account to run it. Check it out
Test set up
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;
/
Here are the tests;
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
/
That's better +1. But, without an invocation toBEACHCOMBER.v_Guest_Count
orBEACHCOMBER.get_cnt
, there's no other way to have it "automatically initialised" as OP is referring to.Looks like the teacher just worded it wrongly
– Kaushik Nayak
Nov 12 '18 at 9:45
Thanks APC, figured it out last night by sheer luck that I tried it, but this was exactly what I did, moving the begin and select into at the bottom was the fix. many thanks
– Craig B
Nov 12 '18 at 21:34
add a comment |
We can include initialising code in a package by putting it at the end of the body. It takes the form of a BEGIN block which is terminated by the final END of the package body.
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;
/
The code under the label << init_block >>
is run the first time the package is invoked. This includes referencing the public variable. This code not run again in the session, unless the package is recompiled, which discards state.
Here is my test script. I have published this as a working demo on Oracle LiveSQL (because DBMS_OUTPUT) but you need a free Oracle account to run it. Check it out
Test set up
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;
/
Here are the tests;
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
/
That's better +1. But, without an invocation toBEACHCOMBER.v_Guest_Count
orBEACHCOMBER.get_cnt
, there's no other way to have it "automatically initialised" as OP is referring to.Looks like the teacher just worded it wrongly
– Kaushik Nayak
Nov 12 '18 at 9:45
Thanks APC, figured it out last night by sheer luck that I tried it, but this was exactly what I did, moving the begin and select into at the bottom was the fix. many thanks
– Craig B
Nov 12 '18 at 21:34
add a comment |
We can include initialising code in a package by putting it at the end of the body. It takes the form of a BEGIN block which is terminated by the final END of the package body.
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;
/
The code under the label << init_block >>
is run the first time the package is invoked. This includes referencing the public variable. This code not run again in the session, unless the package is recompiled, which discards state.
Here is my test script. I have published this as a working demo on Oracle LiveSQL (because DBMS_OUTPUT) but you need a free Oracle account to run it. Check it out
Test set up
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;
/
Here are the tests;
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
/
We can include initialising code in a package by putting it at the end of the body. It takes the form of a BEGIN block which is terminated by the final END of the package body.
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;
/
The code under the label << init_block >>
is run the first time the package is invoked. This includes referencing the public variable. This code not run again in the session, unless the package is recompiled, which discards state.
Here is my test script. I have published this as a working demo on Oracle LiveSQL (because DBMS_OUTPUT) but you need a free Oracle account to run it. Check it out
Test set up
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;
/
Here are the tests;
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
/
edited Nov 12 '18 at 8:25
answered Nov 12 '18 at 8:20
APCAPC
119k15118229
119k15118229
That's better +1. But, without an invocation toBEACHCOMBER.v_Guest_Count
orBEACHCOMBER.get_cnt
, there's no other way to have it "automatically initialised" as OP is referring to.Looks like the teacher just worded it wrongly
– Kaushik Nayak
Nov 12 '18 at 9:45
Thanks APC, figured it out last night by sheer luck that I tried it, but this was exactly what I did, moving the begin and select into at the bottom was the fix. many thanks
– Craig B
Nov 12 '18 at 21:34
add a comment |
That's better +1. But, without an invocation toBEACHCOMBER.v_Guest_Count
orBEACHCOMBER.get_cnt
, there's no other way to have it "automatically initialised" as OP is referring to.Looks like the teacher just worded it wrongly
– Kaushik Nayak
Nov 12 '18 at 9:45
Thanks APC, figured it out last night by sheer luck that I tried it, but this was exactly what I did, moving the begin and select into at the bottom was the fix. many thanks
– Craig B
Nov 12 '18 at 21:34
That's better +1. But, without an invocation to
BEACHCOMBER.v_Guest_Count
or BEACHCOMBER.get_cnt
, there's no other way to have it "automatically initialised" as OP is referring to.Looks like the teacher just worded it wrongly– Kaushik Nayak
Nov 12 '18 at 9:45
That's better +1. But, without an invocation to
BEACHCOMBER.v_Guest_Count
or BEACHCOMBER.get_cnt
, there's no other way to have it "automatically initialised" as OP is referring to.Looks like the teacher just worded it wrongly– Kaushik Nayak
Nov 12 '18 at 9:45
Thanks APC, figured it out last night by sheer luck that I tried it, but this was exactly what I did, moving the begin and select into at the bottom was the fix. many thanks
– Craig B
Nov 12 '18 at 21:34
Thanks APC, figured it out last night by sheer luck that I tried it, but this was exactly what I did, moving the begin and select into at the bottom was the fix. many thanks
– Craig B
Nov 12 '18 at 21:34
add a comment |
You have to set the Package variable in the package body. You need not declare another variable locally in the body.
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
BEGIN
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS;
END Beachcomber;
/
You may then access that variable in any other PL/SQL block.
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(Beachcomber.v_Guest_Count);
end;
/
0
PL/SQL procedure successfully completed.
EDIT
You should put the queries inside the procedure as you would be calling the procedure externally.
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 : using a main procedure for initialisation.
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;
/
Execution of procedure.
BEGIN
beachcomber.main;
beachcomber.add_guest('Sherlock','221b baker street');
END;
/
theres other procedures in the package, it reports an error on them if I do what you've done.
– Craig B
Nov 12 '18 at 5:55
LINE/COL ERROR --------- ------------------------------------------------------------- 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.
– Craig B
Nov 12 '18 at 5:58
@CraigB : I don't know what they are so can't help you on that. You'll have to debug that.This question answers your original question and the errors are not directly related. If you think it helped you please accept it. Ask a new question if you have further problems.
– Kaushik Nayak
Nov 12 '18 at 5:58
kaushik this answer is all well and good IF there is nothing else in the package, the rest of the stuff works perfectly fine in the package when I comment out the bits for the count, it just spits the above error whenever it sees anything AFTER the above and before the end, (if that makes sense)
– Craig B
Nov 12 '18 at 6:03
see edits above
– Craig B
Nov 12 '18 at 6:07
|
show 5 more comments
You have to set the Package variable in the package body. You need not declare another variable locally in the body.
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
BEGIN
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS;
END Beachcomber;
/
You may then access that variable in any other PL/SQL block.
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(Beachcomber.v_Guest_Count);
end;
/
0
PL/SQL procedure successfully completed.
EDIT
You should put the queries inside the procedure as you would be calling the procedure externally.
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 : using a main procedure for initialisation.
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;
/
Execution of procedure.
BEGIN
beachcomber.main;
beachcomber.add_guest('Sherlock','221b baker street');
END;
/
theres other procedures in the package, it reports an error on them if I do what you've done.
– Craig B
Nov 12 '18 at 5:55
LINE/COL ERROR --------- ------------------------------------------------------------- 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.
– Craig B
Nov 12 '18 at 5:58
@CraigB : I don't know what they are so can't help you on that. You'll have to debug that.This question answers your original question and the errors are not directly related. If you think it helped you please accept it. Ask a new question if you have further problems.
– Kaushik Nayak
Nov 12 '18 at 5:58
kaushik this answer is all well and good IF there is nothing else in the package, the rest of the stuff works perfectly fine in the package when I comment out the bits for the count, it just spits the above error whenever it sees anything AFTER the above and before the end, (if that makes sense)
– Craig B
Nov 12 '18 at 6:03
see edits above
– Craig B
Nov 12 '18 at 6:07
|
show 5 more comments
You have to set the Package variable in the package body. You need not declare another variable locally in the body.
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
BEGIN
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS;
END Beachcomber;
/
You may then access that variable in any other PL/SQL block.
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(Beachcomber.v_Guest_Count);
end;
/
0
PL/SQL procedure successfully completed.
EDIT
You should put the queries inside the procedure as you would be calling the procedure externally.
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 : using a main procedure for initialisation.
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;
/
Execution of procedure.
BEGIN
beachcomber.main;
beachcomber.add_guest('Sherlock','221b baker street');
END;
/
You have to set the Package variable in the package body. You need not declare another variable locally in the body.
CREATE OR REPLACE PACKAGE BODY Beachcomber IS
BEGIN
SELECT COUNT(*) INTO v_Guest_Count FROM A2_GUESTS;
END Beachcomber;
/
You may then access that variable in any other PL/SQL block.
SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(Beachcomber.v_Guest_Count);
end;
/
0
PL/SQL procedure successfully completed.
EDIT
You should put the queries inside the procedure as you would be calling the procedure externally.
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 : using a main procedure for initialisation.
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;
/
Execution of procedure.
BEGIN
beachcomber.main;
beachcomber.add_guest('Sherlock','221b baker street');
END;
/
edited Nov 12 '18 at 7:21
answered Nov 12 '18 at 5:44
Kaushik NayakKaushik Nayak
19.2k41331
19.2k41331
theres other procedures in the package, it reports an error on them if I do what you've done.
– Craig B
Nov 12 '18 at 5:55
LINE/COL ERROR --------- ------------------------------------------------------------- 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.
– Craig B
Nov 12 '18 at 5:58
@CraigB : I don't know what they are so can't help you on that. You'll have to debug that.This question answers your original question and the errors are not directly related. If you think it helped you please accept it. Ask a new question if you have further problems.
– Kaushik Nayak
Nov 12 '18 at 5:58
kaushik this answer is all well and good IF there is nothing else in the package, the rest of the stuff works perfectly fine in the package when I comment out the bits for the count, it just spits the above error whenever it sees anything AFTER the above and before the end, (if that makes sense)
– Craig B
Nov 12 '18 at 6:03
see edits above
– Craig B
Nov 12 '18 at 6:07
|
show 5 more comments
theres other procedures in the package, it reports an error on them if I do what you've done.
– Craig B
Nov 12 '18 at 5:55
LINE/COL ERROR --------- ------------------------------------------------------------- 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.
– Craig B
Nov 12 '18 at 5:58
@CraigB : I don't know what they are so can't help you on that. You'll have to debug that.This question answers your original question and the errors are not directly related. If you think it helped you please accept it. Ask a new question if you have further problems.
– Kaushik Nayak
Nov 12 '18 at 5:58
kaushik this answer is all well and good IF there is nothing else in the package, the rest of the stuff works perfectly fine in the package when I comment out the bits for the count, it just spits the above error whenever it sees anything AFTER the above and before the end, (if that makes sense)
– Craig B
Nov 12 '18 at 6:03
see edits above
– Craig B
Nov 12 '18 at 6:07
theres other procedures in the package, it reports an error on them if I do what you've done.
– Craig B
Nov 12 '18 at 5:55
theres other procedures in the package, it reports an error on them if I do what you've done.
– Craig B
Nov 12 '18 at 5:55
LINE/COL ERROR --------- ------------------------------------------------------------- 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.
– Craig B
Nov 12 '18 at 5:58
LINE/COL ERROR --------- ------------------------------------------------------------- 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.
– Craig B
Nov 12 '18 at 5:58
@CraigB : I don't know what they are so can't help you on that. You'll have to debug that.This question answers your original question and the errors are not directly related. If you think it helped you please accept it. Ask a new question if you have further problems.
– Kaushik Nayak
Nov 12 '18 at 5:58
@CraigB : I don't know what they are so can't help you on that. You'll have to debug that.This question answers your original question and the errors are not directly related. If you think it helped you please accept it. Ask a new question if you have further problems.
– Kaushik Nayak
Nov 12 '18 at 5:58
kaushik this answer is all well and good IF there is nothing else in the package, the rest of the stuff works perfectly fine in the package when I comment out the bits for the count, it just spits the above error whenever it sees anything AFTER the above and before the end, (if that makes sense)
– Craig B
Nov 12 '18 at 6:03
kaushik this answer is all well and good IF there is nothing else in the package, the rest of the stuff works perfectly fine in the package when I comment out the bits for the count, it just spits the above error whenever it sees anything AFTER the above and before the end, (if that makes sense)
– Craig B
Nov 12 '18 at 6:03
see edits above
– Craig B
Nov 12 '18 at 6:07
see edits above
– Craig B
Nov 12 '18 at 6:07
|
show 5 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53256160%2foracle-packages-and-using-a-select-statement-in-a-public-variable%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown