Simple PL/SQL function to test if a string is a number - plsql

I'm experienced with T-SQL from SQL Server, but have recently begun working on a project utilizing an Oracle database (11g) and am having some issues writing what seems to be basic code.
I need to test whether a set of values are numeric, and only insert them into a table if they are. PL/SQL doesn't seem to have an is_number function, so I wrote my own based on an AskTom question.
create or replace
function IS_NUMBER(str in varchar2) return boolean
IS
n number;
BEGIN
select to_number(str) into n from dual;
return (true);
EXCEPTION WHEN OTHERS THEN
return (false);
END;
Eventually, I'd like to use this function in a WHERE clause, but for now I'm just trying to get it to run at all:
declare
str varchar2(1);
n boolean;
begin
str := '0';
select ca_stage.is_number(str) into n from dual;
end;
In SQL Developer, trying to run this gives me the following error report:
Error report:
ORA-06550: line 6, column 39:
PLS-00382: expression is of wrong type
ORA-06550: line 6, column 19:
PLS-00382: expression is of wrong type
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
The error report is straight-forward, but doesn't make sense. The function accepts a varchar2, and that's what I'm using as an input variable. It returns a boolean and again, that's what I'm using.
As I said, this is basic code, so I assume that I'm missing something fundamental.

Return a SQL datatype, e.g. VARCHAR2. Also, I'd recommend against using WHEN OTHERS. Also, you don't need a query on dual:
create or replace
function IS_NUMBER(str in varchar2) return varchar2
IS
n number;
BEGIN
n := to_number(str);
return 'Y';
EXCEPTION WHEN VALUE_ERROR THEN
return 'N';
END;

Related

Expression is of wrong type when sending nested array to Function

I want to send a collection to a Function, but I keep getting an error.
I defined the RECORD and TYPES in my Package Header and Implemented the body aswell. I dont understand why I cant send a simple collection as a parameter, the idea is for me to loop through the collection and do some comparisation then return a char within a sql statement.
Been struggling with this for a week now, any help is appreciated.
Exact error:
ORA-06550: line 9, column 45:
PLS-00382: expression is of wrong type
ORA-06550: line 9, column 40:
PLS-00306: wrong number or types of arguments in call to 'TEST_F'
ORA-06550: line 9, column 23:
PL/SQL: ORA-00904: "PACKAGE_SS"."TEST_F": invalid identifier
ORA-06550: line 9, column 3:
PL/SQL: SQL Statement ignored
Header:
create or replace
PACKAGE PACKAGE_SS AS
type t_itemnumber is table of varchar2(100) index by BINARY_INTEGER;
type t_alternative_rec is record
(
itemnumber t_itemnumber
);
type t_alternative_prev is table of t_alternative_rec INDEX BY BINARY_INTEGER;
type t_procestype_rec is record
(
procestype char
);
TYPE result_table IS TABLE OF t_procestype_rec;
FUNCTION test_f(p_items_prev IN t_alternative_prev) RETURN result_table PIPELINED;
END AOPA_VALIDATE_SS;
The package body looks like this:
create or replace
PACKAGE BODY PACKAGE_SS AS
FUNCTION test_f(p_items_prev IN t_alternative_prev) RETURN result_table PIPELINED IS
processType char(1) := 'U';
rec t_procestype_rec :=null;
BEGIN
DBMS_OUTPUT.PUT_LINE('ENTERD ');
if (processType= 'U') then
select 'U' into rec from dual;
end if;
if (processType='C') then
select 'C' into rec from dual;
end if;
if (processType='D') then
select 'D' into rec from dual;
end if;
pipe row (rec);
return;
END test_f;
END PACKAGE_SS;
Usage plsql script:
DECLARE
prev_rev_alternatives PACKAGE_SS.t_alternative_prev;
BEGIN
prev_rev_alternatives(1).itemnumber(10) := 'PR454545';
prev_rev_alternatives(1).itemnumber(20) := 'PR333333';
SELECT * FROM table(PACKAGE_SS.test_f(prev_rev_alternatives));
END;
There are two things which my eyes fall upon:
Usage of SELECT without INTO in an anonymous PLSQL block is not supposed to work.
Usage of types in an SQL statement requires the type defined as an object, not within a package specification.
Try
CREATE TYPE
https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_8001.htm
and
SELECT * INTO ... FROM ...
This might help.

