Update 2 joined tables simultaneously on HANA? - hana

Can I update 2 columns from 2 tables joined by foreign key with one statement in SAP HANA

No, SAP HANA up to its current version HANA 2 SPS 05 does not support multi-table updates (or inserts/deleted for that matter).
Depending on the use-case, you may be able to emulate the behavior via SQLScript, like e.g. so:
DO BEGIN
data_to_insert = SELECT id, stuff FROM DB;
-- update table 1
UPDATE tab1 t FROM t, :data_to_insert d
SET t.one_stuff = d.stuff
WHERE t.id = d.id;
-- update table 2
UPDATE tab2 t FROM t, :data_to_insert d
SET t.two_stuff = d.stuff
WHERE t.id = d.id;
END;

Related

Join only selected tables

I have A table, B table 10 different tables(1,2,3,..10). I have to select the data by joining any one/more of those 10 , A, and B tables based on the input.
Ex: If input is only 2,5,8,10 I have to join A, B, 2,5,8, and 10 tables and retrieve the data. If input is only 1 and 7th table , I have to join A , B, 1, and 7 tables and retrieve the data.
---- sample-----
suppose A is a person table with p_id, p_name, order_id,.......
B is an order table with Order_id,.........
each 1-10 tables are shopping items like clothes, shoes, electronics,...etc
now I want to pull person details who orders only clothes and shoes with some other constraints like within these dates or age should be 20 like that
then I have to join only person table, order table, clothes table, and shoe table and retrived the details about the persons who ordered atlease one of both the tables. person having only shoe or only colthes are not required. result will be like how many clothes he orderd and how many shoes he ordered.
Can anyone please give me some idea how to do it.
I am working on oracle db and using SQL.
This is sql-server syntax as far as variables but hopefully you can translate that to oracle variables. Anyway the trick is to use your input variables as conditions on a LEFT JOIN. That way if the condition for your variable is false it just wont return rows from that table. If true it will return matches. If you really want it to be an INNER JOIN rather than a LEFT JOIN then just put a case statement in your WHERE condition to make it true if your variable condition is met.
DECLARE #IncludeT1 BIT, #IncludeT2 BIT
SELECT *
FROM
TableA a
INNER JOIN TableB B
ON a.somecol = b.somecol
LEFT JOIN Table1 t1
ON a.somecol = t1.somecol
AND #IncludeT1 = 1
LEFT JOIN Table2 t2
ON b.somecol = t2.solmcol
AND #IncludeT1 = 1
WHERE
(CASE WHEN (#IncludeT1 = 1 and t1.someid IS NOT NULL) OR #IncludeT1 = 0 THEN 1 ELSE 0 END) = 1
AND (CASE WHEN (#IncludeT2 = 1 and t2.someid IS NOT NULL) OR #IncludeT2 = 0 THEN 1 ELSE 0 END) = 1
You can also do it via dynamic SQL as the other answer suggests there are more considerations if you go that route.
I don't think you can handle this with plain SQL. It looks like you need to use dynamic SQL. Have a stored procedure with parameters for the tables you need to join and then build your query based on how you call that procedure. Run the query with execute immediate... Read more here: https://docs.oracle.com/cloud/latest/db112/LNPLS/dynamic.htm#LNPLS011
Update: Here's a sample with pseudo plsql as I don't have your actual data. This is just to give you an idea on how to proceed - I can't write you actual code with the given information and your setup:
DECLARE
table1 VARCHAR2 (100) := 'Table1';
table2 VARCHAR2 (100) := '';
table3 VARCHAR2 (100) := 'Table2';
...
table10 VARCHAR2 (100) := 'Table10';
query VARCHAR2 (4000) := '';
BEGIN
--create the core join between A and B
query := query || 'select A.p_id, A.p_name, B.order_id from A, B where A.order_id = B.order_id ';
IF (table1 != '') THEN query := query || ' and a.id = table1.id ';
--if statements for the rest of your tables and add the join condition for each table to the query string
...
EXECUTE IMMEDIATE query; --run the query... depends on what you want to do with the returned result you can use RETURN INTO or BULK COLLECT INTO...
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (SQLERRM);
END;
Hope this helps...
It appears your 10 different tables are actually just 10 different categories of Products.
Is it possible to homogenise them all into one big Products table with an additional field for ProductCategory (clothes, shoes, electronics, etc)? Your assignment would then reduce to a simple WHERE on this ProductCategory field.
An equivalent (albeit less efficient) view can be achieved without modifying your schema by UNION-ing all 10 tables together, upon which you can draw your assignment.
I realise this does not directly answer your question, but this would drastically simplify your problem and normalise your database, thereby eliminating the need for a complicated solution (which is always the preferred way to go).
I think you should go for pipe lined function with dynamic sql.
e.g. you will create sql on the fly, execute it with execute immediate, return resuls row by row. Take a look here.
Note that there is no accepted answer, however I think
Vincent Malgrat's
approach will do just fine.

Multiple columns updation in single query

Can I update two columns in different tables with single update query.
I stuck in a situation where I have :
Table 1:
case id client id created by
1 a john
2 b Mike
3 c Raghu
4 b Mike
Table 2:
case id client id case cost
2 b 5,000
3 j 10,000
4 b 6,000
The problem is , I want to update client id=d in both the tables of those cases created by Mike.
I can fetch out those cases through join which is created by mike but is it possible to update them also by using sql joins??
The answer to more updates in one statement is no. While you can enter multiple tables in the from clause of an update statement, you can only specify a single table after the update keyword. Even if you do write a "updatable" view (which is simply a view that follows certain restrictions), updates like this will fail.
To fix this
Use transaction block:
Example :
BEGIN TRANSACTION
update A
set A.client_id = 'd'
from table1 A inner join table2 B
on B.client_id = A.client_id
where a.created_by='mike'
update B
set B.client_id = 'd'
from table2 B inner join table1 A
on B.client_id = A.client_id
where a.created_by='mike'
COMMIT
Probably something like this will work
UPDATE table1,table2 SET table1.client_id='d',table2.client_id='d'
WHERE table1.client_id=table2.client_id;
Since you mentioned RDBMS as MSSQL 2012; you can have only single update statement.
You can either have multiple in transaction block as mentioned in another answer (OR)
Create a procedure and wrap both your update statement there like
create procedure update_table1_table2
as
begin
UPDATE table1 SET client_id='d' WHERE client_id='b';
UPDATE table2 SET client_id='d' WHERE client_id='b';
end
Then call your procedure like
exec update_table1_table2

Oracle updating table based on a join

I have two tables
table 1 : rm_example(customer, weekno, salenum, card_type,...., imputed)
table 2 : rm_dummy(customer, weekno, imputed)
The imputed column in table one is null(all columns).
I want to set "imputed" column in table 1 with the value of "imputed" in table two where customer and weekno match....
below the query I wrote.....but it is taking forever to execute...
update rm_example e
set e.imputed =
(select imputed
from rm_dummy d
inner join rm_example e on e.customer=d.customer and e.weekno=d.weekno)...
Is something wrong with the query?
I am working on remote database using sqldeveloperplus...and we are talking about million rows.
MERGE is usually quite a bit faster than an UPDATE with a subquery (the syntax might seem a little bit weird, but you'll get used to it); this assumes rm_example has a primary key column PK:
MERGE INTO rm_example target
USING
(SELECT e.pk as e_pk,
d.imputed
FROM rm_dummy d
INNER JOIN rm_example e ON e.customer=d.customer AND e.weekno=d.weekno) src
ON (target.pk = src.e_pk)
WHEN MATCHED THEN UPDATE
SET target.imputed = src.imputed;
Not sure if it will be faster than what you have done already but you try this
UPDATE
(SELECT e.imputed, d.imputed
FROM rm_example e
INNER JOIN rm_dummy d ON e.customer = d.customer AND e.weekno = d.weekno)
SET e.imputed = d.imputed;
After reading 8 Bulk Update Methods Compared (Oracle) I see this is really a Deprecated method that a MERGE syntax should be used. But in saying that depending on your system this could possibly have better performance

Is there any RDBMS which supports inserting into joined tables? (multi-table inserts)

Example:
INSERT INTO table1 inner join table2 on table2.parent=table1.id values(...)
at least one. http://www.oracle-developer.net/display.php?id=209
..excerpt...
1 INSERT ALL
2 INTO t1
3 INTO t2
4 INTO t3
5 INTO t4
6 SELECT owner
7 , object_type
8 , object_name
9 , object_id
10 , created
11 FROM all_objects;
Use of views and triggers can do it as well. http://www.dbforums.com/microsoft-sql-server/663921-update-multiple-tables-via-view.html
....Excerpt from above...
CREATE TRIGGER trgInsteadOfUpdate ON dbo.Someview
INSTEAD OF UPDATE
AS
UPDATE Person
SET Person = inserted.Person_Name
FROM inserted
UPDATE Company
SET Company = inserted.Company_Name
FROM inserted
GO
There may be other ways; but that's the two I was aware of.
Make sure what you know is true. PostgreSQL supports writable multi-table views via its rule system.

Determining best method to traverse a table and update another table

I am using Delphi 7, BDE, and Interbase (testing), Oracle (Production).
I have two tables (Master, Responses)
I need to step through the Responses table, use its Master_Id field to look it up in Master table (id) for matching record and update a date field in the Master table with a date field in the Responses table
Can this be done in SQL, or do i actually have to create two TTables or TQueries and step through each record?
Example:
Open two tables (Table1, Table2)
with Table1 do
begin
first;
while not EOF do
begin
//get master_id field
//locate in id field in table 2
//edit record in table 2
next;
end;
end;
thanks
One slight modification to Chris' query, throw in a where clause to select only the records that need the update. Otherwise it will set the rest of the dates to NULL
UPDATE Master m
SET
m.date = (SELECT r.date FROM Reponses r WHERE r.master_id = m.id)
WHERE m.id IN (SELECT master_id FROM Responses)
Updated to use aliases to avoid confusion which col comes from which table.
This is not ready made, copy-past'able query as UPDATE syntax differs from database to database.
You may need to consult your database sql reference for JOIN in UPDATE statement syntax.
When there are multiple responses to same master entry
UPDATE Master m
SET m.date = (
SELECT MAX(r.date) FROM Reponses r WHERE r.master_id = m.id)
WHERE m.id IN (SELECT master_id FROM Responses)
I used MAX() you can use whatever suits your business.
Again invest some time understanding SQL. Its hardly a few days effort. Get PLSQL Complete reference if you are into Oracle
Try this SQL (changing names to fit your situation)
UPDATE Master m
SET date = ( SELECT date FROM Responses WHERE id = m.id )