I would like to know how to use another table for authenticating.
As you can see I've got a table named 'vdv_medewerker', this table contains two columns, -gebruikersnaam- & -wachtwoord-. These fields are being validated on login, and it works.
Now what I would like to do is, I would like this authenticating script to use values from another table named 'vdv_klant', this table also includes a -gebruikersnaam- & -wachtwoord- column.
I've tried finding a solution online, but I didn't succeed.
CREATE OR REPLACE FUNCTION
custom_inlog(p_username IN VARCHAR2, p_password IN VARCHAR2)
RETURN BOOLEAN
AS
v_gebruikersnaam varchar2(30);
v_wachtwoord varchar2(30);
BEGIN
SELECT gebruikersnaam, wachtwoord
INTO v_gebruikersnaam, v_wachtwoord
FROM vdv_medewerker
WHERE UPPER(gebruikersnaam) = UPPER(p_username)
AND wachtwoord = p_password;
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN FALSE;
END;
Presumably your APEX authentication scheme has been set up to call your function above? So you can either just change your function to look at the new table, or you can create a new function based on the new table and change the APEX authentication scheme to call that instead of the old one:
To give an answer after reading the comments you gave in the meantime, here is a working version for your code:
CREATE OR REPLACE FUNCTION
custom_inlog(p_username IN VARCHAR2, p_password IN VARCHAR2)
RETURN BOOLEAN
AS
v_gebruikersnaam varchar2(30);
v_wachtwoord varchar2(30);
BEGIN
SELECT gebruikersnaam, wachtwoord
INTO v_gebruikersnaam, v_wachtwoord
FROM (
SELECT gebruikersnaam, wachtwoord FROM vdv_medewerker
UNION
SELECT gebruikersnaam, wachtwoord FROM vdv_klant
)
WHERE UPPER(gebruikersnaam) = UPPER(p_username)
AND wachtwoord = p_password;
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN FALSE;
END;
But in the longrun i would suggest using a predfined view and imrpove your database structure in the future.
Related
Coming from a sql server background, I am trying to get the grasp of oracle syntax. I am trying to return some records back from a stored procedure but getting an error:
CREATE OR REPLACE PROCEDURE SP_GetCustomers(username IN VARCHAR2)
AS
BEGIN
if username = 'all' then
select *
from customers c;
else
select *
from customers c
where c.created_by = username;
end if;
END;
What am I missing?
you are missing an INTO clause, but at this stage its better to use a FUNCTION to return values and a PROCEDURE to perform action.
ORACLE doesn't create implicit cursors as a return parameter, you will have to explicitly declare a ref cursor and open it to return a pointer to a cursor, something like:
CREATE OR REPLACE Function SP_GetCustomers(username IN VARCHAR2) return sys_refcursor
AS
ret_cursor sys_refcursor;
BEGIN
if username = 'all' then
open ret_cursor for
'select *
from customers c';
else
open ret_cursor for
'select *
from customers c
where c.created_by = :username' using username ;
end if;
return ret_cursor;
END;
Following function works with SQL Server.
CREATE FUNCTION GET_EMP_PROB_START_ATT_CODE(#EVAL_TYPE VARCHAR(6))
RETURNS #EMP_PROB_START_ATT_CODE TABLE (
PROBATION_START_ATT_CODE varchar(6) NULL
)
AS
BEGIN
IF #EVAL_TYPE='New'
INSERT INTO #EMP_PROB_START_ATT_CODE (PROBATION_START_ATT_CODE)
SELECT NEW_EMP_PROB_START_ATT_CODE FROM HS_HR_PEA_DYNAMIC_ATTRIBUTES;
ELSE
INSERT INTO #EMP_PROB_START_ATT_CODE (PROBATION_START_ATT_CODE)
SELECT EXIS_EMP_PROB_START_ATT_CODE FROM HS_HR_PEA_DYNAMIC_ATTRIBUTES;
RETURN;
END;
I just want to convert this to Oracle equivalent query . Tried but not succeeded.
CREATE FUNCTION GET_EMP_PROB_START_ATT_CODE(EVAL_TYPE VARCHAR(6))
RETURN EMP_PROB_START_ATT_CODE IS TABLE
PROBATION_START_ATT_CODE VARCHAR(6) NULL;
AS
BEGIN
IF EVAL_TYPE='New'
INSERT INTO EMP_PROB_START_ATT_CODE (PROBATION_START_ATT_CODE)
SELECT NEW_EMP_PROB_START_ATT_CODE FROM HS_HR_PEA_DYNAMIC_ATTRIBUTES;
ELSE
INSERT INTO EMP_PROB_START_ATT_CODE (PROBATION_START_ATT_CODE)
SELECT EXIS_EMP_PROB_START_ATT_CODE FROM HS_HR_PEA_DYNAMIC_ATTRIBUTES;
RETURN;
END;
Warning: compiled but with compilation errors
Any help guys..
First of all, create a database-wide type:
create type string_tab6 is table of varchar2(6);
Then you would create your function like so:
create or replace function get_emp_prob_start_att_code(eval_type varchar2)
return string_tab6
is
v_array string_tab6;
begin
if eval_type = 'New' then
select new_emp_prob_start_att_code
bulk collect into v_array
from hs_hr_pea_dynamic_attributes;
else
select exis_emp_prob_start_att_code
bulk collect into v_array
from hs_hr_pea_dynamic_attributes;
end if;
return v_array;
end get_emp_prob_start_att_code;
/
However, I would question why you need such a function. What are you going to use it for?
In Oracle, I'd expect to see that logic embedded directly into whichever SQL statement needs that info, which you could easily do via a case statement.
First define row type. For existing database table you can use %ROWTYPE.
Then define table type.
Finally use the table type as return type of the function.
TYPE tr_row IS my_table%ROWTYPE;
TYPE tab_row IS TABLE OF tr_row;
FUNCTION get_row RETURN tab_row IS
mytab tab_row;
BEGIN
SELECT * FROM my_table
BULK COLLECT INTO mytab;
RETURN mytab;
END;
Example in T-SQL (SQL Server - taken from here):
CREATE PROC proc_authors
#au_lname VARCHAR(40)
AS
SELECT
au_id, au_fname, au_lname, city, state
FROM authors
WHERE au_lname = #au_lname
go
Is it possible in Oracle to create a stored procedure that returns an inline table (without declaring a type - like the above)? If not, what would be the closest alternative? i.e. declare inline type, then use it. The idea is to minimize number of DB permissions that are granted.
Please include sample code as part of your answer.
Reasoning behind using stored procedure vs function - we have legacy software that can only execute stored procedures, or raw queries. It appears that only stored procedures in there have support for parameterized execution, which is what we are after.
try this with ref cursor
PROCEDURE proc_get_tada(ip_user IN VARCHAR2,
op_error_code OUT NUMBER,
op_cursor OUT SYS_REFCURSOR,) AS
BEGIN
OPEN op_cursor FOR
SELECT * FROM your_table yt where yt.user = ip_user;
EXCEPTION
WHEN OTHERS THEN
op_error_code := -1;
END proc_get_tada;
you will get collection of all data from you table you can iterate in java or calling program.
Maybe you are searching for something like this:
create table author
(
au_id number,
au_name varchar2(100)
);
insert into author (au_id, au_name) values(1, 'ME');
create or replace function getAuthor(auName varchar2)
return author%rowtype
is
retval author%rowtype;
begin
select * into retval from author where au_name=auName;
return retval;
end;
declare
auth author%rowtype;
begin
auth := getAuthor('ME');
dbms_output.put_line(auth.au_id);
end;
I am new to Oracle and Stored Procedures. I just would like to know if its possible, like in SQL Server, to return a recordset with Field Names to an extern program. I read some documentations but I'm not sure if I'm on the right track. When I use Sys_Refcursor I can only return one Field and not as many as I would like to.
I need to return multiple Field Names and I have one input parameter.
In the documentation of the program, i have an example for SQL Server and I would like to have the same for my Oracle Stored Procedure:
Use
Go
Set Ansi_Nulls ON
Go
Alter Procedure
#InputLocation Varchar(255)
As
Begin
Set Nocount On;
select FirstName as '#FirstName', Company as '#Company' from dbo.company where Location = #InputLocation
End
Are there any suggestions how I can do that? If you need some additional informations just let me know. Thanks.
/edit:
My sample Code (without using the Input Parameter in the first step, just for generating Output to see if it works):
create or replace
PROCEDURE TEST_PROZEDUR1 (
Input_Location IN Varchar2,
First_Name OUT SYS_Refcursor,
Company OUT Sys_Refcursor) IS
BEGIN
open First_Name For Select FirstName from dbo.company;
open Company For Select Company from dbo.company;
END TEST_PROZEDUR1;
The programming models used for PL/SQL and TSQL are different. Where you might return a recordset in TSQL, in PL/SQL you would return a cursor. A cursor is just a pointer to an SQL statement which is opened and can be read. It is not limited to returning a single column. Roughly, the PL/SQL equivalent of your TSQL procedure above would be something like:
CREATE OR REPLACE FUNCTION GET_INPUT_LOCATION(pinInput_location IN VARCHAR2(255))
RETURN SYS_REFCURSOR
IS
cCursor SYS_REFCURSOR;
BEGIN
OPEN cCursor FOR
SELECT FIRSTNAME,
COMPANY
FROM COMPANY
WHERE LOCATION = pinInput_location;
RETURN cCursor;
END GET_INPUT_LOCATION;
The caller would then invoke this function as:
DECLARE
cCursor SYS_REFCURSOR;
strFirstname COMPANY.FIRSTNAME%TYPE;
strCompany COMPANY.COMPANY%TYPE;
BEGIN
cCursor := GET_INPUT_LOCATION('SOMEWHERE OVER THE RAINBOW, INC.');
FETCH cCursor
INTO strFirstname,
strCompany;
CLOSE cCursor;
END;
However, I probably wouldn't code it this way. If COMPANY.LOCATION is unique then you're going to a lot of trouble to return a cursor which the caller will need to remember to close when they're done with it, which they may forget to do. Instead, I'd just return the FIRSTNAME and COMPANY fields using output parameters; e.g.
CREATE OR REPLACE PROCEDURE GET_INPUT_LOCATION
(pinInput_location IN VARCHAR2(255),
poutFirst_name OUT COMPANY.FIRSTNAME%TYPE,
poutCompany OUT COMPANY.COMPANY%TYPE)
IS
cCursor SYS_REFCURSOR;
BEGIN
SELECT FIRSTNAME,
COMPANY
INTO poutFirst_name,
poutCompany
FROM COMPANY
WHERE LOCATION = pinInput_location;
END GET_INPUT_LOCATION;
Share and enjoy.
We have one requirement to mask a particular table column using a Oracle function which gives persistent masked output string.
We tried Oracle Hash Function but it does not give String type return value.
We tried Oracle Random function (dbms_random.string) but it does not give Persistent output string.
I read on internet that this is called deterministic masking. But we do not want to use Oracle Enterprise Manager; however we require a direct Oracle function.
Please suggest.
This problem is easily solved in 12c with the function STANDARD_HASH.
The solution in previous versions is only slightly more complicated. Build a simple wrapper around DBMS_CRYPTO that acts just like STANDARD_HASH:
--Imitation of the 12c function with the same name.
--Remember to drop this function when you upgrade!
create or replace function standard_hash(
p_string varchar2,
p_method varchar2 default 'SHA1'
) return varchar2 is
v_method number;
v_invalid_identifier exception;
pragma exception_init(v_invalid_identifier, -904);
begin
--Intentionally case-sensitive, just like the 12c version.
if p_method = 'SHA1' then
v_method := dbms_crypto.hash_sh1;
--These algorithms are only available in 12c and above.
$IF NOT DBMS_DB_VERSION.VER_LE_11 $THEN
elsif p_method = 'SHA256' then
v_method := dbms_crypto.hash_sh256;
elsif p_method = 'SHA384' then
v_method := dbms_crypto.hash_sh384;
elsif p_method = 'SHA512' then
v_method := dbms_crypto.hash_sh512;
$END
elsif p_method = 'MD5' then
v_method := dbms_crypto.hash_md5;
else
raise v_invalid_identifier;
end if;
return rawToHex(dbms_crypto.hash(utl_raw.cast_to_raw(p_string), v_method));
end;
/
You may need to logon with SYS and grant your user access to DBMS_CRYPTO to make the function work:
grant execute on sys.dbms_crypto to <your_schema>;
Create a public synonym, grant it to everyone, and it works exactly the same way.
create public synonym standard_hash for <schema with function>.standard_hash;
grant execute on standard_hash to public;
select standard_hash('Some text', 'MD5') from dual;
9DB5682A4D778CA2CB79580BDB67083F
select standard_hash('Some text', 'md5') from dual;
ORA-00904: : invalid identifier
Here is a simple example of using the function:
update some_table
set column1 = standard_hash(column1),
column2 = standard_hash(column2);
But updating large amounts of data can be slow. It may be faster to create a new table, drop the old one, rename the new one, etc. And the hash value may be larger than the column size, it may be necessary to alter table some_table modify column1 varchar2(40 byte);
It amazes me how many products and tools there are to do such a simple thing.
If you looking something like mask the production data to move it into non-prod for integration testing. Below the "user defined" function would be helpful to you. This function will work only 10G and above.
create or replace function scrubbing(word in varchar2)
return varchar2
as
each_var char(2);
final_val varchar2(100);
complete_data varchar2(4000);
each_word varchar2(1000);
cursor val is select substr(replace(word,' ','#'),-level,1) from dual connect by level<=length(word);
begin
open val;
--final_val:= '';
loop
fetch val into each_var;
exit when val%NOTFOUND;
--dbms_output.put_line(each_var);
final_val := trim(final_val)||trim(each_var);
--dbms_output.put_line(final_val);
select regexp_substr(final_val,'[A-Za-z]+') into each_word from dual;
select replace(translate(final_val,each_word,dbms_random.string('L',length(word))),'#',' ') into complete_data from dual;
end loop;
return complete_data;
end;
In Oracle 12C dbms_redact.add_policy is available. It can be used to get the masked value in the select query itself.
You can use dbms_crpyto package of oracle , first you need to convert varchar2 type to raw then mask the data according to the hash value.