How to create package in postgresql - postgres-14

CREATE OR REPLACE PACKAGE emp_admin IS FUNCTION get_dept_name ( p_deptno NUMBER DEFAULT 10) RETURN VARCHAR2; FUNCTION update_emp_sal ( p_empno NUMBER, p_raise NUMBER ) RETURN NUMBER; PROCEDURE hire_emp ( p_empno NUMBER, p_ename VARCHAR2, p_job VARCHAR2, p_sal NUMBER, p_hiredate DATE DEFAULT sysdate, p_comm NUMBER DEFAULT 0, p_mgr NUMBER, p_deptno NUMBER DEFAULT 10 ); PROCEDURE fire_emp ( p_empno NUMBER ); END emp_admin;
On executing this on postgres using pgadmin. getting this error
ERROR: syntax error at or near "PACKAGE"
LINE 1: CREATE OR REPLACE PACKAGE emp_admin
^
SQL state: 42601
Character: 19

Related

Error when insert into table with a varray column through package procedure

PROBLEM IS HOW TO INSERT INTO VARRAY-
I HAVE A PROCEDURE WHERE I AM DECLARE IN PARAMETER AS TABLE DATATYPE
IN PROCEDURE I USE INSERT STATEMENT TO INSERT INTO TABLE.
I AM FACING PROBLEM TO INSERT INTO VARRAY ALREADY I AM A DECLARING A VARY TYPE IN PACKAGE SPECIFICATION AND USING IN BODY BT ERROR SHOWS:-Error(61,17): PL/SQL: ORA-00932: inconsistent datatypes: expected NUMBER got SCOTT.SYS_PLSQL_75329_19_1
create or replace PACKAGE BODY CBIS_LOAN_PROD_PACKAGE AS
PROCEDURE LOAN_PRODUCT_INSERT_PROCEDURE
(P_PRODUCT_TITLE LOAN_PROD_TAB.PRODUCT_TITLE%TYPE,
P_PRODUCT_SUMMERY LOAN_PROD_TAB.PRODUCT_SUMMERY%TYPE,
P_INTEREST_TYPE LOAN_PROD_TAB.INTEREST_TYPE%TYPE,
P_INTEREST_RATE LOAN_PROD_TAB.INTEREST_RATE%TYPE,
P_SECURITY_REQD LOAN_PROD_TAB.SECURITY_REQD%TYPE,
P_MIN_LOAN_AMT LOAN_PROD_TAB.MIN_LOAN_AMT%TYPE,
P_MAX_LOAN_AMT LOAN_PROD_TAB.PRODUCT_TITLE%TYPE,
P_TERM_MIN LOAN_PROD_TAB.TERM_MIN%TYPE,
P_TERM_MAX LOAN_PROD_TAB.TERM_MAX%TYPE,
P_REPAYMENT_FREQUENCY LOAN_PROD_TAB.REPAYMENT_FREQUENCY%TYPE,
P_REPAYMENT_AMT LOAN_PROD_TAB.REPAYMENT_AMT%TYPE,
P_EARLY_REPAY_ALLOWED LOAN_PROD_TAB.EARLY_REPAY_ALLOWED%TYPE,
P_MIN_AGE_LIMIT LOAN_PROD_TAB.MIN_AGE_LIMIT%TYPE,
P_MAX_AGE_LIMIT LOAN_PROD_TAB.MAX_AGE_LIMIT%TYPE,
V_1 VARCHAR2,
V_2 VARCHAR2,
V_3 VARCHAR2,
V_4 VARCHAR2,
V_5 VARCHAR2,
P_PROD_START_DT LOAN_PROD_TAB.PROD_START_DT%TYPE,
P_PROD_END_DT LOAN_PROD_TAB.PROD_END_DT%TYPE,
P_PROD_STATUS LOAN_PROD_TAB.PROD_STATUS%TYPE)
IS
V_T RESIDENT_VARRAY:=RESIDENT_VARRAY('V_1','V_2','V_3','V_4','V_5');
BEGIN
INSERT INTO LOAN_PROD_TAB
(
PRODUCT_TITLE,
PRODUCT_SUMMERY,
INTEREST_TYPE,
INTEREST_RATE,
SECURITY_REQD,
MIN_LOAN_AMT,
MAX_LOAN_AMT,
TERM_MIN,
TERM_MAX,
REPAYMENT_FREQUENCY,
REPAYMENT_AMT,
EARLY_REPAY_ALLOWED,
MIN_AGE_LIMIT,
MAX_AGE_LIMIT,
RESIDENT,
PROD_START_DT,
PROD_END_DT,
PROD_STATUS)
VALUES(P_PRODUCT_TITLE,
P_PRODUCT_SUMMERY,
P_INTEREST_TYPE,
P_INTEREST_RATE,
P_SECURITY_REQD,
P_MIN_LOAN_AMT,
P_MAX_LOAN_AMT,
P_TERM_MIN,
P_TERM_MAX,
P_REPAYMENT_FREQUENCY,
P_REPAYMENT_AMT,
P_EARLY_REPAY_ALLOWED,
P_MIN_AGE_LIMIT,
P_MAX_AGE_LIMIT,
V_T,/*PROBLEM IS HERE-Error(61,17): PL/SQL: ORA-00932: inconsistent
datatypes: expected NUMBER got SCOTT.SYS_PLSQL_75329_19_1*/
P_PROD_START_DT,
P_PROD_END_DT,
P_PROD_STATUS
);
END LOAN_PRODUCT_INSERT_PROCEDURE;
END;
The error you encounter occurs because a SQL type is not the same as a PL/SQL type.
The type of LOAN_PROD_TAB.RESIDENT column which is of a type you declared at schema level, is not recognized as the same as the type called RESIDENT_VARRAY you declared in the CBIS_LOAN_PROD_PACKAGE package spec.
To make it work, when you declare (and instantiate) the variable V_T, you have to use the same type you used when you declared the LOAN_PROD_TAB.RESIDENT column.
Below is a full example to verify my solution:
CREATE OR REPLACE TYPE mem_type IS VARRAY(5) of VARCHAR2(15);
CREATE TABLE test_va (
va_Name VARCHAR2(10),
va_Address VARCHAR2(20),
va_City VARCHAR2(20),
va_Phone VARCHAR2(8),
va_Members mem_type);
create or replace package test_va_pkg as
TYPE p_mem_type IS VARRAY(5) of VARCHAR2(15); -- cannot be used to insert into test_va.va_Members column!!!!
procedure p_test_va(
p_name VARCHAR2,
p_Address VARCHAR2,
p_City VARCHAR2,
p_Phone VARCHAR2
);
end test_va_pkg;
/
create or replace package body test_va_pkg as
procedure p_test_va(
p_name VARCHAR2,
p_Address VARCHAR2,
p_City VARCHAR2,
p_Phone VARCHAR2
) is
-- v_members_va p_mem_type := p_mem_type('V_1','V_2','V_3','V_4','V_5'); -- doesn't work!
v_members_va mem_type := mem_type('V_1','V_2','V_3','V_4','V_5');
begin
insert into test_va
values (
p_name,
p_Address,
p_City,
p_Phone,
v_members_va
);
commit;
exception
when others then
rollback;
raise;
end p_test_va;
end test_va_pkg;
/
begin
test_va_pkg.p_test_va('Eric Smith', 'N/A', 'London', '12345679');
end;
/
select * from test_va;
Hope it helps!

