Unix Technical Forum

SEO

vBulletin Search Engine Optimization


Go Back   Unix Technical Forum > Database Server Software > Microsoft SQL Server > SQL Server

Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 05-10-2008, 02:12 PM
Leif Neland
 
Posts: n/a
Default updating multiple columns with subselect

This is not supported in MSsql.

update T1 set (theUpdatedValue, theOtherValue) =
(select theTop, theValue from T2 where T2.theKey = T1.theID)

Is there a workaround?

Other than doing it in a loop from eg asp, over either fields (one statement
per field), or over records (a query with a loop which for each row does a
select from one table, update other table with the selected values.)


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 05-10-2008, 02:12 PM
Dan Guzman
 
Posts: n/a
Default Re: updating multiple columns with subselect

> This is not supported in MSsql.
>
> update T1 set (theUpdatedValue, theOtherValue) =
> (select theTop, theValue from T2 where T2.theKey = T1.theID)
>
> Is there a workaround?


You can use the proprietary UPDATE...FROM syntax:

UPDATE T1
SET
theUpdatedValue = T2.theTop,
theOtherValue = T2.theValue
FROM T2
WHERE
T2.theKey = T1.theID

Or with an alias:

UPDATE a
SET
theUpdatedValue = b.theTop,
theOtherValue = b.theValue
FROM T1 a
JOIN T2 b ON
b.theKey = a.theID

--
Hope this helps.

Dan Guzman
SQL Server MVP
http://weblogs.sqlteam.com/dang/

"Leif Neland" <leif@neland.dk> wrote in message
news:4822d7e6$0$56781$edfadb0f@dtext02.news.tele.d k...
> This is not supported in MSsql.
>
> update T1 set (theUpdatedValue, theOtherValue) =
> (select theTop, theValue from T2 where T2.theKey = T1.theID)
>
> Is there a workaround?
>
> Other than doing it in a loop from eg asp, over either fields (one
> statement
> per field), or over records (a query with a loop which for each row does a
> select from one table, update other table with the selected values.)
>
>


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 05-10-2008, 02:12 PM
Plamen Ratchev
 
Posts: n/a
Default Re: updating multiple columns with subselect

On SQL Server 2005 you can use CTE to perform the update:

WITH UpdateSet
AS
(SELECT theUpdatedValue, theOtherValue, theTop, theValue
FROM T1
JOIN T2
ON T1.theID = T2.theKey)
UPDATE UpdateSet
SET theUpdatedValue = theTop,
theOtherValue = theValue;

HTH,

Plamen Ratchev
http://www.SQLStudio.com
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 05-10-2008, 02:12 PM
Leif Neland
 
Posts: n/a
Default Re: updating multiple columns with subselect


"Dan Guzman" <guzmanda@nospam-online.sbcglobal.net> skrev i en meddelelse
news:VyCUj.15179$V14.7043@nlpi070.nbdc.sbc.com...
> > This is not supported in MSsql.
> >
> > update T1 set (theUpdatedValue, theOtherValue) =
> > (select theTop, theValue from T2 where T2.theKey = T1.theID)
> >
> > Is there a workaround?

>
> You can use the proprietary UPDATE...FROM syntax:
>
> UPDATE T1
> SET
> theUpdatedValue = T2.theTop,
> theOtherValue = T2.theValue
> FROM T2
> WHERE
> T2.theKey = T1.theID
>

Thanks, worked perfectly.

Now I can update my system can be updated, so customers can order stuff for
both their loved ones, and their wives, without the ordrers getting mixed up
:-) (I had delivery adress in the customer table, not the order table)

Leif


Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 05-13-2008, 06:13 PM
--CELKO--
 
Posts: n/a
Default Re: updating multiple columns with subselect

The proprietary syntax does not work all the time:

CREATE TABLE Orders
(order_nbr INTEGER NOT NULL PRIMARY KEY,
some_col DECIMAL (9,2) NOT NULL);

INSERT INTO Orders VALUES (1, 0);
INSERT INTO Orders VALUES (2, 0);
INSERT INTO Orders VALUES (3, 0);

CREATE TABLE OrderDetails
(order_nbr INTEGER NOT NULL,
sku INTEGER NOT NULL,
item_price DECIMAL (9,2) NOT NULL,
PRIMARY KEY(order_nbr, sku),
-- FOREIGN KEY(sku) REFERENCES Products(sku)
FOREIGN KEY(order_nbr) REFERENCES Orders(order_nbr));

INSERT INTO OrderDetails VALUES (1, 1, 500.00);
INSERT INTO OrderDetails VALUES (1, 2, 205.00);
INSERT INTO OrderDetails VALUES (2, 1, 490.95);
INSERT INTO OrderDetails VALUES (3, 1, 480.00);

SELECT * FROM Orders;

UPDATE Orders
SET Orders.some_col = OrderDetails.item_price
FROM Orders
INNER JOIN
OrderDetails
ON Orders.order_nbr = OrderDetails.order_nbr;

results -- see item #1; last physical value
1 205.00 - where is the $500.00?
2 490.95
3 480.00

--repeat with new physical ordering
DELETE FROM OrderDetails;
DELETE FROM Orders;
DROP INDEX OrderDetails.foobar;

-- index will change the execution plan
CREATE INDEX foobar ON OrderDetails (order_nbr, item_price);

INSERT INTO Orders VALUES (1, 0);
INSERT INTO Orders VALUES (2, 0);
INSERT INTO Orders VALUES (3, 0);

INSERT INTO OrderDetails VALUES (1, 2, 205.00);
INSERT INTO OrderDetails VALUES (1, 1, 500.00);
INSERT INTO OrderDetails VALUES (2, 1, 490.95);
INSERT INTO OrderDetails VALUES (3, 1, 480.00);

UPDATE Orders
SET Orders.some_col = OrderDetails.item_price
FROM Orders
INNER JOIN
OrderDetails
ON Orders.order_nbr = OrderDetails.order_nbr;

SELECT * FROM Orders;

Results
1 500.00
2 490.95
3 480.00

What is the first property that you must have in an INDEX? It cannot
change the results of a statement, only the performance. See the
problem?

This would not have happened with the ANSI syntax. That's the point
that I am trying to make. The ANSI equivalent of the incorrect query
above is

UPDATE Orders -- no alias allowed!
SET some_col
= (SELECT item_price
FROM OrderDetails
WHERE OrderDetails.order_nbr = Orders.order_nbr)
WHERE EXISTS
(SELECT *
FROM OrderDetails
WHERE OrderDetails.order_nbr = Orders.order_nbr);

This will of course result in an error, and even the most junior of
junior programmers will eventually figure out (probably by asking a
senior) what's wrong. At that point, either the query is corrected to
match the request, or a note is sent back to management asking for a
clarification of the ambiguity in the request.

Bottom line: UPDATE FROM *can* be safely used - but only if you are
FOREVER certain that no single row in the target table can EVER be
joined to more than one row in the source table(s); FOREVER in the
ENTIRE LIFETIME of the application; FOREVER across all programmers yet
to come.

I like to err on the safe side, I do not bet only an endless stream of
100% perfect programmers. You correctly guessed the row constructor
syntax that is standard in ANSI/ISO SQL, by the way.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT. The time now is 04:47 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145