PLSQL procedure error

I get the below error while executing code
create or replace
function contact_restriction_function(obj_schema varchar2, obj_name varchar2)
return varchar2 is
v_contact_info_visible hr_user_access.contact_info_visible%type;
begin
-- Here you can put any business logic for filtering
select nvl(max(contact_info_visible),'N')
into v_contact_info_visible
from hr_user_access
where user_name = user;
-- SQL filter / policy predicate
return ''''||v_contact_info_visible||''' = ''Y'' ';
end;
/
after show erros command i got this
show errors
Errors for FUNCTION CONTACT_RESTRICTION:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/1 PLS-00103: Encountered the symbol "?" when expecting one of the
following:
begin function pragma procedure subtype type
current cursor delete
exists prior external language
This is the remaining code:
begin
dbms_rls.add_policy(object_schema => 'HR' ,
object_name => 'EMPLOYEES' ,
policy_name => 'Contact_Restriction_Policy' ,
policy_function => 'contact_restriction_function' ,
sec_relevant_cols=>'EMAIL,PHONE_NUMBER'Contact Info ,
sec_relevant_cols_opt=>dbms_rls.all_rows);
end;
below is the actual code which i am executing before show errors:
create or replace function contact_restriction(obj_schema varchar2, obj_name varchar2)
return varchar2
is
v_contact_info_visible IN user_access.contact_info_visible%type;
begin
select nvl(max(contact_info_visible),'N')
into v_contact_info_visible
from user_access where username = user;
return 'v_contact-info_visible ='|| 'Y';
end;
Your original question shows an error message referring to "?", but the code yout posted a as comment would raise a similar error for `"IN"' instead:
2/24 PLS-00103: Encountered the symbol "IN" when expecting one of the following:
That is because you've used IN for a local variable; but IN, OUT and IN OUT are only applicable to stored procedure parameters. You could have declared the function with an explicit IN for example, though it is the default anyway:
create or replace function contact_restriction(obj_schema IN varchar2, ...
So that needs to be removed from the v_contact_info_visible declaration. You've linked to an example you're working from, but you've removed a lot of important quotes from that, which will still cause it to fail when executed as a part of a VPD; because v_contact_info_visible will be out of scope to the caller. And you have a typo, with a hyphen instead of an underscore.
You need something like:
create or replace function contact_restriction(obj_schema varchar2,
obj_name varchar2)
return varchar2 is
v_contact_info_visible user_access.contact_info_visible%type;
begin
select nvl(max(contact_info_visible),'N')
into v_contact_info_visible
from user_access
where username = user;
return ''''||v_contact_info_visible ||''' =''Y''';
end;
/
When called, that will return a string which is either 'N'='Y' or 'Y'='Y'. VPD will include that as a filter in the original query, which will either prevent any rows being returned (in the first case) or have no effect and allow all rows that match any other existing conditions to be returned (in the second case).
The syntax of the function header is incorrect. It should be:
create or replace function contact_restriction(obj_schema IN varchar2, obj_name IN varchar2)
return varchar2
is

how to execute pl/sql procedure

Procedure:
create or replace
PROCEDURE ADDITION
(
A IN NUMBER
, B IN NUMBER
, C OUT number
) AS
BEGIN
C := A+B;
dbms_output.put_line(c);
END ADDITION;
executing:
begin
addition(4,5);
end;
Error:
PLS-00306: wrong number or types of arguments in call to 'ADDITION'
ORA-06550: line 2, column 2:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
How to rectify this error.Let me know what is the wrong in code
Your procedure expects an out parameter which you also need to provide:
declare
add_result number;
begin
addition(4,5,add_result);
end;
/

wrong number or types of arguments in call to my procedure

hi I wrote this code to create a procedure to return a Boolean value based on the if conditions but when I execute it I got this error:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'DDPAY_SP'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
here is my procedure
create or replace procedure DDPAY_SP (
donor_id dd_donor.iddonor%type,
pldgstatus out dd_pledge.idstatus%type,
monthplan out dd_pledge.paymonths%type,
ret out boolean)
IS
begin
select idstatus, paymonths into
pldgstatus, monthplan from dd_pledge
where iddonor = donor_id ;
if (pldgstatus = 10 AND monthplan >0)
then ret:= true;
else
ret:= false;
end if;
end;
and this how I execute it
EXECUTE DDPAY_SP (308);
I didn't put much talk I hope it's clear enough for you
I read online it recommends me to check the naming also the data type which I did but nothing change
any ideas
If you don't need the second and third arguments you could declare those as variables in the procedure instead of arguments, as follows:
CREATE OR REPLACE PROCEDURE DDPAY_SP(DONOR_ID IN DD_DONOR.IDDONOR%TYPE,
RET OUT BOOLEAN)
IS
nPayment_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO nPayment_count
FROM DD_PLEDGE p
WHERE p.IDDONOR = DONOR_ID AND
p.IDSTATUS = 10 AND
p.PAYMONTHS > 0;
IF nPayment_count > 0 THEN
RET := TRUE;
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('DD_PAY - exception: ' || SQLCODE || ' : ' || SQLERRM);
RAISE;
END DDPAY_SP;
I've included an example of an EXCEPTION handler at the end of DD_PAY. It's always a good idea to include at least this minimal handler so that in the event an exception occurs you'll get some indication of where the problem lies.
Because this procedure returns a BOOLEAN value, and BOOLEANs cannot (to the best of my knowledge) be used from SQL*Plus, you'll have to invoke it from a PL/SQL block, as follows:
DECLARE
bRetval BOOLEAN;
BEGIN
DD_PAY(308, bRetval);
DBMS_OUTPUT.PUT_LINE('Returned value is ' ||
CASE bRetval
WHEN TRUE THEN 'TRUE'
ELSE 'FALSE'
END);
END;
Give that a try.
EDIT: rewrote procedure based on further information from later comments.
Share and enjoy.

retrieve recordset with more than one column value using refcursor in oracle

am creating a package in pl/sql . with in this i declared the ref cursor . With in procedure am using select statement with multiple column name . but am not able to get the result.
here i attached my code. Help me to correct the error. Am new to pl/sql
code
CREATE OR REPLACE PACKAGE types AS
TYPE cursor_type IS REF CURSOR;
END Types;
/
CREATE OR REPLACE
PROCEDURE get_CDR_rs (p_no IN zkv.FLD_callingPartyNumber%TYPE,
CDR_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN CDR_recordset FOR
SELECT FLD_callingPartyNumber,
FLD_dateTimeConnect
FROM CISCOCUIC_TBL
WHERE FLD_callingPartyNumber= p_no
ORDER BY FLD_callingPartyNumber,;
END get_CDR_rs;
/
SET SERVEROUTPUT ON SIZE 1000000
DECLARE
l_cursor SYS_REFCURSOR;
l_callingPartyNumber zkv.FLD_callingPartyNumber%TYPE;
l_dateTimeConnect zkv.FLD_dateTimeConnect%TYPE;
BEGIN
LOOP
FETCH l_cursor
INTO l_callingPartyNumber, l_dateTimeConnect;
EXIT WHEN l_cursor%NOTFOUND;
END LOOP;
CLOSE l_cursor;
END;
/
Error
9/41 PL/SQL: ORA-00936: missing expression
5/5 PL/SQL: SQL Statement ignored
First thing is there is a syntax error in the procedure. It should be
CREATE OR REPLACE
PROCEDURE get_CDR_rs (p_no IN zkv.FLD_callingPartyNumber%TYPE,
CDR_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN CDR_recordset FOR
SELECT FLD_callingPartyNumber,
FLD_dateTimeConnect
FROM CISCOCUIC_TBL
WHERE FLD_callingPartyNumber= p_no
ORDER BY FLD_callingPartyNumber; -- there was a comma which is not required or you
-- missed a column
END get_CDR_rs;
/
Secondly where is get_CDR_rs being called to retrieve the results?
Thirdly why do you need the following? because you are using sys_refcursor
CREATE OR REPLACE PACKAGE types AS
TYPE cursor_type IS REF CURSOR;
END Types;
/
If you would like to see the results of your procedure which returns sys_refcursor, do as follows
variable rset refcursor;
DECLARE
p_no zkv.FLD_callingPartyNumber%TYPE;
BEGIN
p_no := '123';
get_CDR_rs (p_no, :rset);
END;
/
print rset

Resources