What do these errors mean and how do you suggest I fix them? - oracle

I am new to learning SQL and currently learning it in class. I am trying to write a code that fulfills the following requirements:
Make a reservation: Input parameters: Hotel, guest’s name, start date, end dates, room type, date of reservation. Output: reservation ID. NOTE: Only one guest per reservation. However, the same guest can make multiple reservations.
Find a reservation: Input is the guest’s name and date, hotel ID. The output is reservation ID
I am still somewhat new to deciphering error codes and tried to look up what they mean. However, I'm still not quite sure why my code is wrong.
CREATE OR REPLACE PACKAGE hotelmanagement AS
FUNCTION make(rsrv_id VARCHAR2
,hotel_name VARCHAR2
,guest VARCHAR2
,start_date VARCHAR2
,end_date VARCHAR2
,room_type VARCHAR2
,rsrv_date VARCHAR2)
RETURN NUMBER IS
rsrv_id NUMBER;
BEGIN
SELECT rsrv_seq.nextval INTO reserve_id FROM dual;
INSERT INTO reservations
VALUES
(reserve_id, 'Four Seasons', 'Amanda', 'July-30-2019', 'Aug-8-2019',
'King', 'July-18-2019');
tot_rsrv := tot_rsrv + 1;
RETURN(rsrv_id);
END;
FUNCTION find(guest VARCHAR2
,rsrv_date VARCHAR2)
RETURN NUMBER IS
rsrv_id NUMBER;
BEGIN
SELECT rsrv_id
INTO guest
FROM reservations
WHERE rsrv_date = find_rsrv_date;
END;
RETURN(rsrv_id);
END hotelmanagement;
I have these error messages(two of them look the same?):
Error(4,1): PLS-00103: Encountered the symbol "SELECT" when expecting one of the following: begin function pragma procedure subtype type current cursor delete exists prior The symbol "begin" was substituted for "SELECT" to continue.
Error(5,1): PLS-00103: Encountered the symbol "RSRV_ID" when expecting one of the following: language
Error(5,1): PLS-00103: Encountered the symbol "RSRV_ID" when expecting one of the following: language

The requirements are a quite vague, so it is difficult to provide the desired procedure. Anyway, your code has some weak items.
Your procedure has several input parameters but you don't use them inside the procedure.
Use appropriate data types, i.e. never(!) store DATE or number values in string, i.e. VARCHAR2. Use VARCHAR2 only for string data. At least you use four digit year, which is the proper way of doing it.
RETURN command does not use brackets.
Taking all this into account your code should be more or less like this:
CREATE OR REPLACE PACKAGE BODY hotelmanagement AS
FUNCTION make( -- you can't declare variable "rsrv_id" twice
hotel_name IN VARCHAR2
,guest IN VARCHAR2
,start_date IN DATE
,end_date IN DATE
,room_type IN VARCHAR2
,rsrv_date IN DATE)
RETURN NUMBER IS
rsrv_id NUMBER;
BEGIN
INSERT INTO reservations
VALUES
(rsrv_seq.nextval, hotel_name, guest, start_date, end_date,
room_type, rsrv_date)
RETURNING reserve_id INTO rsrv_id ;
-- tot_rsrv := tot_rsrv + 1; -> I don't see any use for it, variable tot_rsrv is not declared
RETURN rsrv_id;
END;
FUNCTION find(v_guest IN VARCHAR2
,rsrv_date IN DATE) RETURN NUMBER IS
rsrv_id NUMBER;
BEGIN
SELECT rsrv_id
INTO rsrv_id
FROM reservations
WHERE rsrv_date = find_rsrv_date
and guest = v_guest; -- don't use "guest = guest" because this will select all rows.
RETURN rsrv_id;
END;
END hotelmanagement;

Related

How to add a new user in a PL/SQL table using a function?