getting wrong number or types of arguments in call to procedure

I am trying to call a procedure using below code and getting
wrong number or types of arguments in call to procedure
The issue could be with the record type being passed as parameter , but I couldn't see any issue with that .
DECLARE
p_status VARCHAR2 (4) := 'S';
p_id NUMBER := 123456;
p_py_id NUMBER := 513;
p_type NUMBER := 1;
p_date_time DATE := TO_DATE ('10/01/2018 23:50:42', 'DD/MM/YYYY HH24:MI:SS');
p_os_pay NUMBER := 0;
p_ind VARCHAR2 (2) := 'Y';
p_confirm VARCHAR2 (2) := 'Y';
p_year NUMBER := 2018;
p_reason VARCHAR2 (5) := NULL;
p_currrpay NUMBER := 1517;
p_details pkg.g_r_type;
BEGIN
p_details.pro_code := 'AB';
p_details.inst_type := '1';
p_details.pay_date := TO_DATE ('19/10/2016 00:00:00', 'DD/MM/YYYY HH24:MI:SS');
p_details.pay_amt := 5000;
p_details.h_code := 'ABCD';
p_details.pay_ind := 'N';
p_details.c_code := 123456;
p_details.c_year := 8;
pkg.procedure_info ( p_status,
p_id,
p_py_id,
p_type,
p_date_time,
p_os_pay,
p_ind,
p_confirm,
p_year,
p_reason,
p_details,
p_currrpay
);
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (SQLERRM);
END;
/
Below is the package description :
CREATE OR REPLACE package pkg
as
type g_r_type is record (
pro_code varchar2 (2)
,inst_type varchar2 (1)
,pay_date date
,pay_amt number (13, 2)
,h_code varchar2 (4)
,pay_ind varchar2 (1)
,c_code number(6)
,c_year number(2)
);
procedure procedure_info (
p_status in varchar2
,p_id in number
,p_py_id in number
,p_type in number
,p_date_time in date
,p_os_pay in number
,p_ind in varchar2
,p_confirm in varchar2
,p_year in number
,p_failure_reason in varchar2
,p_details in g_r_type
,p_currrpay in number
);
end pkg;
/
I have cross checked the datatypes, length and number of arguments , but couldn't find the issue.
Make sure your package scripts end with a / at the very end of the text file, as the first char of the line (and last non blank).
If your package was created successfully, you should get a message:
package created successfully
Then if your package's Body is:
package body created successfully
To make sure your package is correctly created on the database:
This query should help:
Select * from all_source where name='PKG';
And for the body:
Select *
from all_source
where name='PKG'
and type='PACKAGE BODY';

