Update database from another using joins? - sql

I am trying to update a table from another database using joins and having a hard time. This is what I am trying to do in pseudo:
UPDATE [Database1].[dbo].[Sessions]
SET [SpeakerID] = ?STATEMENT1?
WHERE ?STATEMENT2?
For "Statement1", this would be coming from another database and table that has columns: SessionID and SpeakerID. How can this be achieved?

UPDATE a
SET a.SpeakerID = b.colName -- SET valoue here
FROM Database1.dbo.Sessions a
INNER JOIN Database2.dbo.Sessions b
ON a.SessionID = b.SessionID -- assumes that their
-- relationship column is SessionID,
-- change it in your original columnName
WHERE ....
a and b are called alias. They are useful when you have longer source name.

UPDATE L
SET SpeakerID = R.SpeakerID
FROM dbo.LocalTable AS L
INNER JOIN RemoteDatabase.dbo.RemoteTable AS R
ON L.SomeValue = R.SomeValue;
This really is no different from this problem except you have to add a database prefix to one of the tables in the join.

try
UPDATE [Database1].[dbo].[Sessions]
SET
Sessions.col1 = other_table.col1
FROM
[Database1].[dbo].[Sessions] Sessions
INNER JOIN
[Database2].[dbo].other_table AS other_table
ON
Sessions.id = other_table.id
WHERE Sessions.id = ??
Note if the database is on another server you will need to create a linked server first
http://msdn.microsoft.com/en-us/library/ff772782.aspx

Related

Update field in a table on a database 1 from an external identical database 2

To keep this shot.
I would like to update a field of product_price with all prices where I keep on an external demo table.
I tried to use the following query but it's throwing error
UPDATE dest
SET product_price = src.product_price
FROM DB2.trades AS dest
INNER JOIN DB1.trades AS src
ON dest.KEY = src.KEY
--And KEY = '12323';
Could you please help with how to do this?
Presuming that table you're updating resides in database DB2 and "external" table resides in another database (DB1), you'll need to create a database link to DB1 (let's call it dbl_db1) and reference its table as trades#dbl_db1. Something like this:
update trades d set
d.product_price = (select s.product_price
from trades#dbl_db1 s
where s.key = d.key
)
where exists (select null from trades#dbl_db1 a
where a.key = d.key
);
Or, using MERGE:
merge into trades d
using trades#dbl_db1 s
on (s.key = d.key)
when matched then update set
d.product_price = s.product_price;

Is this questionable SQL Update syntax with aliased table correct?

I saw this SQL Update statement in a trigger and am unsure if the update works accurately - based on looking at where the table alias is and the update table syntax.
The syntax doesn't give any error on execution, and updates the record correctly when executing on random samples on my test DB.
However, on a larger PROD DB with more records, is there a possibility that the update fails or skips altogether? There were reports that random records did not have the SAMPLE.ISCOMPOSITESAMPLE field set.
Questionable syntax
UPDATE SAMPLE SET
SAMPLE.SAMPLETYPE = (SELECT DESCRIPTION FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO),
SAMPLE.ISCOMPOSITESAMPLE = (SELECT COMPOSITESAMPLE FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO)
FROM SAMPLE C
INNER JOIN INSERTED T ON C.SAMPLENO = T.SAMPLENO
Syntax I am familiar with (similar to above but intentionally not optimised for comparison)
UPDATE C SET
SAMPLETYPE = (SELECT DESCRIPTION FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO),
ISCOMPOSITESAMPLE = (SELECT COMPOSITESAMPLE FROM SAMPLETYPE WHERE SAMPLETYPENO = C.SAMPLETYPENO)
FROM SAMPLE C
INNER JOIN INSERTED T ON C.SAMPLENO = T.SAMPLENO
The query is correct and will work. However, there are two things that I would fix:
TheUPDATE SAMPLE does update the table whose alias is C. This is documented as correct and something that really irks me, because aliases should be respected. You should use the alias for the update.
The correlated subqueries are not using fully qualified column names.
So, using correlated subqueries, I would recommend:
UPDATE S
SET SAMPLETYPE = (SELECT ST.DESCRIPTION FROM SAMPLETYPE ST WHERE ST.SAMPLETYPENO = S.SAMPLETYPENO),
ISCOMPOSITESAMPLE = (SELECT ST.COMPOSITESAMPLE FROM SAMPLETYPE ST WHERE ST.SAMPLETYPENO = S.SAMPLETYPENO)
FROM SAMPLE S INNER JOIN
INSERTED I
ON S.SAMPLENO = I.SAMPLENO ;
You can also write this -- probably more efficiently -- using a LEFT JOIN:
UPDATE S
SET SAMPLETYPE = ST.DESCRIPTION,
ISCOMPOSITESAMPLE = ST.COMPOSITESAMPLE
FROM SAMPLE S INNER JOIN
INSERTED I
ON S.SAMPLENO = I.SAMPLENO LEFT JOIN
SAMPLETYPE ST
ON ST.SAMPLETYPENO = S.SAMPLETYPENO;

Oracle SQL - How do I update from an Outer Joined Table?

The Problem
I need to write an Update query where my SET references an outer joined table.
I can do this fairly easily with SQL Server but I'm having a heck of a time figuring out the syntax in Oracle as I'm only allow a single table in an update query.
I have written the following Oracle query:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
WHERE EXISTS (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
AND tmp.sysind = 'AIM';
This takes care of the intersection but I need to deal with values in SalesExt_tmp that do not have equivalent matches in dw_sls_rep_conv (I plan to add a case statement to set null values to a default value). To do this I need to set up dw_sls_rep_conv as an outer joined table. But this is where I get stuck.
SQL Server Example
In SQL Server the solution is a piece of cake as you can have multiple tables in an Update Query:
UPDATE SalesExt_tmp tmp
LEFT JOIN dw_sls_rep_conv sls ON sls.aims_rep = tmp.slsrep
SET tmp.slsrep = sls.three_dig_rep
WHERE tmp.sysind = 'AIM';
But I can't for the life of me figure out how to do this in Oracle. I understand that this query will allow my slsrep field to be set to NULL in some occasions which causes me to fear that this operation may not be allowed.
Questions
1) Firstly is this possible in Oracle? (It's got to be, right?)
2) How do I need to restructure my query to pull this off? I'm guessing my WHERE EXISTS clause needs to go... but I'm still stuck as to where to place my JOIN.
If I understood you correctly, you want to set the value to NULL if there is no match in the dw_sls_rep_conv table? If so, just drop your EXISTS condition and all the rows will be updated:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls
WHERE sls.aims_rep = tmp.slsrep)
WHERE tmp.sysind = 'AIM';
If there is a match in the dw_sls_rep_conv table, then the slsrep column will be updated with selected value, otherwise, with NULL.
Have you considered using a subquery in your where clause that performs the outer join as you stated like this:
UPDATE SalesExt_tmp tmp
SET slsrep = (SELECT three_dig_rep
FROM dw_sls_rep_conv sls WHERE sls.aims_rep = tmp.slsrep)
WHERE
tmp.rowid in
(SELECT tmp1.rowid
FROM SalesExt_tmp tmp1,
dw_sls_rep_conv sls
WHERE
tmp1.slsrep = sls.aims_rep (+)
AND tmp1.sysind = 'AIM' );

