overloading procedure in package [closed] - sql

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Below is the HEADER for the Package TASK5
CREATE OR REPLACE PACKAGE TASK5
AS
PROCEDURE TASK5APROCEDURE (
REG_NO IN NUMBER,
CERT_TITLE OUT VARCHAR2,
E_DATE OUT DATE,
C_MARKS OUT INTEGER);
PROCEDURE TASK5BPROCEDURE (
CERT_ID IN CHAR,
C_T OUT CHAR) ;
END TASK5;
The BODY for the PACKAGE TASK5
CREATE OR REPLACE PACKAGE BODY TASK5
AS
PROCEDURE TASK5APROCEDURE (
REG_NO IN NUMBER,
CERT_TITLE OUT VARCHAR2,
E_DATE OUT DATE,
C_MARKS OUT INTEGER)
IS
BEGIN
SELECT
O.PCP_TITLE,
C.CERT_EXAMDATE,
C.CERT_MARKS
INTO
CERT_TITLE,
E_DATE,
C_MARKS
FROM
PROFCERTPROGRAM O
INNER JOIN
CERTIFICATION C
ON O.PCP_ID = C.PCP_ID
WHERE
C.S_REGNO LIKE REG_NO;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE('NO DATA FOUND');
END TASK5APROCEDURE;
PROCEDURE TASK5BPROCEDURE (
CERT_ID IN CHAR, C_T OUT CHAR)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE ('COURSE NAMES: ');
FOR R IN (
SELECT O.C_TITLE C_T
FROM
COURSE O
INNER JOIN
CERTIFICATIONREQUIREMENT C
ON O.C_ID = C.C_ID
WHERE
C.PCP_ID LIKE '%'||CERT_ID||'%')
LOOP
DBMS_OUTPUT.PUT_LINE (R.C_T);
END LOOP ;
END TASK5BPROCEDURE;
END TASK5;
I wrote the package with two different procedure for 2 different input.
But, I want to rewrite the header and body with overloading procedure, any suggestions?

Overloading means creating multiple procedures or functions of the same name in a package, which take different numbers of arguments and / or where the arguments have different datatypes. This enables you to call a procedure and have different things happen depending on the arguments given.
The answer to your question, therefore, is that simple. Rename TASK5BPROCEDURE to TASK5APROCEDURE in both the package specification and the package body. Alternatively, rename them both to something different. As an example your specification might look like this afterwards:
create or replace package task5 as
procedure task5procedure (
, reg_no in number
, cert_title out varchar2
, e_date out date
, c_marks out integer);
procedure task5procedure (
, cert_id in char
, c_t out char);
end task5;
On a little side note using dbms_output.put_line in a caught exception isn't really best practice. If you're going to catch an exception you should do something with it.
As APC notes in the comment it would be normal to overload a procedure when you are doing highly related things. For example if you're sending an e-mail using a procedure and you're passing the e-mail addresses either as a string or as an array. You don't seem to be doing the same thing in your procedures here and may want to reconsider the necessity of doing this.

Related