unable to execute a store procedure getting error [duplicate]

This question already has an answer here:
Unable to call an Oracle Function
(1 answer)
Closed 9 years ago.
Can any one help me to execute the below procedure in PL/SQL. I am getting error as
declare
TYPE c_charge_code_arra IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
myarray c_charge_code_arra;
out_val number := 12;
begin
myarray(0) := 'hg';
BRANCH_BKK.air_pkg.airinvoice_pd('01','13070410012','4610032','A','IN','bkkrp_bkk','Asia/Bangkok','56YUSEN',null,myarray,null,'B',out_val);
end;
Error at line 1
ORA-06550: line 7, column 2:
PLS-00306: wrong number or types of arguments in call to 'AIRINVOICE_PD'
ORA-06550: line 7, column 2:
PL/SQL: Statement ignored
Below is the package declaration. When I try to execute the below procedure I get the above error. Thanks in Advance
CREATE OR REPLACE PACKAGE BRANCH_BKK.air_pkg AS
TYPE c_charge_code_arra IS TABLE OF VARCHAR2(20) INDEX BY PLS_INTEGER;
PROCEDURE airinvoice_pd (in_company IN varchar2,
in_file_no IN varchar2,
c_reference IN varchar2,
in_run_option IN varchar2,
in_invoice_type IN varchar2,
in_user IN varchar2,
c_time_zone in varchar2,
in_payor_code IN varchar2,
in_payor_reference IN varchar2,
i_charge_code IN c_charge_code_arra,
in_invoice_number IN varchar2,
in_invoice_against IN varchar2,
out_message OUT varchar2);
The problem is with your declaration of myarray. You are attempting to re-declare the table type in the calling script, when instead, you need to declare the variable of the table type defined in the package spec:
DECLARE
myarray BRANCH_BKK.air_pkg.c_charge_code_arra;
out_val NUMBER := 12;
BEGIN
myarray (0) := 'hg';
BRANCH_BKK.air_pkg.airinvoice_pd ('01',
'13070410012',
'4610032',
'A',
'IN',
'bkkrp_bkk',
'Asia/Bangkok',
'56YUSEN',
NULL,
myarray,
NULL,
'B',
out_val
);
END;

