In my Storedprocedure , I want to move data from TableA, TableB and return a message that it is successfully copied.
Also I want to truncate TableB before moving data.
Following the SP I wrote, it gives me an error while truncating the table, how can I modify this to achieve this.
CREATE OR REPLACE PROCEDURE SP_MOVE_DATA
(
name IN VARCHAR2,
gender IN VARCHAR2,
city IN VARCHAR2,
OU_MSG OUT VARCHAR2
)
AS
BEGIN
DECLARE
BEGIN
execute immediate 'TRUNCATE table TableB';
INSERT INTO tableB(name, gender, city)
SELECT a.name, a.gender, a.city
from TableA a
where a.city in (select distinct city from ADDRESS where AREATYPE not in (4))
OU_MSG :='Successfully moved data';
COMMIT;
END;
END SP_MOVE_DATA ;
Related
I have like thousands tables, each of them will have their own unique key(s) columns. I want to select the keys based on the table name in a single query. Its always the second column in the table if it helps.
I want something like
select c_name from t_name
where c_name (is)
(
select column_name as c_name
from Dba_tab_Columns
where table_name = t_name
and column_name like '%name' --->>>(((or column_id =2)))
)
I know the t_name but I need a single query to select column name based on table_name.
So let say if I say select c_name from Animals, it should give me list of all animals and if I say select c_name from Cars, it should give me a list of avilable cars.
You cannot do this in pure SQL, you'll need a table function. Here's a way:
create or replace type tvc as table of varchar2(128);
/
create or replace function return_col (tname user_tables.table_name%type) return tvc pipelined
as
c_statement varchar2(400);
get_data sys_refcursor;
out_d varchar2(128);
begin
for gettnames_and_cols in (select c.column_name
from user_cons_columns c, user_constraints uc
where constraint_type in ('P','U') and uc.table_name=c.table_name and c.table_name=upper(tname)) loop
c_statement:='select '||gettnames_and_cols.column_name||' as output_col from '||tname;
open get_data for c_statement;
while true loop
fetch get_data into out_d;
exit when get_data%notfound;
pipe row(out_d);
end loop;
close get_data;
end loop;
return;
end;
/
Thing is that this just gives the data, with no idea what's the column_name or from which table the data comes. You can modify the PL/SQL code to add this info. Also, this assumes that the data will be returned as VARCHAR2(128), you may need to adapt this to your needs. You use this table function as follows:
select *
from table (return_col('your_table_name'));
I want to create PL/SQL stored procedure for following query:
SELECT order_id, order_date, customer_id
FROM Orders
INNER JOIN Customers ON Orders.customer_id = Customers.customer_id
WHERE order_id = xyz;
I want to pass order_id as input parameter in stored procedure.
Can someone please share the PL/SQL code for this?
Try this function
CREATE OR REPLACE FUNCTION fn_test(p1 IN NUMBER)
RETURN VARCHAR2
IS
s_query_stmt VARCHAR2(1000 CHAR);
r1 VARCHAR2(100 CHAR);
r2 VARCHAR2(100 CHAR);
r3 VARCHAR2(100 CHAR);
BEGIN
s_query_stmt := 'Select order_id, order_date, customer_id
From Orders inner join Customers
On Orders.customer_id = Customers.customer_id
WHERE order_id = :x )';
EXECUTE IMMEDIATE s_query_stmt INTO r1, r2, r3 USING p1;
return 'x';
END;
The most simple form of a procedure that would return those values is like this (:
create or replace procedure retrieve_order_values(
p_order_id IN Orders.order_id%type
, p_order_date OUT Orders.order_date%type
, p_customer_id OUT Orders.customer_id%type
)
is
begin
select order_date, customer_id
into p_order_date, p_customer_id
from orders
where order_id = p_order_id;
end retrieve_order_values;
Please note that you do not need the join to the Customers table to retrieve the customer_id.
I have function which returns sys_refcursor I give you my code's example.
function myfunc( p_city IN VARCHAR2,
p_order IN VARCHAR2)
RETURN SYS_REFCURSOR IS
v_result SYS_REFCURSOR;
begin
OPEN v_result FOR WITH all_prb AS(
select * from tableA ta inner join tableB tb)
'select * from all_prb ff where (:p_city is null or (LOWER(ff.city) like ''%''||:p_city||''%'') ) order by ' || p_order || 'asc' using p_city,p_city;
return v_result;
end myfunc;
and when i am trying to compile it i have ORA-00928: missing SELECT keyword and this error targets line where i have dynamic sql 'select * from all_prb ff where ...'
How can i fix it and how can i write correct dynamic sql ? I am writing dynamic sql for ordering .
I'm not sure why you're bothering with the with clause, it's simpler without a CTE; you just need to identify which table the city column is in:
function myfunc(p_city IN VARCHAR2,
p_order IN VARCHAR2)
RETURN SYS_REFCURSOR IS
v_result SYS_REFCURSOR;
begin
OPEN v_result FOR
'select * from tableA ta
inner join tableB tb on tb.some_col = ta.some_col
where :p_city is null or LOWER(ta.city) like ''%''||:p_city||''%''
order by ' || p_order || ' asc'
using p_city, p_city;
return v_result;
end myfunc;
/
I've guessed it's table A, just change the alias if it's the other one. You also need to specify the join condition between the two tables. (Also noticed I added a space before asc to stop that being concatenated into the order-by string).
This compiles without errors; when run I get ORA-00942: table or view does not exist which is reasonable. If I create dummy data:
create table tablea (some_col number, city varchar2(30));
create table tableb (some_col number);
insert into tablea values (1, 'London');
insert into tablea values (2, 'Londonderry');
insert into tablea values (3, 'East London');
insert into tablea values (4, 'New York');
insert into tableb values (1);
insert into tableb values (2);
insert into tableb values (3);
insert into tableb values (4);
then calling it gets:
select myfunc('lond', 'city') from dual;
SOME_COL CITY SOME_COL
---------- ------------------------------ ----------
3 East London 3
1 London 1
2 Londonderry 2
If you really want to stick with the CTE for some reason then (as #boneist said) that needs to be part of the dynamic statement:
OPEN v_result FOR
'with all_prb as (
select * from tableA ta
inner join tableB tb on tb.some_col = ta.some_col
)
select * from all_prb ff
where :p_city is null or LOWER(ff.city) like ''%''||:p_city||''%''
order by ' || p_order || ' asc'
using p_city, p_city;
I am trying to create a function which would return multiple rows.
Following is my function and type
create or replace type emp_type
(
first_name varchar2(20)
, last_name varchar2(20)
, depart_name varchar2(20)
)
/
create or replace function get_employee
(loc in number)
return emp_type
as
emp_record emp_type;
begin
select a.first_name, a.last_name, b.department_name into emp_record.first_name,
emp_record.last_name,emp_record.depart_name
from employees a, departments b
where a.department_id=b.department_id and location_id=loc;
return(emp_record);
end;
And I used
select get_employee(5) from dual;
I am getting "exact fetch returns more than requested number of rows " error.
Later when I used rownum<2 in the select query I got "Reference to uninitialized composite".
Could you please help?
Thanks in Advance
If you want to return a sys_refcursor, there is no reason to declare the object type or to try to return an object type. Just return a sys_refcursor.
create or replace function get_employee
(p_loc in number)
return sys_refcursor
as
l_rc sys_refcursor;
begin
open l_rc
for select a.first_name, a.last_name, b.department_name
from employees a,
departments b
where a.department_id=b.department_id
and location_id=p_loc;
return l_rc;
end;
How can I read a stored procedure from a .sql file? Example of this file's content:
create or replace procedure insert(p_t varchar(20), p_e varchar(10), out p_id number)
as begin
insert into instrument(type, status) values (p_t, p_e);
commit;
select max(id) from instrument into p_id;
end /
...other procedures...
I want this procedure to be created when I use the command #"filepath", but instead of doing so, Oracle executes the content of the procedure.
I would like to create all my procedures reading the file I made, any ideas?.
Firstly, please don't call your procedure INSERT. I'd be horrified if this actually compiled.
Secondly, you seem to be missing a semi-colon after end; and you need to put the / on a new line:
create or replace procedure insert_instrument (
p_t varchar(20), p_e varchar(10), out p_id number ) as
begin
insert into instrument(type, status) values (p_t, p_e);
commit;
select max(id) from instrument into p_id;
end;
/
You could simplify this using the RETURNING INTO clause; it saves an extra SELECT and so will operate quicker:
create or replace procedure insert_instrument (
p_t varchar(20), p_e varchar(10), out p_id number ) as
begin
insert into instrument(type, status)
values (p_t, p_e)
returning id into p_id;
commit;
end;
/