Find the primary key on a table in oracle - oracle

I am trying to write a stored procedure to get all the dependencies on a table. Here is the code which I tried and I dont really get any output from it.
Tere are two blocks of cod. The first one is to get the FK and PK for this table. The second block gets the FK references from other tables.
I have taken table name and schema names as input and all the other variables as out. i was trying to make this code dynamic.

You use out variable in where clause:
and rowner is not null
and rconstraintname is not null
and rconstraintname in (select constraint_name from all_constraints) ;
It should be r_constraint_name and r_owner
In the second query add constraint_name in subquery:
and table_name = tablename
and constraint_name = ac.r_constraint_name)
And hear #WilliamRobertson ;)

Related

Using multiple select statement inside insert statement in Hive

I'm new in Hive. I have three tables like this:
table1:
id;value
1;val1
2;val2
3;val3
table2
num;desc;refVal
1;desc;0
2;descd;0
3;desc;0
I want to create a new table3 that contains:
num;desc;refVal
1;desc;3
2;descd;3
3;desc;3
Where num and desc are columns from table2 and refVal is the max value of column id in table1
Can someone guide me to solve this?
First, you have to create an table to hold this.
CREATE TABLE my_new_table;
After that, you have to insert into this table, as showed here
INSERT INTO TABLE my_new_table
[PARTITION (partcol1=val1, partcol2=val2 ...)]
select_statement1;
In the select_statement1 you can use the same select you would normally use to join and select the columns you need.
For more informations, you can check here

Temporary table for deletion

I have to use a PL_SQL anonymous block to delete rows in a lot of tables.
Every table is related to the main table "TABLE1", and I cannot add CASCADE DELETE. I have to do something like
DELETE FROM table2 WHERE foreign_key in (SELECT ID FROM table1 WHERE ...).
DELETE FROM table3 WHERE foreign_key in (SELECT ID FROM table1 WHERE ...).
...
The "SELECT ID.." query may take several minute, does it make sense to put all the ID in a temporary table or something like that? So I can execute the "select" query only once.
There are alternatives?
If
select id from table1 where ....
takes a lot of time, then it depends. The result will probably be cached so the next execution (while deleting from table3) won't last that long.
Won't cost much to test it. Delete a couple of tables the old way then create a "temporary" table using CTAS
create table ids as
select id from table1 where ...
and use it in DELETE statements. You don't even need an index as you have to perform full table scan anyway.
Then choose a better option.
Another way is the use of PL/SQL-Collections:
DECLARE
id_list SYS.ODCINUMBERLIST;
BEGIN
SELECT ID
BULK COLLECT INTO id_list
FROM table1
WHERE ...
FORALL i IN id_list.FIRST..id_list.LAST
DELETE FROM table2
WHERE foreign_key = id_list(i);
FORALL i IN id_list.FIRST..id_list.LAST
DELETE FROM table3
WHERE foreign_key = id_list(i);
...
END;

How to copy all constrains and data form one schema to another in oracle

I am using Toad for oracle 12c. I need to copy a table and data (40M) from one shcema to another (prod to test). However there is an unique key(not the PK for this table) called record_Id col which has something data like this 3.000*******19E15. About 2M rows has same numbers(I believe its because very large number) which are unique in prod. When I try to copy it violets the unique key of that col. I am using toad "export data to another schema" function to copy the data.
when I execute query in prod
select count(*) from table_name
OR
select count(distinct(record_id) from table_name
Both query gives the exact same numbers of data.
I don't have DBA permission. How do I copy all data without violating unique key of the table.
Thanks in advance!
You can use UPSERT for decisional INSERT or UPDATE or you may write small procedure for this.
you may consider to use NOT EXISTS, but your data is big and it might not be resource efficient.
insert into prod_tab
select * from other_tab t1 where NOT exists (
select 1 from prod_tab t2 where t1.id = t2.id
);
In Oracle you can use a MERGE query for that.
The following query proceeds as follows for each data row :
if the source record_id does not yet exist in the target table, a new record is inserted
else, the existing record is updated with source values
For the sake of the example, I assumed that there are two other columns in the table : column1 and column2.
MERGE INTO target_table t1
USING (SELECT * from source_table t2)
ON (t1.record_id = t2.record_id)
WHEN MATCHED THEN UPDATE SET
t1.column1 = t2.column1,
t1.column2 = t2.column2
WHEN NOT MATCHED THEN INSERT
(record_id, column1, column2) VALUES (t2.record_id, t2.column1, t2.column2)

PL/SQL create function with param for a check constraint

Given the syntax:
CREATE [OR REPLACE] FUNCTION [Owner.]FunctionName
[(arguments [IN|OUT|IN OUT][NOCOPY] DataType [DEFAULT expr][,...])]
RETURN DataType [InvokerRightsClause] [DETERMINISTIC]
{IS|AS}
I think my query is syntactically correct, but for some reason, I get these errors during compilation:
Error(6,5): PL/SQL: SQL Statement ignored
Error(8,34): PL/SQL: ORA-00942: table or view does not exist
CREATE or replace FUNCTION aCombinationMismatches(p_column1 IN VARCHAR2)
RETURN Number
IS
duplicate_count NUMBER(4,0);
BEGIN
select count(*) into duplicate_count
from schema1.tableA a
inner join schema1.tableB b
on a.b_id = b.id and a.column1 = p_column1
group by a.b_id, a.column1, a.column2, b.column1, b.column2, b.column3;
return duplicate_count;
END;
Anyone see anything wrong with my query above?
Also I'd like to how to set this UDF up to be used to create a CHECK constraint. How exactly do I specify the param: p_param1 to the function assuming this is the value of a field column1 in a row that a user is trying to insert? I just don't want the user to insert a record into tableA that consists of duplicate combinations of fields across tables: tableA and tableB.
Note: The tables tableA and tableB do exist - a select query like below indicates it. So the error above is rather confusing to me, I must add. (All table and column names in the two queries were found/replaced with dummy values.)
select count(*)
from schema1.tableA a
inner join schema1.tableB b
on a.b_id = b.id
group by a.b_id, a.column1, a.column2, b.column1, b.column2, b.column3;
Output:
Count(*)
OK, you already know that you have problem with priviliges. I wanted to add that you won't be able to create CHECK constraint basing on your function. According to documentation:
The condition of a check constraint can refer to any column in the table, but it cannot refer to columns of other tables.
Conditions of check constraints cannot contain the following constructs:
Subqueries and scalar subquery expressions
Calls to the functions that are not deterministic (CURRENT_DATE, CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER, and USERENV)
Calls to user-defined functions
So to achieve what you want, you would have to define some triggers, or make use of some combination of MATERIALIZED VIEW and CHECK constraint. See for example this discussion on Ask Tom
You probably have access to TableA and TableB through a Role. This means that you can query the table, but you cannot create a procedure that reads or writes that table. In order to compile your procedure you should at least grant select on the table to your user.
In the link below you'll find more info
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1065832643319

How to find dependency of a column

In oracle how can we find all the foreign key of a column.
Meaning to say in table info i have id column.
So how can I find who is referring id column.
Use the below query.
SELECT *
FROM user_constraints
WHERE r_constraint_name= '<constraint_name>';
Find the constraint name for your column, and then use the query below
SELECT table_name
FROM all_constraints
WHERE r_constraint_name = ConstraintName;

Resources