Not able to store values to a nested table in oracle

I am trying to write a function to show values for monthly data according to the selection made by the user in monthly report. Code snippet below is just trying to fetch values in a nested table and once data is loaded successfully in a nested table, I will call the function to display the table. I have tried a few things; but am running into issues while loading data. Below are 2 different SQLs to create this function but both of them are getting same error regarding incorrect values; I have tried a few things but to no avail:
Snippet 1:
/* Formatted on 10/16/2012 8:40:45 AM (QP5 v5.215.12089.38647) */
CREATE OR REPLACE TYPE tempObject AS OBJECT
(
kpiid number,
kpigroup VARCHAR2 (300)
);
CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;
CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
mainarea IN VARCHAR2)
RETURN tempTable
IS
MonthlyData temptable := temptable ();
n INTEGER := 0;
BEGIN
IF (mainarea = 'ALL')
THEN
FOR r IN (SELECT DISTINCT kpiid, kpigroup
FROM kpi_summary_reporting
WHERE kpifrequency = 'Monthly' AND active_ind = 'Y')
LOOP
monthlydata.EXTEND;
n := n + 1;
monthlydata (n) := tempobject (r.kpiid, r.kpigroup);
END LOOP;
END IF;
RETURN MonthlyData;
END;
Error: [Error] PLS-00306 (26: 29): PLS-00306: wrong number or types of arguments in call to 'TEMPOBJECT'
Snippet2:
/* Formatted on 10/16/2012 8:27:22 AM (QP5 v5.215.12089.38647) */
CREATE OR REPLACE TYPE tempObject AS OBJECT
(
kpiid NUMBER,
kpigroup VARCHAR2 (300)
);
CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;
CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
mainarea IN VARCHAR2)
RETURN tempTable
AS
MonthlyData temptable := temptable ();
BEGIN
IF (mainarea = 'ALL')
THEN
SELECT DISTINCT ksr.kpiid, ksr.kpigroup
INTO MonthlyData
FROM kpi_summary_reporting ksr
WHERE kpifrequency = 'Monthly' AND active_ind = 'Y';
ELSE
SELECT DISTINCT kpiid, kpigroup
INTO MonthlyData
FROM kpi_summary_reporting;
END IF;
RETURN MonthlyData;
END;
Error: [Error] ORA-00947 (24: 9): PL/SQL: ORA-00947: not enough values
I would do something like this assuming that the data is small enough that it really makes sense to load it entirely into a nested table in the server's PGA. If the data volume is larger, you probably want to use a pipelined table function instead.
Since your nested table is a table of object types, you need to use the object type constructor.
CREATE OR REPLACE FUNCTION KPI_HORIZON.Monthly_All_Data (
mainarea IN VARCHAR2)
RETURN tempTable
IS
MonthlyData temptable;
BEGIN
IF (mainarea = 'ALL')
THEN
SELECT tempObject( kpiid, kpigroup )
BULK COLLECT INTO monthlydata
FROM kpi_summary_reporting
WHERE kpifrequency = 'Monthly'
AND active_ind = 'Y';
END IF;
RETURN MonthlyData;
END;
I'm always dubious when I see a DISTINCT in a query. Do you really expect to get duplicate rows that you need to remove? If not, you'll be much better served removing the DISTINCT as I did above. If you really need the DISTINCT, then your object type would need a MAP or an ORDER method which would complicate the example a bit.
A demonstration of this working
SQL> CREATE OR REPLACE TYPE tempObject AS OBJECT
2 (
3 kpiid NUMBER,
4 kpigroup VARCHAR2 (300)
5 );
6 /
Type created.
SQL> CREATE OR REPLACE TYPE tempTable AS TABLE OF tempObject;
2 /
Type created.
SQL> create table kpi_summary_reporting (
2 kpiid integer,
3 kpigroup varchar2(300),
4 kpifrequency varchar2(30),
5 active_ind varchar2(1)
6 );
Table created.
SQL> insert into kpi_summary_reporting values( 1, 'Foo', 'Monthly', 'Y' );
1 row created.
SQL> ed
Wrote file afiedt.buf
1 CREATE OR REPLACE FUNCTION Monthly_All_Data (
2 mainarea IN VARCHAR2)
3 RETURN tempTable
4 IS
5 MonthlyData temptable;
6 BEGIN
7 IF (mainarea = 'ALL')
8 THEN
9 SELECT tempObject( kpiid, kpigroup )
10 BULK COLLECT INTO monthlydata
11 FROM kpi_summary_reporting
12 WHERE kpifrequency = 'Monthly'
13 AND active_ind = 'Y';
14 END IF;
15 RETURN MonthlyData;
16* END;
17 /
Function created.
SQL> select monthly_all_data( 'ALL' ) from dual;
MONTHLY_ALL_DATA('ALL')(KPIID, KPIGROUP)
--------------------------------------------------------------------------------
TEMPTABLE(TEMPOBJECT(1, 'Foo'))

