Oracle query to get the results of a particular table using the result obtained from another table - oracle

I am new to Oracle, so kindly bear with me if the question sounds really naive.
So, I have two tables TableA and TableB which have say just two columns id, name for simplicity.
I now want to now get the id value for a particular value of name in TableA. If this would be the only requirement, this query would suffice -
SELECT id from TableA WHERE name = 'some_name';
Now, what I want to do is take this id and delete all the rows in TableB that match this id-
DELETE FROM TableB WHERE id = <id obtained from the above query>;
What is the composite query in oracle that would perform this function?
Thanks!

If you know that only a single id value is going to be returned for a particular name value, you'd just do
DELETE FROM tableB b
WHERE b.id = (SELECT a.id
FROM tableA a
WHERE a.name = 'some_name')
Note that the aliases are optional. However, adding aliases generally makes things clearer so no one has to guess which id or which name you're referring to at any point.
If there might be multiple id values in tableA for a given name, you'd just use an IN rather than an =
DELETE FROM tableB b
WHERE b.id IN (SELECT a.id
FROM tableA a
WHERE a.name = 'some_name')
This would also work if you knew that the query against tableA was only going to return one row. I'd prefer the equality query if you're sure that only one row would be returned, though. I'd generally rather get an error if my expectations were violated rather than potentially having unexpected rows get deleted.

Related

Oracle SQL: Single Index with two Columns vs index on one Column

I'm using Oracle12c
I have a table with a primary key and separate column.
create tableB(
ID number(10)
,data number(10)
);
ID is my primary key.
I have to join 3 tables on my query and the performance issue is the B.data without an index.
B.data contains 'null' values and multiple entries on the same numbers.
select A.examp from tabled D
join tableb B on D.data = B.data
join tablec C on B.ID = C.ID
join tablea A on C.val = A.val
where D.ID = :value;
So my question is what is the difference between an index that contains only one value like the data column
create index ind_tableb on tableb (data);
and an index that contains multiple columns like
create index ind_tableb on tableb (data, id);
Can i get an improvement by selecting the id in the index with the data in the way i join the columns ?
Thanks for any advise and help.
For this particular query, you want the two column index version:
create index ind_tableb on tableb (data, id);
The above index, if used, would let Oracle rapidly lookup tabled.data values for a potential match with a tableb.data value. If a match be found, then the same index would also contain the tableb.ID value for the next join to tablec. If you just used the single column version on tableb.data alone, then Oracle would have to seek back to the tableb table to find the ID values. This could hurt performance and might even cause the index to not be used.

How to get distinct single column value while fetching data by joining two tables

$data['establishments2'] = Establishments::Join("establishment_categories",'establishment_categories.establishment_id','=','establishments.id')->where('establishments.city','LIKE',$location)->where('establishments.status',0)->whereIn('establishment_id',array($est_data))->get(array('establishments.*'));
this is controller condition.
I have two tables, in table1 i am matching id with table2 and then fetching data from table1, and in table2 i have multiple values of same id in table 1. i want to get data of table1 values only one time, but as i am hvg multiple data of same id in table2 , data is repeating multiple times, can anyone please tell me how to get data only one time wheater table2 having single value or multiple value of same id... thank you
you can do it by selecting the field name you desired
instead get all field from table establishments
$data['establishments2'] = Establishments::Join("establishment_categories",'establishment_categories.establishment_id','=','establishments.id')->where('establishments.city','LIKE',$location)->where('establishments.status',0)->whereIn('establishment_id',array($est_data))->get(array('establishments.*'));
you can select specific field from table establishments like
$data['establishments2'] = Establishments::Join("establishment_categories",'establishment_categories.establishment_id','=','establishments.id')->where('establishments.city','LIKE',$location)->where('establishments.status',0)->whereIn('establishment_id',array($est_data))->get('establishments.fieldName');
or you can also do
$data['establishments2'] = `Establishments::Join("establishment_categories",'establishment_categories.establishment_id','=','establishments.id')->where('establishments.city','LIKE',$location)->where('establishments.status',0)->whereIn('establishment_id',array($est_data))->select('establishments.fieldName')->get();`

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

oracle find difference between 2 tables

I have 2 tables that are the same structure. One is a temp one and the other is a prod one. The entire data set gets loaded each time and sometimes this dataset will have deleted records from the prior datasets. I load the dataset into temp table first and if any records were deleted I want to deleted them from the prod table also.
So how can I find the records that exist in prod but not in temp? I tried outer join but it doesn't seem to be working. It's returning all the records from the table in the left or right depending on doing left or right outer join.
I then also want to delete those records in the prod table.
One way would be to use the MINUS operator
SELECT * FROM table1
MINUS
SELECT * FROM table2
will show all the rows in table1 that do not have an exact match in table2 (you can obviously specify a smaller column list if you are only interested in determining whether a particular key exists in both tables).
Another would be to use a NOT EXISTS
SELECT *
FROM table1 t1
WHERE NOT EXISTS( SELECT 1
FROM table2 t2
WHERE t1.some_key = t2.some_key )
How about something like:
SELECT * FROM ProdTable WHERE ID NOT IN
(select ID from TempTable);
It'd work the same as a DELETE statement as well:
DELETE FROM ProdTable WHERE ID NOT IN
(select ID from TempTable);
MINUS can work here
The following statement combines results with the MINUS operator, which returns only rows returned by the first query but not by the second:
SELECT * FROM prod
MINUS
SELECT * FROM temp;
Minus will only work if the table structure is same

Is the first predicate in effect when I reference the first table after using a predicate to filter it, then in a second predicate on another table?

Using the Oracle VPD facility(aka RLS, aka FGAC), suppose that I use the predicate
(WHERE) id = 'XXXX'
on TableA and then I use the predicate
(WHERE) col in (SELECT col From TableA)
on TableB.
Will TableA be filtered or not? Is filtering is done only outside of predicate definitions, when you query the tables?
Will I need to make predicate on TableB like this?:
(WHERE) col in (SELECT col From TableA where id ='XXXX')
Yes, TableA will be automatically filtered using the predicate you specified (id = 'XXXX').
Oracle automatically applies the filters wherever you use (select from, in this case) the table, even in sub-queries, if the filter criteria is met (see sec_relevant_cols).

Resources