Transaction procedure [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
It should make a bank transaction. So i have a table called "transaction" and also an "account" table and a "withdraw" and "deposit". The procedure should create a row in the transaction table. It should call my function which looks if the person is certified. If the user isnt error should show of course. If the transaction has been made the new "saldo" (which is in the account table) of both accounts should be printed. This is what i have so far:
create or replace procedure do_transaction(
p_rownr in transaction.rownr%type,
p_pnr in transaction.pnr%type,
p_knr in transaction.knr%type,
p_date in transaction."date"%type)
as
not_certified exception;
begin
insert into transaction(rownr,pnr,knr,"date")
values(p_rownr,p_pnr,p_knr,p_date);
if user <> get_certification(p_pnr,p_knr) then
raise not_certified;
end if;
dbms_output.put_line('Pnr: '||''||p_pnr||''||'Current saldo: '||''||get_saldo(p_knr)); /*I also have a function which gets the saldo from the matching knr*/
commit;
exception
when not_certified then
raise_application_error(-20007,'Not certified!');
end;
The get certification function:
create or replace function get_certification(
p_pnr in bankcust.pnr%type,
p_knr in account.knr%type)
return varchar2
as
v_certification bankcust.pnr%type;
begin
select count(*)
into v_certification
from bankcust,account
where pnr = p_pnr
and knr = p_knr;
return v_certification;
exception
when no_data_found then
return -1;
end;
Any suggestions?
I am going to take a guess here as you did not actually state your problem. But that issue is your do_transaction procedure always results in the not certified exception. This is the result of the statement
if user <> get_certification(p_pnr,p_knr) then
This will always evaluate true. It compares the character representation of the result count function from get_certification to the current user (unless the user is presumably '1') thus always resulting in "raise not_certified;" being executed. Additionally, while not actually an exception but falls into the category of not doing unnecessary work; validate certification before inserting into transaction. So:
create or replace procedure do_transaction(
p_rownr in transaction.rownr%type,
p_pnr in transaction.pnr%type,
p_knr in transaction.knr%type,
p_date in transaction."date"%type)
as
not_certified exception;
begin
if get_certification(p_pnr,p_knr) = 0 then
raise not_certified;
end if;
insert into transaction(rownr,pnr,knr,"date")
values(p_rownr,p_pnr,p_knr,p_date);
dbms_output.put_line('Pnr: '||''||p_pnr||''||'Current saldo: '||''||get_saldo(p_knr)); /*I also have a function which gets the saldo from the matching knr*/
commit;
exception
when not_certified then
raise_application_error(-20007,'Not certified!');
end do_transaction;

RESTRICT_REFERENCES and triggers

I add a PRAGMA RESTRICT_REFERENCES to a procedure in a package (for example, RNPS). That procedure implementation inserts a row in a table.
That table has a before insert trigger. that trigger reads a variable from a package and puts it :new.my_column.
I can compile the package body without problems, even though it seems like it is actually reading values from a package variable.
When I execute the procedure, it actually works. But this is the development eviroment, where there are no multiple simultaneous connections usually. I'm afraid that this could fail in the production enviroment.
So, should I be worried, or will this actually work?
Example code:
CREATE TABLE MY_TABLE
(
ID VARCHAR2(20) NOT NULL
, USER_ID VARCHAR2(50)
, CONSTRAINT MY_TABLE_PK PRIMARY KEY
(
ID
)
ENABLE
);
CREATE OR REPLACE PACKAGE PUSER IS
PROCEDURE saveUser(
pUserId VARCHAR2
);
PRAGMA RESTRICT_REFERENCES (saveUser, WNDS, RNDS, RNPS);
FUNCTION getUser RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES (getUser, WNDS, RNDS, WNPS);
END PUSER;
CREATE OR REPLACE PACKAGE BODY PUSER AS
userId VARCHAR2(50);
PROCEDURE saveUser(
pUserId VARCHAR2
) IS
BEGIN
userId := pUserId;
END saveUser;
FUNCTION getUser RETURN VARCHAR2 IS
BEGIN
RETURN userId;
END getUser;
END PUSER;
CREATE OR REPLACE PACKAGE MY_PACKAGE IS
PROCEDURE insertMyTable(
pId VARCHAR2
);
PRAGMA RESTRICT_REFERENCES (insertMyTable, RNPS);
END MY_PACKAGE;
CREATE OR REPLACE PACKAGE BODY MY_PACKAGE AS
PROCEDURE insertMyTable(
pId VARCHAR2
) IS
BEGIN
INSERT INTO MY_TABLE(id) VALUES(pId);
END insertMyTable;
END MY_PACKAGE;
CREATE OR REPLACE TRIGGER MY_TABLE_TRIGGER
BEFORE INSERT ON MY_TABLE FOR EACH ROW
DECLARE
BEGIN
:new.USER_ID := PUSER.getUser;
END MY_TABLE_TRIGGER;
Edit: I know that RESTRICT_REFERENCES is deprecated, but knowing this would still be useful for already existing code.
RNPS is useful only for functions as it tells the compiler that the return value of a function will not have changed between calls if in the meanwhile no package state (or database state for the other pragmas) has been changed. It allows for caching, but in a more implicit way than with RESULT_CACHE or DETERMINISTIC (which is now the preferred way to tell the optimizer what to expect).
Since you use it on a procedure, it does not really matter. You can safely proceed without changing package specifications. However, since you (or your successor) might ask yourselves the same question a year from now, you might as well change the packages right now while you're at it.

SQL procedure to select a column value [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I am tring to write a sql procedure with some select and insert statements. But I am getting some errors. I am not able to figure out what the problem is. Kindly help me.
Following is the error I am getting:
Error(15,1): PL/SQL: Statement ignored
Error(15,22): PLS-00201: identifier 'PROJECT_ID' must be declared
Code:
create or replace
PROCEDURE UPDATION
(
NO_IN IN VARCHAR2
) IS
poject_id defects.reference_id%type;
BEGIN
Select REFERENCE_ID INTO poject_id from DEFECTS where ID=NO_IN;
dbms_output.put_line(project_id);
if poject_id is not null then
dbms_output.put_line('proj not null');
end if;
end;
You had syntax error on the project_id declaration.
create or replace
PROCEDURE UPDATION
(
NO_IN IN VARCHAR2
) IS
project_id defects.reference_id%type;
BEGIN
Select REFERENCE_ID INTO project_id from DEFECTS where ID=NO_IN;
dbms_output.put_line(project_id );
if project_id is not null then
dbms_output.put_line('proj not null');
end if;
end;
line 6
poject_id defects.reference_id%type;
project*

PL/SQL DEVELOPER 10.2 create triggers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
create or replace trigger TDB_TRIGGER1
before insert on KTOVOT
for each row
declare
begin
insert into TEMPORARY_DATA(MIS_ZEHUT,TA_RISHUM, SHEM_TAVLA)
values(:new.id, sysdate, user_tables.table_name);
end TDB_TRIGGER1
I get this error:
PL/SQL: ORA-00984: column not allowed here
What I want to do here is to write into table:
TEMPORARY_DATA mis_zehut, ta_rishum, user_tables.table_name
I want to write the table name ktovot to the third field of table TEMPORARY_DATA with no success.
If I do it hardcoded it will work:
values(:new.id, sysdate, 'ktovot' );
PL/SQL does not support reflection - or rather it supports an extremely limited level of reflection. Nothing like Java. But we can find out the name of the current program unit using the $$PLSQL_UNIT inquiry directive. Find out more.
Triggers are program units, so we can find out the name of the currently executing trigger. And with that piece of information we can look up the name of the table which owns the trigger:
create or replace function get_table_name
( i_trigger_name in varchar2)
return varchar2
is
return_value varchar2(30);
begin
select table_name
into return_value
from user_triggers
where trigger_name = i_trigger_name;
return return_value;
end;
/
So, here is a journal table:
create table jrnl1 (id number
, action varchar2(20)
, ts timestamp
, table_name varchar2(30));
Here is a trigger to populate that journal, getting the table name dynamically:
create or replace trigger t23_trg
before insert on t23 for each row
begin
insert into jrnl1 values
(:new.id
, 'INSERT'
, systimestamp
, get_table_name($$PLSQL_UNIT));
end;
/
And here is the proof of the pudding:
SQL> select * from jrnl1;
no rows selected
SQL> insert into t23 values ('TEST', 42);
1 row created.
SQL> select * from jrnl1;
ID ACTION TS TABLE_NAME
---------- -------- ---------------------------- ------------------------------
42 INSERT 17-AUG-14 10.14.30.688672 AM T23
SQL>
I'm afraid it's not the elegant solution you might have hoped for. And in fact, given that you have to write a separate trigger for each table I'm not sure it saves you much in the way of hard-coding.
But I think it makes an interesting toy which serves to illustrate how PL/SQL works.

Function to verify username and password in pl/sql [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I've got a table called BANKCUSTOMER with the following columns:
USERNAME NOT NULL VARCHAR2(11)
FAMILY_NAME NOT NULL VARCHAR2(25)
NAME NOT NULL VARCHAR2(25)
PASSWD NOT NULL VARCHAR2(6)
I want to make a function which checks in the database if the users USERNAME and PASSWORD matches the data in the database. If the login succeeds then it should print out "Login successful!" otherwise "Wrong username or password!"
I visited a pl/sql tutorial site and came over the following code which i modified a bit so it can work with my database, but there is something I don't understand and that is what z number does and what begin select 1 into z does. Could someone please explain that for me.
create or replace function log_in(x in varchar2, y in varchar2)
return varchar2
as
z number;
begin
select 1
into z
from bankcustomer
where username=x
and passwd=y;
dbms_output.put_line('Login successful!');
exception
when no_data_found then
dbms_output.put_line('Wrong username or password!');
end;
I would like to test the function by writing SELECT log_in() FROM dual; to see if it works. When I write SELECT log_in() FROM dual; I get an error message saying:
Error starting at line 1 in command:
SELECT log_in() FROM dual
Error at Command Line:1 Column:7
Error report:
SQL Error: ORA-06553: PLS-306: wrong number or types of arguments in call to 'LOG_IN'
06553. 00000 - "PLS-%s: %s"
*Cause:
*Action:
How can this be resolved?
You have defined a function but do not return a value from it. Given the fact that you "select" the function there is no need to use dbms_output:
create or replace function log_in(x in varchar2, y in varchar2)
return varchar2
as
match_count number;
begin
select count(*)
into match_count
from bankcustomer
where username=x
and passwd=y;
if match_count = 0 then
return 'Wrong username or password!';
elsif match_count = 1 then
return 'Login successful!';
else
return 'Too many matches, this should never happen!';
end if;
end;
/
Additionally your call to the function does not provide the username and password parameters, that's why you get the error message. Assuming you have changed the function to actually return something, you need to use
SELECT log_in('username', 'secretpassword') FROM dual;
Have you actually passed any arguments to the log_in function? And what is logga_in()? Is the latter a typo on your side?
Anyway, the select 1 into z only forces an exception in case no match is found. Nothing more.
In other words, you could write the code without it, for example with select count(*) into authenticated ... and then you could check if authenticated != 0 and do the appropriate action. I don't have an Oracle instance so this code is written blindly, you'll need to test it:
create or replace function log_in(x in varchar2, y in varchar2)
return varchar2
as
match_count number;
begin
select count(*)
into match_count
from bankcustomer
where username=x
and passwd=y;
if match_count = 0 then
dbms_output.put_line('Wrong username or password!');
elsif match_count = 1 then
dbms_output.put_line('Login successful!');
else
dbms_output.put_line('Too many matches, this should never happen!');
end;
Just to add more information to what's already been provided, the BEGIN keyword indicates the beginning of the execution block; what's above that is the function header and any declaration statements.
The statement z number; is a variable declaration statement declaring a variable that is named z and is of the datatype number. The SELECT 1 INTO z WHERE... statement is checking the BANKCUSTOMER table for a row where the username matches what's passed to the function in the first parameter, and a password that matches what's passed to the function in the second parameter.
If there is a row where the username and password match what's passed to the function, then the variable z will contain the number 1. If there isn't, the Oracle NO_ROWS_FOUND exception will be raised, because SELECT...INTO statements must always select one and only one row, or else they will raise an exception (the NO_ROWS_FOUND exception for no rows, and the TOO_MANY_ROWS exception for more than one row).
Hope that's helpful! Don't hesitate to ask if you have more questions.