PLSQL, execure formula stored in a table

I'm a newbie in PLSQL. I was just wondering if I can save my formula into a table as string and use it in my functions to calculate some values.
Here is an example:
ID NAME FORMULA
1 test prm_testval*prm_percent/18
2 test2 (prm_testval +20)*prm_percent
what I want to do is to select formula column from the table and use the string in my functions
select t.* from table t where id=1
prm_calculated_value = t.formula
I don't want the string value of formula in here, just the formula itself.
Any ideas, If I can use it or not?
The starting point is execute immediate-statement. It's PL/SQL's eval().
create table formulas (
id number,
name varchar2(20),
formula varchar2(50)
);
insert into formulas values (1, 'test 1', 'prm_testval*prm_percent/18');
insert into formulas values (2, 'test 2', '(prm_testval +20)*prm_percent');
/* eval from: http://www.adp-gmbh.ch/blog/2005/may/5.html */
create or replace function eval (
expr in varchar2
) return varchar2 as
ret varchar2(32767);
begin
execute immediate 'begin :result := ' || expr || '; end;' using out ret;
return ret;
end;
/
create or replace function eval2 (
vars in varchar2,
expr in varchar2
) return varchar2 as
ret varchar2(32767);
begin
execute immediate vars || ' begin :result := ' || expr || '; end;' using out ret;
return ret;
end;
/
create or replace function calc_prm (
id_ in number,
prm_testval in varchar2,
prm_percent in varchar2
) return number as
formula_ formulas.formula%type;
vars constant varchar2(32767) :=
'declare prm_testval constant number := to_number(' || prm_testval ||
'); prm_percent constant number := to_number(' || prm_percent || ');';
begin
select formula into formula_ from formulas where id = id_;
return eval2(vars, formula_);
end;
/
/* call from SQL */
select eval('3*4') from dual;
select calc_prm(1, 97, 10) from dual;
select calc_prm(2, 97, 10) from dual;
/* call from PL/SQL block */
begin
dbms_output.put_line(eval('3*4'));
dbms_output.put_line(calc_prm(1, 97, 10));
dbms_output.put_line(calc_prm(2, 97, 10));
end;
/
Based on this example you can start building your own way to map symbol values (prm_testval and prm_percent) to real values. Next you might want to have a look into DBMS_SQL.
Beware SQL injection when using client supplied data ! See also e.g. Bobby Tables: A guide to preventing SQL injection.

Resources