I am fairly new to PL/SQL and one of the doubts I have is to create and declare functions.
Specifically this one:
Create a function that creates a new user:
Use a sequence togive the new User a new ID
Pass the name, address, etc... as IN arguments
Return as OUT arguments the ID created and a O_ERROR_MESSAGE
Function returns TRUE if the user is added, otherwise returns FALSE
Handle exceptions
Create a PL/SQL block and test the created function
This is my code so far:
CREATE OR REPLACE FUNCTION DSB_ADD_NEW_USERS (I_NAME IN VARCHAR2,
I_ADDRESS IN VARCHAR2,
I_BIRTHDATE IN DATE,
I_COUNTRY IN VARCHAR2)
RETURN NUMBER IS
O_ERROR_MESSAGE EXCEPTION;
CURRENT_USER NUMBER;
BEGIN
DSB_NB_SEQ_USER_ID.NEXTVAL;
SELECT COUNT(USER_ID) INTO CURRENT_USER
FROM DSB_NB_USERS;
WHILE CURRENT_USER != 0
LOOP
DSB_NB_SEQ_USER_ID.NEXTVAL;
SELECT COUNT(USER_ID) INTO CURRENT_USER
FROM DSB_NB_USERS;
END LOOP;
INSERT INTO DSB_NB_USERS (USER_ID, NAME, ADDRESS, BIRTHDATE, COUNTRY_ID_FK) VALUES (CURRENT_USER, I_NAME, I_ADDRESS, TO_DATE('I_BIRTHDATE', 'DD/MM/YYYY'), I_COUNTRY);
RETURN CURRET_USER;
EXCEPTION
WHEN O_ERROR_MESSAGE THEN
RETURN NULL;
WHEN OTHERS THEN
RETURN NULL;
END;
DECLARE
I_NEW_USER NUMBER;
BEGIN
I_NEW_USER := DSB_ADD_NEW_USERS(I_NAME => 'Arnaldo Amaral',
I_ADDRESS => 'Rua da Agra',
I_BIRTHDATE => '03/05/1959',
I_COUNTRY => 'PT');
END;
Am i too far from the truth?
I know there's still a lot to add.
Thank you for the help!!!
It seems to me you are asking for a lifeline, that needs more than just a code response. First off look at the answer by
#Tejash. His solution is a far cry from what you have, and is correct for your function definition (although that is itself incorrect given your listed requirements.) Also, #EdStevens is correct that is is a very poor use of a function. However a function is your assignment's requirement.
So lets dissect your code and see how it satisfies each of your requirements. (I cannot stand all caps, so I'm lower casing it.)
Fails. While you have a sequence it is used improperly. You can not
just code a standalone name. It must be used in either a SQL
statement or an assignment statement.
Passes.
Fails. Your function passes the IN parameters correctly. However
there are no OUT parameters.
Your function returns Number not the required True/False which
requires either Boolean or varchar2 for literal.
Code section for requirements 3,4.
create or replace function dsb_add_new_users (i_name in varchar2,
i_address in varchar2,
i_birthdate in date,
i_country in varchar2) <<< where are the 2 required out parameters
return number is <<< Should be True or False so either Boolean or varchar2
o_error_message exception; <<< Should be an Out parameter not an exception
Yes you have the Exception Section, which is required for handling
exceptions. However you do not handle exceptions so much as suppress
them, indicating to Oracle, and to the calling routine, that they didn't actually happen.
exception
when o_error_message then <<< as coded this is a developer defined exception, yet is not raised so it cannot happen.
return null; <<< even if it were raised you have thrown it away, the calling routine will never it happened
when others then <<< One of the worst pieces of code that can be written. I tend to remember seeing a discussion in
return null; <<< Oracle that would make this a compile time error. To bad the supporters lost the argument.
Passed, mostly. Correct for posted code, but insufficient per requirements.
So all-in-all not highly successful when viewed against the requirements.
A couple other items not specific the requirements, but disaster to successful implementation.
While technically you might get away with the following it is very bad practice. Current_User is an Oracle reserved word.
current_user number; <<< NO, NO bad verifiable name.
The following completely decimates your function. It creates a never ending loop. Well not quite -- it runs 1 time, but never afterward.
I believe you intended for the current_user variable to contain the ID assigned to the user. But it actually contains the number of rows in the table. Further what would the number of rows (count) have to do with Inserting a row? SO what does the code actually Do?
dsb_nb_seq_user_id.nextval; <<< systax error.
select count(user_id) into current_user <<< count the number of rows in the table
from dsb_nb_users;
while current_user != 0 <<< if there are any rows in the table
loop
dsb_nb_seq_user_id.nextval; <<< syntax error
select count(user_id) into current_user <<< try counting then again until there are none.
from dsb_nb_users;
end loop;
So correcting for the above what do we wind up with. I hesitate here in fear you will just copy the below and submit it. Please don't do that but study and understand what it's doing, then rewrite you routine. But after tearing you initial effort up, I guess I owe a corrected solution.
create or replace function dsb_add_new_users
( i_name in varchar2
, i_address in varchar2
, i_birthdate in date
, i_country in varchar2
, o_new_user_id out number
, o_error_message out varchar2
return boolean
is
country_id_l number;
begin
-- initialize out variables
o_new_user_id := null;
o_error_message := null;
-- get country id from input parameter
select country_id
into country_id_l
from country
where name = i_country;
-- create user and get the assigned user_id
insert into dsb_nb_users (user_id, name, address, birthdate, country_id_fk)
values dsb_nb_seq_user_id.nextval
, i_name
, i_address
, i_birthdate
, country_id_l
)
returning user_id
into o_new_user_id;
return true;
exception
when no_date_found then
o_output_message = 'ERROR: Specified country name ''' || country_id_l || ''' Not Found.';
return false;
when others then
o_output_message := 'ERROR: ' || sqlerrm;
return false
end dsb_add_new_users ;
--------------- Test Driver ----------------
declare
i_new_user number;
new_user_created boolean;
error_message varchar2(255);
begin
new_user_created := dsb_add_new_users( i_name => 'Arnaldo Amaral',
, i_address => 'Rua da Agra'
, i_birthdate => to_date('03/05/1959','mm/dd/yyyy') -- or is it 'dd/mm/yyyy'
, i_country => 'PT'
, o_new_user_id => i_new_user
, o_error_message => error_message);
if not new_user_created
then
dbms_output.put_line (error_messag);
end if ;
end;
Disclaimer: As you did not post table DDL nor test data the routine has not been tested nor even compiled. Any syntax error(s) is for you to resolve. Further, I follow Tejash in the assumption you actually have a countries table and there is a FK to it. That may be an erroneous assumption.
Why don't you directly use the sequence value to insert new user as follows:
CREATE OR REPLACE FUNCTION DSB_ADD_NEW_USERS (
I_NAME IN VARCHAR2,
I_ADDRESS IN VARCHAR2,
I_BIRTHDATE IN DATE,
I_COUNTRY IN VARCHAR2
) RETURN NUMBER IS
CURRENT_USER_ID NUMBER;
BEGIN
CURRENT_USER_ID := DSB_NB_SEQ_USER_ID.NEXTVAL; -- returns new and unique number
INSERT INTO DSB_NB_USERS (
USER_ID,
NAME,
ADDRESS,
BIRTHDATE,
COUNTRY_ID_FK
) VALUES (
CURRENT_USER_ID,
I_NAME,
I_ADDRESS,
I_BIRTHDATE,
(
SELECT
COUNTRY_ID
FROM
COUNTRIES
WHERE
NAME = I_COUNTRY
) -- it is FK so need to use SELECT sub-query to find COUNTRY_ID
);
RETURN CURRENT_USER_ID; -- returning the new user ID
EXCEPTION
WHEN OTHERS THEN
RETURN -1; -- returning -1 in case there is any error
END;
-1 will be returned when there is an error while adding the new user.
Came up with this much simpler answer after asking to a few people for help.
create or replace FUNCTION DSB_ADD_NEW_USERS (I_NAME IN VARCHAR2,
I_ADDRESS IN VARCHAR2,
I_BIRTHDATE IN DATE,
I_COUNTRY IN VARCHAR2)
RETURN NUMBER IS
CURRENT_USER NUMBER;
BEGIN
CURRENT_USER := DSB_NB_SEQ_USER_ID.NEXTVAL;
DBMS_OUTPUT.PUT_LINE('Hello World');
INSERT INTO DSB_NB_USERS (USER_ID, NAME, ADDRESS, BIRTHDATE, COUNTRY_ID_FK) VALUES (CURRENT_USER, I_NAME, I_ADDRESS, TO_DATE(I_BIRTHDATE, 'DD/MM/YYYY'), I_COUNTRY);
RETURN CURRENT_USER;
EXCEPTION
WHEN OTHERS THEN
RETURN -1;
END;
SET SERVEROUT ON
DECLARE
I_NEW_USER NUMBER;
BEGIN
I_NEW_USER := DSB_ADD_NEW_USERS(I_NAME => 'Arnaldo Amaral',
I_ADDRESS => 'Rua da Agra',
I_BIRTHDATE => '03/MAY/1959',
I_COUNTRY => 'PT');
commit;
END;
/
Thank you all!!!

How to run Oracle function which returns more than one value

My test function is this
CREATE OR REPLACE FUNCTION MULTI_VAL
(MYNAME OUT EMP2017.ENAME%TYPE)
RETURN NUMBER AS
MYSAL EMP2017.SAL%TYPE;
BEGIN
SELECT SAL, ENAME INTO MYSAL, MYNAME FROM EMP2017 ;
RETURN MYSAL;
END;
/
When I run it like
variable mynm varchar2(20)
SELECT MULTI_VAL(:mynm) FROM dual;
it gives this error
ERROR at line 1:
ORA-06553: PLS-561: character set mismatch on value for parameter 'MYNAME'
The error you get now indicates a datatype mismatch.
However there is a fundamental problem with your code. We cannot use functions which have OUT parameters in SQL. So once you have fixed the datatype issue you will get this error: ORA-06572: Function MULTI_VAL has out arguments.
You can run it like this:
declare
n varchar2(20);
x number;
begin
x := multi_val(n);
end;
/
Generally, functions with OUT parameters are considered bad practice. The syntax allows them, but the usage is hard to understand. It's better to use a procedure with two OUT parameters (because we can only call the program in PL/SQL anyway) or else have the function return a user-defined type.
CREATE TABLE EMP2017(ENAME VARCHAR2(10),SAL NUMBER);
INSERT INTO EMP2017 VALUES ('SMITH',5000);
INSERT INTO EMP2017 VALUES ('JOHNS',1000);
COMMIT;
CREATE TYPE RET_MULT AS OBJECT
(ENAME VARCHAR2(10),SAL NUMBER);
CREATE TYPE T_RET_MULT AS TABLE OF RET_MULT;
CREATE OR REPLACE FUNCTION MULTI_VAL RETURN T_RET_MULT PIPELINED IS
MYSAL RET_MULT;
BEGIN
FOR I IN(SELECT SAL, ENAME FROM EMP2017) LOOP
MYSAL := RET_MULT(I.ENAME,I.SAL);
PIPE ROW(MYSAL);
END LOOP ;
RETURN ;
END;
SELECT * FROM TABLE(MULTI_VAL());
I think this question can be solved without using pipeline functions. Just like this. All pre required data as described #Sedat.Turan except function. Sorry for copy/past.
CREATE TABLE EMP2017(ENAME VARCHAR2(10),SAL NUMBER);
INSERT INTO EMP2017 VALUES ('SMITH',5000);
INSERT INTO EMP2017 VALUES ('JOHNS',1000);
COMMIT;
CREATE TYPE RET_MULT AS OBJECT
(ENAME VARCHAR2(10),SAL NUMBER);
CREATE TYPE T_RET_MULT AS TABLE OF RET_MULT;
create or replace function MULTI_VAL return T_RET_MULT is
RET_SET T_RET_MULT;
begin
select RET_MULT(ENAME, SAL) bulk collect into RET_SET from EMP2017;
return RET_SET;
end;

ORA-00904 Invalid Identifier -- Dynamic Oracle function

create or replace
FUNCTION JDT_UDC_Desc
(
V_SY IN VARCHAR2,
V_RT IN VARCHAR2,
V_KY IN VARCHAR2
)
RETURN VARCHAR2
AS
V_DL01 VARCHAR2(30);
BEGIN
EXECUTE IMMEDIATE 'select drdl01
from PRODCTL.F0005
WHERE DRSY = V_SY
AND DRRT = V_RT
AND ltrim(rtrim(drky)) =ltrim(rtrim(V_KY))'
INTO V_DL01
using V_SY,V_RT,V_KY;
END;
Compiled. I click on run and enter below values:
V_SY ='00',
V_RT = '01',
V_KY='04';
And I get below error
ORA-00904 V_KY Invalid Identifier
Can anyone help me understand the reason for this error?
You are passing the literal values 'V_SY', 'V_RT' and 'V_KY' in your statement and it's interpreting them as column names, hence the invalid identifier error. You need to use the variable placeholders like:
EXECUTE IMMEDIATE 'select drdl01
from PRODCTL.F0005
WHERE DRSY = :1
AND DRRT = :2
AND ltrim(rtrim(drky)) =ltrim(rtrim(:3))'
INTO V_DL01
using V_SY,V_RT,V_KY;
First, there does not appear to be any reason to use dynamic SQL here. It should be rare that you need to resort to dynamic SQL-- your code is going to be more efficient and more maintainable.
create or replace
FUNCTION JDT_UDC_Desc
(
V_SY IN VARCHAR2,
V_RT IN VARCHAR2,
V_KY IN VARCHAR2
)
RETURN VARCHAR2
AS
V_DL01 VARCHAR2(30);
BEGIN
select drdl01
into V_DL01
from PRODCTL.F0005
WHERE DRSY = V_SY
AND DRRT = V_RT
AND trim(drky) =trim(V_KY);
return v_dl01;
END;
Second, it would be really helpful if you picked meaningful variable names and meaningful names for your columns and tables. F0005 tells you nothing about what the table contains. v_sy and drsy tell you nothing about what the variable or column is supposed to contain. That is going to make maintaining this code far more difficult that it needs to be.

How can implement a procedure in ESQL (an internal procedure) from Oracle database

I create a store procedure in Oracle db that insert Customer to my Table
this is my code :
CREATE OR REPLACE PROCEDURE THP.INSERT_CUSTOMER(
P_CUSTNAME IN VARCHAR2,
P_CUSTLAST IN VARCHAR2,
P_CUSTFATHER IN VARCHAR2,
P_NATIONNO IN NUMBER,
P_BIRTHDAY IN VARCHAR2,
P_BIRHTPLACE IN VARCHAR2,
P_EMAIL IN VARCHAR2,
P_CUSTENAME IN VARCHAR2,
P_CUSTELAST IN VARCHAR2,
P_OWNID IN NUMBER,
P_CUSTTYPEID IN NUMBER,
P_GENDERID IN NUMBER,
P_BILLSTID IN NUMBER,
P_BILLSPID IN NUMBER,
P_IDNO IN varchar2,
RESULT OUT INTEGER) IS
CNT NUMBER;
BEGIN
RESULT := 1;
CNT := 0;
SELECT COUNT(1) INTO CNT FROM THP.TBCUSTOMER WHERE NATIONNO=P_NATIONNO ;
IF CNT=1 THEN
COMMIT;
RESULT := 1; --IF RECORD is EXIST
ELSE
BEGIN
INSERT INTO TBCUSTOMER(CUSTID,CUSTNAME,CUSTLAST,CUSTFATHER,NATIONNO,BIRTHDAY,BIRHTPLACE,EMAIL,CUSTENAME,CUSTELAST,OWNID,CUSTTYPEID,GENDERID,BILLSTID,BILLSPID,IDNO)
VALUES(CUSTID_SEQ.NEXTVAL,P_CUSTNAME,P_CUSTLAST,P_CUSTFATHER,P_NATIONNO,P_BIRTHDAY,P_BIRHTPLACE,P_EMAIL,P_CUSTENAME,P_CUSTELAST,P_OWNID,P_CUSTTYPEID,P_GENDERID,P_BILLSTID,P_BILLSPID,P_IDNO);
COMMIT;
RESULT :=0; --IF INSERT NEW COLUMN
END;
END IF;
END INSERT_CUSTOMER;
/
now I want use this procedure in ESQL and create it directly in ESQL not CALL it from Oracle database or other DB
would you please guide me a bout it...
General comments, not an answer ...
count(1)
count(1) = count(*), which is the standard form for "count the number of rows". count(1) has no advantages, so best to use count(*).
RESULT := 1
is redundant at the beginning of the procedure
CNT := 0
... also redundant. The variable name is not very meaningful, and might make people think of a rude word, so perhaps change it to rows_found.
Prefixing the arguments with P_ is not required. If you use one of them in a SQL statement and need to deconflict it from a database object name then prefix it with the procedure name, so you have:
WHERE NATIONNO= INSERT_CUSTOMER.NATIONNO
Is NATIONNO constrained to be unique in the customer table? If not, use:
SELECT COUNT(*)
INTO CNT
FROM THP.TBCUSTOMER
WHERE NATIONNO=INSERT_CUSTOMER.NATIONNO AND
ROWNUM = 1;
(12g will introduce the LIMIT SQL syntax, by the way).
Commiting in a procedure is often held to be bad practice, as the procedure often becomes part of a longer business transaction (eg. inserting a new customer and address) and the commit should be controlled by the application code.
Upper case code is harder to read than lower case -- that's why direction signs on motorways are not uppercase.
The begin-end block for the insert is not required at all.
"birhtplace" is spelled wrong.
So I'd suggest that what you want to convert to ESQL is actually:
create or replace procedure thp.insert_customer(
custname in varchar2,
custlast in varchar2,
custfather in varchar2,
nationno in number ,
birthday in varchar2,
birhtplace in varchar2,
email in varchar2,
custename in varchar2,
custelast in varchar2,
ownid in number ,
custtypeid in number ,
genderid in number ,
billstid in number ,
billspid in number ,
idno in varchar2,
result out integer) is
rows_found number;
begin
select count(*)
into rows_found
from thp.tbcustomer
where nationno=insert_customer.nationno;
if rows_found = 1 then
result := 1;
else
insert into
tbcustomer(
custid ,
custname ,
custlast ,
custfather,
nationno ,
birthday ,
birthplace,
email ,
custename ,
custelast ,
ownid ,
custtypeid,
genderid ,
billstid ,
billspid ,
idno)
values(
custid_seq.nextval,
custname ,
custlast ,
custfather,
nationno ,
birthday ,
birthplace,
email ,
custename ,
custelast ,
ownid ,
custtypeid,
genderid ,
billstid ,
billspid ,
idno);
result :=0;
end if;
end insert_customer;
/
To call an external procedure via ESQL, you need to first declare the external function.
Do it as below:
CREATE PROCEDURE DoSomething (IN in1 CHARACTER, OUT out1 CHARACTER, OUT out2 CHARACTER)
LANGUAGE DATABASE
EXTERNAL NAME "DoSomething";
Now you can call this function from your ESQL function as below:
CALL DoSomething(in,out1,out2) IN Database.yourschema.yourDB;
P.S. The parameters you are passing must be compatible with the parameters of your stored procedure.

Creating a package to keep track of tapes used

Thought I had followed creation pattern, but the body will not compile. What I am trying to accomplish is to develop a package to run a procedrure periodically to determine at what time and date more than 15 are in use.. Oracle 11g.
The only other data that needs to go into the table beingg inserted into the sysdate.
CREATE OR REPLACE
PACKAGE TAPES_USED AS
function TAPESCOUNT(count number) return number;
procedure INSERT_TAPES_COUNT(sysdate date, count NUMBER);
END TAPES_USED;
/
-----------------------------------------
CREATE OR REPLACE
PACKAGE body TAPES_USED AS
function TAPESCOUNT(count number) return number as count number;
begin
select count(*)
into
count
from DEV.TAPES_IN USE where count(*) > 15;
procedure INSERT_TAPES_COUNT(sysdate date, count NUMBER)as
begin
INSERT INTO DEV.TAPES_USED VALUES
(sysdate, count);
end INSERT_TAPES_COUNT;
END TAPES_USED;
/
Any help or suggestion anyone can offer will be appreciated.
CREATE OR REPLACE
PACKAGE BODY tapes_used AS
FUNCTION tapescount(in_ct NUMBER) RETURN NUMBER IS
ct NUMBER;
BEGIN
SELECT COUNT(*)
INTO ct
FROM dev.tapes_in_use;
IF ct > in_ct THEN
RETURN ct;
ELSE
RETURN NULL;
END IF;
END tapescount;
PROCEDURE insert_tapes_count(sysdt date, ct NUMBER) IS
BEGIN
INSERT INTO dev.tapes_used VALUES (sysdt, ct);
END insert_tapes_count;
END tapes_used;
/
You should refrain from using reserved words such as COUNT and SYSDATE for variable names (I don't know but that could be some of your compilation issues), so I've renamed them. Also, you forgot to END your function. I think you were missing an underscore in your table name in the FROM clause of the SELECT in your function, and you didn't have a RETURN statement in your function, which you must have.
Generally speaking, a function should accept one or more input parameters and return a single value. You're not making use of the input parameter in your function. I've implemented a suggested parameter.
As Egor notes, this isn't a realistic function, and I'm not certain about your intent here. What is the function supposed to do?
Maybe you want your function to return the Date/Time your count was exceeded? You could also combine everything into a single procedure:
PROCEDURE ck_tape_ct(min_tape_ct NUMBER) IS
ct NUMBER;
BEGIN
SELECT COUNT(*)
INTO ct
FROM dev.tapes_in_use;
IF ct > min_tape_ct THEN
INSERT INTO dev.tapes_used VALUES(SYSDATE, ct);
END IF;
END;

Resources