How to call the procedure and function from the package?
PROCEDURE P_INSERT_PER_LG(IN_DATA DATE,
IN_CHECK VARCHAR2,
IN_PSE VARCHAR2,
IN_TP_CHECK VARCHAR2,
IN_STATUS NUMBER,
IN_MSG VARCHAR2,
OUT_ERR_MSG OUT VARCHAR2);
FUNCTION F_GT_COD_PTH(IN_CODE IN VARCHAR2)RETURN C_GT_COD_OBJ;
A small sample package:
CREATE OR REPLACE
PACKAGE TEST_PKG AS
FUNCTION Get_Squere(p_num NUMBER) RETURN NUMBER;
PROCEDURE Put_Line(p_Text VARCHAR2);
END TEST_PKG;
-- .. and package body
CREATE OR REPLACE
PACKAGE BODY TEST_PKG AS
FUNCTION Get_Squere(p_num NUMBER) RETURN NUMBER AS
BEGIN
RETURN p_num * p_num;
END Get_Squere;
PROCEDURE Put_Line(p_Text VARCHAR2) AS
BEGIN
DBMS_OUTPUT.PUT_LINE(p_Text);
END Put_Line;
END TEST_PKG;
And plsql block calling procedure/function from the package
SET SERVEROUTPUT ON
DECLARE
m_number NUMBER(9);
m_text VARCHAR2(100) := 'Test - printed out by packaged Procedure...';
BEGIN
TEST_PKG.Put_Line(m_text); -- calling pacakaged procedure
m_number := TEST_PKG.Get_Squere(5); -- calling pakaged function
TEST_PKG.Put_Line(m_number || ' squered is ' || TEST_PKG.Get_Squere(m_number)); -- calling procedure with the value returned by function
END;
/
Result:
anonymous block completed
Test - printed out by packaged Procedure...
25 squered is 625
Related
I have the following procedure for merging 10 varchar variables of length 4000 characters into one CLOB:
procedure insert_iec_by_parts(p_header_id in number,
p_contents_part1 in varchar2,
p_contents_part2 in varchar2,
p_contents_part3 in varchar2,
p_contents_part4 in varchar2,
p_contents_part5 in varchar2,
p_contents_part6 in varchar2,
p_contents_part7 in varchar2,
p_contents_part8 in varchar2,
p_contents_part9 in varchar2,
p_contents_part10 in varchar2,
o_cur_results out sys_refcursor,
result_code out number) is
l_clob clob;
begin
l_clob:=p_contents_part1||p_contents_part2||p_contents_part3||p_contents_part4||p_contents_part5||
p_contents_part6||p_contents_part7||p_contents_part8||p_contents_part9||p_contents_part10;
insert_iec(p_header_id, l_clob, o_cur_results, result_code );
end;
procedure insert_iec(p_header_id in number,
p_contents in clob,
o_cur_results out sys_refcursor,
result_code out number) is
id_temp number;
l_id number;
procedure SetError(pErrCode number) is
-- A centralised sub proc could allow for a quick change to raise_application_error at any time.
begin
result_code := pErrCode;
end;
begin
select count(*) into l_id from log_sync_calls_headers
where log_sync_calls_headers.id =p_header_id;
case
when (p_header_id is null) or (l_id <= 0) then SetError(9804);
when p_contents is null then SetError(9805);
else
-- fetch sequence number
id_temp := iec_seq.nextval;
result_code:=0;
open o_cur_results for
select id_temp as id
from dual;
insert into log_sync_calls_iecs
(id, header_id, contents)
values
(id_temp, p_header_id, p_contents );
commit;
end case;
exception when others then
result_code :=9701;
rollback;
pkg_common.insert_log_record(p_source => 'insert_iec',
p_type => 'Er',
p_message => sqlerrm);
end;
Procedure works fine when merging 10 varchar variables of 4000 characters each. However, I want to extend it to 20 varchar variables of length 4000 characters.
When I try that, it gives me the following error:
ORA 06502: character string buffer too small.
Could someone show me how to be able to extend this procedure to 20 varchar variables of length 4000 characters?
Use DBMS_LOB.APPEND function like in this question (or just search for DBMS_LOB.APPEND in SO): how to insert long string oracle clob or blob
you should use the DBMS_LOB package.
first you should create a clob object otherwise you variable is not initialized
dbms_lob.createtemporary(l_clob ,true);
now you can use append procedure
dbms_lob.append(l_clob, p_contents_part1 );
after you are finished , don't forget to release a clob Memory and destroy you clob object
dbms_lob.freetemporary(l_clob);
I am trying to Insert a line into a table using PLSQL. The table name is DOCUMENT_ISSUE_HISTORY. I am using an API Procedure name PROCEDURE
Insert_New_Line_ (
doc_class_ IN VARCHAR2,
doc_no_ IN VARCHAR2,
doc_sheet_ IN VARCHAR2,
doc_rev_ IN VARCHAR2,
info_category_db_ IN VARCHAR2,
note_ IN VARCHAR2 );
I am confused if PRECEDURE can return value like function does.
I am doing this:
DECLARE
doc_class_ varchar2(4000) := 'CVS FILE';
doc_no_ varchar2(4000) := '01004901.DWG-DWF';
doc_sheet_ varchar2(20) := 1;
doc_rev_ varchar2(20) := -1;
info_category_db_ VARCHAR2(20) := NULL;
note_ VARCHAR2(4000) := 'TEXTING TO UPDATE or FIeld to update';
BEGIN
Document_Issue_History_API.Insert_New_Line__ (doc_class_ ,doc_no_,doc_sheet_,doc_rev_ ,info_category_db_,note_);
end;
How can I can insert the line in the table?
Functions have return values and hence may appear anywhere an expression may be used (such as to the right of the assignment operator, or as a column expression in a SQL statement) while Procedures do not have return values and may not be used as expressions.
This is not to say that procedures can't return values, because they can as long as they are OUT or IN/OUT parameters. You just can't use the procedure directly in an expression.
Similarly since Functions do have a return value (other than those parameters specified as OUT or IN/OUT parameters) they must be used in an expression and can't be called directly.
I have a use case where a package has 2 procedure with the same name and argument, one as CHAR type and another is VARCHAR2 type.
How to call tham?
For PL/SQL the package spec and body compiles ok.
But at runtime the 2 procedures are the same and there is no way to distinguish because CHAR type and VARCHAR2 type are of the same datatype family.
For example:
create or replace package pk_over
is
procedure pr_text(p_isbCaracter char);
procedure pr_text(p_isbCaracter varchar2);
End;
create or replace package body pk_over
is
procedure pr_text(p_isbCaracter char)
is
Begin
Dbms_Output.Put_Line('Soy PR_TEXT parĂ¡metro CHAR="'||p_isbCaracter||chr(34));
End pr_text;
--
procedure pr_text(p_isbCaracter varchar2)
is
Begin
Dbms_Output.Put_Line('Soy PR_TEXT parĂ¡metro VARCHAR2="'||p_isbCaracter||chr(34));
End pr_text;
--
End pk_over;
An you call with:
Declare
sbVar2 varchar2(20);
Begin
sbVar2:='Texto 1';
pk_over.pr_text(sbVar2);
End;
The error at runtime is:
PLS-00307: too many declarations of 'PR_TEXT' match this call
So you don't need the 2 procedures, only one.
Package:
create or replace package manage_emps
is
tax_rate constant number(5,2) := .28;
v_id number;
procedure insert_emp(p_deptno number,p_sal number);
procedure delete_emp;
procedure update_emp;
function calc_tax(p_sal number) return number;
end;
Package body:
create or replace package body manage_emps
is
procedure update_sal(p_raise_amt number)
is
begin
update emp
set sal = (sal * p_raise_amt) + sal;
where empno = v_id;
end;
procedure insert_emp(p_deptno number,p_sal number)
is
begin
insert into emp(empno,deptno,sal)
values(v_id,p_deptno,p_sal);
end;
procedure delete_emp
is
begin
delete from emp
where empno = v_id;
end;
procedure update_emp
is
begin
v_sal number(10,2);
v_raise number(10,2);
select sal into v_sal
from emp
where empno = v_id;
if v_sal < 500 then
v_raise := .05;
elsif v_sal < 1000 then
v_raise := .07;
else
v_raise := .04;
end if;
update_sal(v_raise);
end;
function calc_tax(p_sal number) return number
is
begin
return p_sal * tax_rate;
end;
end;
The question is "How many public procedures are in MANAGE_EMPS package ?"
I answered "three". How can it be wrong ? Clearly 3 functions are mentioned in package specification. That procedure whose declaration/body is in package's body, then its private. Here in body, procedure UPDATE_SAL is private. But the correct answer is: "none". NO public procedures ? How ?
The correct answer is three. There are three public procedures in the package.
Note:
The package design could be improved. v_id should be a parameter and not a global variable.
I am not sure how to set variables in a stored procedure which calls another stored procedure. I want to save the value returned and use it later in another select.
I want to do something like this:
PROCEDURE procName(bcur OUT IssCur)
IS
cur2 IssCur;
extCur IssCur;
exlineno varchar2(30);
BEGIN
exlineno :=getExternlineno(exlineno,'50036648','00060');
open cur2 for SELECT concat(SUBSTR(susr2, 0, INSTR(susr2, '-')-1),'' ) from OrderDetail;
the stored procedure to call
PROCEDURE getExternlineno(
oRetValue OUT varchar2,
pKey IN varchar2,
poNum IN varchar2)
AS
Begin
select externlineno into oRetValue from podetail where pokey = pKey and polinenumber = poNum;
end getExternlineno;
once I figure out how to do that then I can also break up something like this(which doesn't understand the proc name:
SELECT concat(concat(SUBSTR(susr2, 0, INSTR(susr2, '-')-1),'' ),' - ' || getExternlineno(exlineno,'50036648','00060')) from OrderDetail;
Egor is right in his comment. You should declare getExternlineno as a function in order to use it inside an SQL query.
The function getExternlineno would then become:
FUNCTION getExternlineno(
pKey IN varchar2,
poNum IN varchar2)
RETURN VARCHAR
AS
DECLARE
oRetValue VARCHAR2(2000); -- Change the precision as per program's requirements.
Begin
select externlineno into oRetValue from podetail where pokey = pKey and polinenumber = poNum;
end getExternlineno;
/
Your procName procedure would then become:
PROCEDURE procName(bcur OUT IssCur)
IS
cur2 IssCur;
extCur IssCur;
exlineno varchar2(30);
BEGIN
exlineno := getExternlineno('50036648','00060'); -- Notice the change in number of arguments here.
open cur2 for SELECT concat(SUBSTR(susr2, 0, INSTR(susr2, '-')-1),'' ) from OrderDetail;
END procName;
/
And your SQL query would become:
SELECT concat(concat(SUBSTR(susr2, 0, INSTR(susr2, '-')-1),'' ),' - '
|| getExternlineno('50036648','00060'))
FROM OrderDetail;