SQL Update with multiple INNER JOIN

I have two tables,
SELECT [SHADOW_ID]
,[DATA]
,[TSN]
,[HEALTH_PLAN_CATEGORY_VALUE_ID]
FROM [stbl834]
and
SELECT [HEALTH_PLAN_CATEGORY_VALUE_ID]
,[TSN]
FROM [uvwCLIENT_HEALTH_PLAN]
Right now HEALTH_PLAN_CATEGORY_VALUE_ID are all set to NULL in stbl834, I need to fetch these values from uvwCLIENT_HEALTH_PLAN based on different TSN values from stbl834. Is there a way to do this using JOIN statements? I need to avoid any sort of loops.
First run a select
SELECT *
FROM [stbl834] A
INNER JOIN [uvwCLIENT_HEALTH_PLAN] B ON A.TSN = B.TSN
and verify that you have correct number of rows and that the values in the columns match. this would ensure that you have a correct join key. If this looks correct use the below update
UPDATE [stbl834]
SET [HEALTH_PLAN_CATEGORY_VALUE_ID] = B.[HEALTH_PLAN_CATEGORY_VALUE_ID]
FROM [stbl834] A
INNER JOIN [uvwCLIENT_HEALTH_PLAN] B ON A.TSN = B.TSN
Select HEALTH_PLAN_CATEGORY_VALUE_ID, TSN
from stbl834 left join uvwCLIENT_HEALTH_PLAN
on stbl834.TSN=uvwCLIENT_HEALTH_PLAN.TSN
Do you need to insert them into stbl834? If so --
update stbl834
set HEALTH_PLAN_CATEGORY_VALUE_ID = uvwCLIENT_HEALTH_PLAN.HEALTH_PLAN_CATEGORY_VALUE_ID
from stbl834 left join uvwCLIENT_HEALTH_PLAN
on stbl834.TSN=uvwCLIENT_HEALTH_PLAN.TSN
Alternatively, you can do this for any RDBMS that does not support the UPDATE..FROM syntax:
UPDATE stbl834
SET health_plan_category_value_id = (SELECT health_plan_category_value_id
FROM uvwclient_health_plan
WHERE uvwclient_health_plan.tns = stbl834.tns)
This solution is SQL Ansi compatible, meaning it will work for any RDBMS. Please make sure the sub-query (SELECT) will only return record value for a given TNS, or else you will have to ensure that by using TOP or LIMIT (whatever is supported by your RDBMS).
You can try out this too, this might serve your purpose.
update stbl834
set stbl834.HEALTH_PLAN_CATEGORY_VALUE_ID= uvwCLIENT_HEALTH_PLAN.HEALTH_PLAN_CATEGORY_VALUE_ID
inner join uvwCLIENT_HEALTH_PLAN.TSN=HEALTH_PLAN_CATEGORY_VALUE_ID.TSN

Multiple Query Writing in Single Query

I have two tables in Database , I need to select a field from one table and update it in another table with a condition where id is same .. Is it Possible to write in single query ???
This should work for you:
update storage
set storage.email = (select register.email
from register
where register.id = storage.id)
Yeah it is, you could do this for example:
UPDATE Origin SET DesiredColumn = NewValue
FROM Origin
JOIN NewTable ON Origin.Id = NewTable.Id
And guess the column names were like DesiredColumn in the updating table and NewValue in the table that holds the new value.
Yes, this is possible, although the syntax depends on the type of SQL you are using.
Here is an example for T-SQL (for Microsoft SQL Server)
UPDATE
S
SET
Email = R.Email
FROM
dbo.Register R
INNER JOIN dbo.Storage S
ON S.RegisterID = R.RegisterID