Procedure conversion in Oracle - oracle

I am a new member here so apologies from me if i am not able to follow the rules here.
I am using Oracle 11g express edition along with pl/sql. I am trying to convert a database of sql server in oracle 11g. So far i have done everything.
But now i am trying to convert procedures. I have done all changing but still i am not able to make procedures completely.
This is code of procedure in SQL server:
create proc Result_proc
#name varchar(40),
#Test varchar(40)
as
(
select * from [Result View] where ([Student Name] = #name AND Test# IN (#Test))
)
Converted code in ORACLE:
create or replace procedure Result_proc (
p_name varchar2,
p_Test varchar2)
as
begin
(
select * from ahmad where (Student_Name = p_name AND Test# IN (p_Test))
)
end;
Here in the image you see when i run the converted code in PL/SQL it is not executed properly:Output of CONVERTED proc in PL/SQL
Output:
SQL> 10

In SQL Server this stored procedure means 'return result of this select statement to the client'. It's common way in MSSQL to return recordsets.
When using Oracle, default way of do this is to use ref cursor output parameter. This procedure should be converted in something similar to
create procedure Result_Proc(p_Name varchar2, p_Test varchar2, p_Result out sys_refcursor) is
begin
open p_result for
select * from "Result View" where student_name = p_Name and test# = p_Test;
end;
But generally better way is to drop such junk procedures at all. Unlike MSSQL, Oracle does not require such select SPs as security call. More powerful and handy method is to just select what you need directly.

Related

Oracle Procedure to call with list from Microsoft Report Builder/Power BI Builder

I want to create a report in Microsoft Report Builder where the user can choose multiple values as input parameters. These should be used to call a procedure on an oracle database with the choosen values as a parameter.
I was able to create the report and the procedures, but only with a single value:
create or replace PROCEDURE TEST_PROCEDURE1
(
PARAM1 IN VARCHAR2,
cursorParam OUT SYS_REFCURSOR
) AS
BEGIN
OPEN cursorParam FOR
select distinct column_value from table(sys.odcinumberlist(1,1,2,3,3,4,4,5))
WHERE column_value IN (PARAM1);
END TEST_PROCEDURE1;
I can call the procedure from Microsoft Report Builder, and directly like this:
var c refcursor;
EXECUTE test_procedure1(PARAM1 => '2', cursorParam => :c);
print c;
I tried to change this to a multiple input type like this:
CREATE OR REPLACE TYPE PARAM_ARRAY1 IS TABLE OF VARCHAR2(30);
And the updated procedure:
create or replace PROCEDURE TEST_PROCEDURE2
(
PARAM1 IN PARAM_ARRAY1,
cursorParam OUT SYS_REFCURSOR
) AS
BEGIN
OPEN cursorParam FOR
select distinct column_value from table(sys.odcinumberlist(1,1,2,3,3,4,4,5))
WHERE column_value IN (SELECT * FROM table(PARAM1));
END TEST_PROCEDURE2;
I get an error from Microsoft Report Builder stating "Unsupported PL/SQL-Datentyp at parameter position 1" (I had to translate it from german, I'm not sure what the exact wording in english would have been).
How can I verify this from the Oracle SQL Developer? I can't figure out the correct way to test the procedure without the Microsoft Report Builder. This call fails:
var c refcursor;
EXECUTE test_procedure2(PARAM1 => ('1', '2'), cursorParam => :c);
print c;
What is the correct way to change the parameter in the procedure? Create a new TYPE, but as a TABLE or a VARRAY or something else?

PLSQL Get All table Data

I have a function in PLSQL and trying to call it from PowerBI which I finally got it to work.
Currently to return a tables columns, I need to manually specify the types. Is there a way to simply edit this code to return all columns of any given table?
Meaning that given this script, I only need to change the name of the table in the script and it should give me all the data.
I have to use PLSQL for this as there are some Auth protection to query tables which I cant simply query from PowerBI.
Drop Type VW_PEOPLE_TABLE;
Drop Type VW_PEOPLE_TYPE;
Drop Function TESTPOWERBI;
Drop Public Synonym PBI;
CREATE TYPE VW_PEOPLE_TYPE AS Object
{
Name VarChar2(70).
ALIAS VarChar2(90)
};
/
Create Type VW_PEOPLE_TABLE as TABLE OF VW_PEOPLE_TYPE;
/
Grant execute on VW_PEOPLE_TABLE TO public;
Create Function TESTPOWERBI
Return VW_PEOPLE_TABLE Pipelined AUTHID current_user AS VWT VW_PEOPLE_TABLE;
Pragma AUTONOMOUS_TRANSACTION;
Begin
Select VW_PEOPLE_TYPE(NAME,ALIAS)
Bulk COLLECT INTO VWT
FROM mytable;
FOR I IN 1 .. VWT.count
LOOP
PIPE ROW(VW_PEOPLE_TYPE(VWT(I).NAME, VWT(I).ALIAS));
END LOOP;
END TESTPOWERBI;
/
create public synonym PBI for TESTPOWERBI;
Grant Execute on PBI to public;
EDIT : as per this powerBI community post :
You should be able to achieve it using a procedure like this.
CREATE OR REPLACE PROCEDURE get_query_result (
p_tab_name VARCHAR2,
p_rc OUT SYS_REFCURSOR
) AS
BEGIN
OPEN p_rc FOR 'select * FROM '
|| p_tab_name;
END;
/
In Oracle environment, If you are using Oracle 12c and above, you may use DBMS_SQL.RETURN_RESULT with a dynamic REFCURSOR.
CREATE OR REPLACE PROCEDURE get_query_result (
p_tab_name VARCHAR2
) AS
rc SYS_REFCURSOR;
BEGIN
OPEN rc FOR 'select * FROM '
|| p_tab_name;
dbms_sql.return_result(rc);
END;
/
Get the query result for any table using
EXEC get_query_result('EMPLOYEES');

To get data from Stored Procedure having without parameter

I have a stored procedure proc1 without parameters. I want to extract data from this stored procedure. How can I get that? Could you help me?
Stored procedure:
create procedure proc1
as
begin
select e_id, e_nm, e_sal
from emp
where e_id like 'e%';
end proc1;
You can do this in Oracle 12.1 or above:
create or replace procedure demo
as
rc sys_refcursor;
begin
open rc for select * from dual;
dbms_sql.return_result(rc);
end demo;
This requires an Oracle 12.1 or later client/driver to handle the implicit result set.
For more details, see Implicit Result Sets in the Oracle 12.1 New Features Guide, Tom Kyte's Blog, Oracle Base etc.
Here's one possible solution:
Declaration:
create procedure proc1 (emp_row IN OUT emp%rowtype)
as
begin
select * --e_id, e_nm, e_sal
into emp_row
from emp
where e_id like 'e%';
end proc1;
Use case:
DECLARE
l_emp_row emp%rowtype;
BEGIN
proc1(l_emp_row);
-- Here you can access every column of table "emp", like so:
-- dbms_output.put_line('e_id: ' || to_char(l_emp_row.e_id));
-- dbms_output.put_line('e_nm: ' || to_char(l_emp_row.e_nm));
-- dbms_output.put_line('e_sal: ' || to_char(l_emp_row.e_sal));
END;
Is there anything special that you need to get out of the Procedure?
Cheers
you create a view this query. (recomended)
Oracle procedure is not return any data. So, you do not see any result. Your result get buffer but not print screen. if You need a procedure, insert all data another table.
create procedure proc1
as
begin
insert into new_table select e_id, e_nm, e_sal from emp where e_id like 'e%';
end proc1;
Another way; You create a function. Because function outputs and inputs. This function;
for example Create an Oracle function that returns a table

Not able to get the correct column names of CLOB type columns despite using DBMS_LOB.substr(myColumn, 3000)

I am using Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production . I have two columns declared as CLOB in a table and I want to read the data from the table using SYS_REFCURSOR. But I am getting the correct data and column names from all the columns except the columns that declared as CLOB. The following is my stored procedure:
create or replace
procedure ZSPPQCSGAPHISTORY
(
P_MEMBERID in types.char20,
P_CAREGAPCODE in types.char90, cur in out SYS_REFCURSOR
)
authid current_user
as
begin
open cur for select
A.MEMBERID,
A.CAREGAPCODE,
A.RATINGPERIOD,
A.DISCUSSEDDATETIME,
A.DISCUSSEDUSERID,
A.COMPLETEDDATE,
DBMS_LOB.substr(A.CALLSCRIPT, 3000),
DBMS_LOB.substr(A.NOTES, 3000)
from PQCSCGAP A
where A.MEMBERID=P_MEMBERID
and A.CAREGAPCODE=P_CAREGAPCODE order by DISCUSSEDDATETIME desc;
end;
I am using DBMS_LOB.substr(myColumn, 3000) to read the data, but still I am not getting the correct column names from the columns declared as CLOB type. Any ideas on how to tackle this issue?
You should give alias in the select statement like: DBMS_LOB.substr(A.CALLSCRIPT, 3000) as CALLSCRIPT, – Mottor
It's my mistake that I haven't used Alias names for the column of CLOB type.So, The following modified stored procedure works:
create or replace
procedure ZSPPQCSGAPHISTORY
(
P_MEMBERID in types.char20,
P_CAREGAPCODE in types.char90, cur in out SYS_REFCURSOR
)
authid current_user
as
begin
open cur for select
A.MEMBERID,
A.CAREGAPCODE,
A.RATINGPERIOD,
A.DISCUSSEDDATETIME,
A.DISCUSSEDUSERID,
A.COMPLETEDDATE,
DBMS_LOB.substr(A.CALLSCRIPT, 3000) AS CALLSCRIPT,
DBMS_LOB.substr(A.NOTES, 3000) AS NOTES
from PQCSCGAP A
where A.MEMBERID=P_MEMBERID
and A.CAREGAPCODE=P_CAREGAPCODE order by DISCUSSEDDATETIME desc;
end;

Oracle stored procedure to return a list of ids

I'm trying to convert an sql stored procedure to oracle. It's a very trivial procedure. It just returns a list of ids from a table, which is very easy to do in sql.
SQL
CREATE PROCEDURE [dbo].[tspInstalledLanguages]
AS
BEGIN
SELECT language_id from languages
END
I'm a complete novice when it comes to oracle, and I've learned that it's not as straight forward as this.
I've tried the following:
Oracle
CREATE OR REPLACE PROCEDURE tspInstalledLanguages
AS
BEGIN
SELECT LANGUAGE_ID FROM LANGUAGES;
END;
With no luck.
I get a message that it's expecting select into
It is.
Example:
DECLARE
v_authName author.author_last_name%type;
BEGIN
SELECT author_last_name
INTO v_authName
FROM author
WHERE author_key = 'A103';
dbms_output.put_line('Name: '||v_authName);
END;
/
So using your code:
CREATE OR REPLACE PROCEDURE tspInstalledLanguages
IS
v_language NUMBER;
BEGIN
SELECT LANGUAGE_ID
INTO v_language
FROM LANGUAGES;
dbms_output.put_line(v_language);
END;
/

Resources