Using Functions in triggers - sql

I have created a function,which i think is right but im not sure how to call it in the trigger. I know the trigger is wrong but thats what i have tried
Function:
create or replace function log_in(pass in varchar2, user in varchar2)
return number
is
match_count number;
begin
select count(*)
into match_count
from Member
where username=user
and password=pass;
return match_count;
end;
Trigger:
create or replace TRIGGER PASSWORDCHECK
BEFORE INSERT OR UPDATE ON Login
FOR EACH ROW
DECLARE
usern VARCHAR2(12);
pass VARCHAR2(12);
result number;
BEGIN
usern := :new.username;
pass := :new.password;
/*Select LOG_IN(pass,usern)INTO result From MEMBER Where usern = Username;*/
result := LOG_IN(pass,usern);
If result = 1 THEN
dbms_output.put_line('Login Succesful');
ElsIF result = 0 THEN
dbms_output.put_line('Login Failed');
END IF;
END;

I'm assuming all login attempts fail?
USER is a keyword, which identifies the current schema:
SQL> select user from dual;
USER
------------------------------
REF
As it's unlikely any of your users have the same name as the schema your count is always returning 0.

Related

Using plsql, issue authentication number and check if it matches the input value

Use plsql.
If you receive your name, resident registration number, and phone number when you register as a member, you will generate 6 digits of the authentication code.
Enter 6 digits of the authentication code and pass if it matches the received authentication code.
I want to implement this, but there's an error.
Is there any way to handle it in one procedure? (It doesn't matter if there are multiple procedures. )
That's what I've done so far.
This is a procedure to verify that the authentication number matches.
create or replace procedure auth_check (
authen_send number, --receive code
authen_input number --input code
,authen_check out number --check
)
is
begin
if authen_send=authen_input
then authen_check := 1;
dbms_output.put_line('success');
else
authen_check := 0;
dbms_output.put_line('fail');
end if;
commit;
end;
This generates the authentication number at random.
var aucode number;
begin
select substr(ltrim( ltrim(dbms_random.value, '0.'),'0'),0,6)
into :aucode from dual;
end;
print aucode;
var inputcode number;
var check number;
exec auth_check(:aucode,&inputcode,:check);
Well, it is a bit confusing, but maybe it is an authentication system where you generate the number -> send it to the users (SMS maybe) -> ask to enter the number -> and check it... maybe this could help
-- Procedure
--
CREATE OR REPLACE PROCEDURE
AUTH_CHECK( authen_send IN number, --receive code
authen_input IN number, --input code
authen_check OUT number --check
) AS
BEGIN
authen_check := 0;
If authen_send = authen_input Then
authen_check := 1;
dbms_output.put_line('success');
Else
authen_check := 0;
dbms_output.put_line('fail');
End If;
END AUTH_CHECK;
--
-- Usage
--
SET SERVEROUTPUT ON
Declare
aucode NUMBER(6);
inputcode NUMBER(6);
chk NUMBER(1);
Begin
chk := 0;
Select
SubStr(LTrim(LTrim(DBMS_RANDOM.value, '0.'),'0'),0,6) InTo aucode
From dual;
auth_check(aucode, &inputcode, chk);
end;

when I am trying to create a log_in function?Why I have error Error(3,10): PLS-00215: String length constraints must be in range (1 .. 32767)

I am trying to create a function to verify log_in by return 0(zero) if the login failed, or 1(one) if the login was successful by matching cust_id and Passwd as parametrars and I have two questions:
Why I get error bad bind p_cust_id?
How to return 0 when it fail?
.
create or replace function log_in
(
p_cust_id varchar2,
p_paswd varchar2
) return number
as p_all varchar2;
begin
select cust_id,passwd
into p_all
from customer
where cust_id=p_cust_id and passwd=p_paswd;
return 1;
end;
first of all, you are trying to select 2 column but into 1 variable. this can't be possible. check my fix below
select cust_id,passwd
into variable1, variable2
from customer
where cust_id=p_cust_id and passwd=p_paswd;
for your second requirement, you need to add below line before end.
EXCEPTION WHEN NO_DATA_FOUND THEN
return 0;
END;
EDIT
Your procedure can also be rewritten as
CREATE OR REPLACE FUNCTION LOG_IN
(
P_CUST_ID VARCHAR2,
P_PASWD VARCHAR2
) RETURN NUMBER
AS P_COUNT NUMBER;
BEGIN
SELECT COUNT(*)
INTO P_COUNT
FROM CUSTOMER
WHERE CUST_ID=P_CUST_ID AND PASSWD=P_PASWD;
IF (P_COUNT > 0)
RETURN 1;
END IF;
RETURN 0;
END;

How to store result of a function which will return sysrefcursor?

Scenario: there is an procedure inside which we have a cursor.
I need to call a function which will take an input from that cursor value and will return SYS_REFCURSOR.
I need to store that result of function in a different variable/cursor & need to return this value from procedure as out parameter.
I am using Oracle 11g.
How can I proceed?
PFB My Approach:
create or replace procedure prc_test
(p_dept_id in number,
c_detail out sysrefcursor)--need to add extra out parameter
as
var1 varchar2(200) :=null;
begin
open c_detail for
select -1 from dual;
if p_dept_id is not null then
open c_detail for
select emp_no from emp
where dept_id=p_dept_id;
--i need to retrn value of 'get_emp_dtls' function as out parameter.
end if;
end procedure;
/
Function to be called
CREATE OR REPLACE FUNCTION get_emp_dtls
(p_emp_no IN EMP.EMP_NO%TYPE)
RETURN SYS_REFCURSOR
AS
o_cursor SYS_REFCURSOR;
BEGIN
OPEN o_cursor FOR
SELECT
ENAME,
JOB
FROM emp
WHERE EMP_NO = p_emp_no;
RETURN o_cursor;
-- exception part
END;
/
Here is your function that takes a varchar2 variable and returns A refcursor( weakly typed).
CREATE OR replace FUNCTION fn_return_cur(v IN VARCHAR2)
RETURN SYS_REFCURSOR
IS
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR
SELECT 'ABC'
FROM dual
WHERE 'col1' = v;
RETURN c1;
END;
/
Here is the procedure that has a cursor value passed as argument to function and the returned cursor passed as OUT argument.
CREATE OR replace PROCEDURE Pr_pass_out_cur(v_2 OUT SYS_REFCURSOR)
IS
func_arg VARCHAR2(3);
other_arg VARCHAR2(3);
CURSOR c_2 IS
SELECT 'ABC' col1,
'DEF' col2
FROM dual;
BEGIN
LOOP
FETCH c_2 INTO func_arg, other_arg;
EXIT WHEN c_2%NOTFOUND;
v_2 := Fn_return_cur(func_arg);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
/
Let me know your feedback.

how to make variable hold the value taken from one procedure to be used in another procedure in plsql

I have a package with two procedures
in same package.
p_set_values (pn_id_number IN number)
p_get_values (prc_records OUT sys_refcursor)
p_set_values (pn_id_number IN number)
inserts data in to my_table where id_number = pn_id_number
p_get_values (prc_records OUT sys_refcursor) - this procedure has to select the value from my_table where id_number = pn_id_number (Note: same id number which is used to insert the value ,now used to set the values inserted.)
I have declared package level variable and assigned as ln_id_number = pn_id_number.
Now when using this 'ln_id_number' in second procedure, the value of ln_id_number is nothing when checked using dbms_putput.putline(ln_id_number)
Please help me to do this,
Procedures are as follows
CREATE OR REPLACE PACKAGE BODY pck_exit_info
IS
ln_id_number po010.polref%TYPE;
PROCEDURE p_set_values(pn_id_number IN number
,pv_exit_option IN VARCHAR2)
IS
ln_system_date cs340.sysdte%TYPE;
lv_audaplcde package_audits.audit_application_code%TYPE;
ln_audstfno package_audits.audit_staff_number%TYPE;
ln_audupdid NUMBER;
lv_exit_option VARCHAR2(1);
BEGIN
ln_system_date := pck_system_context.f_get_system_date;
ln_id_number := pn_id_number;
dbms_output.put_line(ln_id_number);
SELECT AUDUPDID_SEQ.NEXTVAL INTO ln_audupdid FROM DUAL;
IF pv_exit_option = 'LE' THEN
lv_exit_option := 'L';
ELSE
lv_exit_option := 'S';
END IF;
SELECT audit_application_code,audit_staff_number
INTO lv_audaplcde,ln_audstfno
FROM package_audits
WHERE process = 'PCK_LEAVERS'
AND subprocess ='DEFAULT';
INSERT INTO my_table
VALUES(pn_id_number
,ln_system_date
,lv_exit_option
,ln_audupdid
,ln_system_date
,lv_audaplcde
,ln_audstfno);
END set_employer_exit_info;
PROCEDURE p_get_values(prc_records OUT SYS_REFCURSOR) IS
BEGIN
/*dbms_output.put_line('ID inside get employer');
dbms_output.put_line(ln_id_number);*/
OPEN prc_records FOR
SELECT *
FROM my_table
WHERE polref = ln_id_number;
-- CLOSE prc_policy;
END get_employer_exit_info;
END pck_exit_info;

PL SQL Function - How to call

I have a function in PL/SQL as follows (being used in Oracle APEX):
create or replace FUNCTION User_Levels(result OUT VARCHAR2)
RETURN VARCHAR2 IS
v_user_types employee.user_type%TYPE;
BEGIN
SELECT user_type
INTO v_user_types
FROM Employee
WHERE upper(username) = v('APP_USER');
IF v_user_types = 1
THEN
result := 'TRUE';
ELSE
result := 'FALSE';
END IF;
END User_Levels;​
How can I call this just to see its current output in normal SQL i.e. does it evaluate to True or False at the time it is run.
Do I really need the OUT parameter called result?
From SQL*Plus:
var result varchar2(10);
var rc varchar2(10);
exec :rc := user_levels(:result);
print rc
print result
However, your function is invalid because you have no return clause. Since the only thing you can return is result, having that as both an out parameter and the return value is redundant. Which you keep depends on how you want to use it, but I'd suggest a function is more flexible and appropriate here.
create or replace FUNCTION User_Levels
RETURN VARCHAR2 IS
v_user_types employee.user_type%TYPE;
BEGIN
SELECT user_type
INTO v_user_types
FROM Employee
WHERE upper(username) = v('APP_USER');
IF v_user_types = 1 THEN
RETURN 'TRUE';
ELSE
RETURN 'FALSE';
END IF;
END User_Levels;​
/
... assuming v('APP_USER') does something sensible. You can then just do:
select user_levels from dual;
Should work. Typically, you would create a variable (like v_user_types) and return that (p_result). Also, you need to make sure that your v('APP_USER') is also uppercase.
Additionally, you can not run this from a SQL*PLUS or any command prompt as v('APP_USER') is application variable; therefore, you have to test this on an APEX page.
create or replace FUNCTION User_Levels(p_result OUT VARCHAR2)
RETURN VARCHAR2 IS
v_user_types employee.user_type%TYPE;
p_result VARCHAR2(10);
BEGIN
SELECT user_type
INTO v_user_types
FROM Employee
WHERE upper(username) = v('APP_USER');
IF (v_user_types = 1) THEN
p_result := 'TRUE';
ELSE
p_result := 'FALSE';
END IF;
RETURN p_result;
END User_Levels;​