views:

287

answers:

3

I misremembered what the key was for this Templates table and therefore I added the wrong field as a foreign key. Now I need to add the foreign key and I want to populate its values based on this other field that is already populated. I started trying to do this with an update statement, but I'm not sure how to do it.

Part of my schema:

Products Table:

ProductName (key)
TemplateName
TemplateID
...

I've added TemplateID, but it has no data in it yet and is nullable.

Templates Table:

TemplateID (key)
TemplateName
...

I want to use the Templates table to find the matching TemplateID for each TemplateName in the Products table and fill that in the foreign key reference in the Products table.

Can I do this with a subquery in Update, or do I need to write some kind of Stored Proc? I'm using Sql Server 2008

A: 
update Templates
set TemplateId=Products.TemplateId
from Templates
inner join Products
   on Templates.TemplateName=Products.TemplateName
JoshBerke
You can simply specify FROM products, instead of FROM templates with a join on Products, like I've posted. /)
Frederik Gheysels
I think its just a matter of preference I'm used to doing it this way. I',m not positive but I don't think there is any difference in execution plans
JoshBerke
+2  A: 

You can do it with a simple UPDATE query

UPDATE Products
SET Products.TemplateID = Templates.TemplateID
FROM Templates
WHERE Templates.TemplateName = Products.TemplateName

You do not need to specify the Products table in the FROM clause, nor a JOIN clause. Just specify the Templates table in the FROM clause. You can use the tablename you use in the UPDATE clause in the WHERE clause, to correlate recordds from both tables.

Frederik Gheysels
Thanks. Didn't think about doing it that work. Don't know why. I've never thought of using more than one table in an update statement.
Tony Peterson
using a join is safer, then you can alias the update part and can never accidentally udate everything when someone only highlights the first two lines before executing.You are doing a join anyway why not be specific so it is clear for maintenance as well.
HLGEM
If only the first 2 lines are selected when executing, an error will be given, since the Templates table is never 'defined' in the SQL statement. :)
Frederik Gheysels
+1  A: 

Here's a join solution. It's significant in that only the matched rows will be updated.

Update p
Set p.TemplateId = t.TemplateId
From Products p
  join Templates t
  On p.TemplateName = t.TemplateName

Here's the subquery solution. Every row of Products will be updated, even when there is no match.

Update p
Set p.TemplateId =
(
  Select t.TemplateId
  From Templates t
  Where p.TemplateName = t.TemplateName
)
From Products p
David B
The subquery solution is a good one for cross-DB SQL generation, because it's structurally different from what works in Oracle or DB2, for example, in just 2 places (right after "Update" and at the end). It helped me fix a bug today.