If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Data Access, Manipulation & Batch Languages > ANSI SQL > Update From

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 08-20-08, 08:06
gvee gvee is offline
www.gvee.co.uk
 
Join Date: Jan 2007
Location: UK
Posts: 10,002
Update From

Someone told me recently that UPDATE FROM is proprietary syntax and not the standard.

So what should be used instead?!

I'm mainly a Microsoft SQL Server user so my guess is that, as of version 2005, MERGE is the answer?
What about previous versions?
__________________
George
Twitter | Blog
Reply With Quote
  #2 (permalink)  
Old 08-20-08, 08:33
pootle flump pootle flump is offline
King of Understatement
 
Join Date: Feb 2004
Location: One Flump in One Place
Posts: 14,905
I forget the strinct standard syntax but I think it is a series of corrolated subselects. Try googling Celko on this - he is a strong proponent of the standard update syntax.

HTH until someone more standards literate than lil' ol' me comes along.
__________________
Testimonial:
Quote:
pootle flump
ur codings are working excelent.
Reply With Quote
  #3 (permalink)  
Old 08-20-08, 08:36
pootle flump pootle flump is offline
King of Understatement
 
Join Date: Feb 2004
Location: One Flump in One Place
Posts: 14,905
Blimey - check out all the luminaries in here for example:
http://www.eggheadcafe.com/software/...-sql-help.aspx
__________________
Testimonial:
Quote:
pootle flump
ur codings are working excelent.
Reply With Quote
  #4 (permalink)  
Old 08-21-08, 04:47
gvee gvee is offline
www.gvee.co.uk
 
Join Date: Jan 2007
Location: UK
Posts: 10,002
Wow, what a complicated premise... Let's see if I understand this:
Code:
USE playdb

CREATE TABLE table_1 (
   some_id     int         PRIMARY KEY
 , some_value  varchar(10)
 , other_value varchar(10)
)

CREATE TABLE table_2 (
   some_id     int         PRIMARY KEY
 , some_value  varchar(10)
 , other_value varchar(10)
)

SET NOCOUNT ON
  INSERT INTO table_1 (some_id, some_value, other_value)
        SELECT 1, NULL, 'a'
  UNION SELECT 2, NULL, 'b'
  UNION SELECT 3, NULL, 'c'

  INSERT INTO table_2 (some_id, some_value, other_value)
        SELECT 1, 'row 1', 'x'
  UNION SELECT 2, 'row 2', 'y'
  UNION SELECT 3, 'row 3', 'z'
SET NOCOUNT OFF

--SELECT * FROM table_1
--SELECT * FROM table_2

BEGIN TRAN --Proprietary UPDATE FROM syntax
  UPDATE table_1
  SET    some_value = t2.some_value
       , other_value = t2.other_value
  FROM   table_1 As [t1]
   INNER
    JOIN table_2 As [t2]
      ON t1.some_id = t2.some_id

  SELECT * FROM table_1
ROLLBACK TRAN

BEGIN TRAN --Still a FROM clause..?
  UPDATE table_1
  SET    some_value  = (SELECT some_value  FROM table_2 t2 WHERE t1.some_id = t2.some_id)
       , other_value = (SELECT other_value FROM table_2 t2 WHERE t1.some_id = t2.some_id)
  FROM   table_1 t1

  SELECT * FROM table_1
ROLLBACK TRAN

GO
DROP TABLE table_1
DROP TABLE table_2
__________________
George
Twitter | Blog
Reply With Quote
  #5 (permalink)  
Old 08-21-08, 05:32
pootle flump pootle flump is offline
King of Understatement
 
Join Date: Feb 2004
Location: One Flump in One Place
Posts: 14,905
I can't believe you used proprietary insert syntax too!!!1!
__________________
Testimonial:
Quote:
pootle flump
ur codings are working excelent.
Reply With Quote
  #6 (permalink)  
Old 08-21-08, 05:33
pootle flump pootle flump is offline
King of Understatement
 
Join Date: Feb 2004
Location: One Flump in One Place
Posts: 14,905
Ah - I believe this:
Code:
......
BEGIN TRAN --Still a FROM clause..?
  UPDATE table_1
  SET    some_value  = (SELECT some_value  FROM table_2 t2 WHERE t1.some_id = t2.some_id)
       , other_value = (SELECT other_value FROM table_2 t2 WHERE t1.some_id = t2.some_id)
  FROM   table_1 t1
should not include the bit in red to be ANSItastic.
__________________
Testimonial:
Quote:
pootle flump
ur codings are working excelent.
Reply With Quote
  #7 (permalink)  
Old 08-21-08, 05:55
stolze stolze is offline
Registered User
 
Join Date: Jan 2007
Location: Jena, Germany
Posts: 2,578
Quote:
Originally Posted by georgev
Wow, what a complicated premise... Let's see if I understand this:
Code:
USE playdb
There is no "USE" statement in standard SQL. So this is proprietary already.

Quote:
Code:
SET NOCOUNT ON
  INSERT INTO table_1 (some_id, some_value, other_value)
        SELECT 1, NULL, 'a'
  UNION SELECT 2, NULL, 'b'
  UNION SELECT 3, NULL, 'c'
I have no idea what this SET NOCOUNT ON should do. It isn't standard SQL. Also, statement terminators would be helpful to understand the code better (which is typically a good thing).

The INSERT statement itself doesn't make any sense. You have there "SELECT 1, NULL, 'a'" - select this FROM what? There is the FROM clause missing. You could simplify the multi-row insert to this:
Code:
INSERT INTO table_1 (some_id, some_value, other_value)
VALUES (1, NULL, 'a'),
       (2, NULL, 'b'),
       (3, NULL, 'c')
Quote:
Code:
  UPDATE table_1
  SET    some_value = t2.some_value
       , other_value = t2.other_value
  FROM   table_1 As [t1]
   INNER
    JOIN table_2 As [t2]
      ON t1.some_id = t2.some_id
First, I would remove the brackets around the tables' correlation names because they don't belong there.

Now let's try to read the statement (which is one of the things you can typically do with SQL):
Update "table_1" and set the value in columns "some_value" and "other_value".

Here we start stumbling: Now comes a "FROM" - it simply doesn't fit in the sentence, wouldn't you agree? Even more strange from a logical point of view is that "table_1" occurs in this FROM clause again.

What is more natural and straight-forward would be the following. You define which table shall be updated, calculate the new values and finally you restrict the rows on which the update shall take place.
Code:
UPDATE table_1 AS t1
SET    ( some_value, other_value ) = ( SELECT t2.some_value, other_value
                                       FROM table_2 AS t2
                                       WHERE t1.some_id = t2.some_id )
WHERE EXISTS ( SELECT 1
               FROM table_2 AS t2
               WHERE t1.some_id = t2.some_id )
Some other extensions (which may find their way into the standard) is this:
Code:
UPDATE ( SELECT t1.some_value, t1.other_value, t2.some_value AS new_some_value, t2.other_value AS new_other_value
         FROM table_1 AS t1 JOIN table_2 AS t2 ON WHERE t1.some_id = t2.some_id )
SET some_value = new_some_value, other_value = new_other_value
The DBMS builds a temporary table that does the join, then applies the update on this temporary table and maps it back to the underlying base tables or views. Of course, this will only work if such a mapping-back can be done in the first place and the columns being updated are updateable.
__________________
Knut Stolze
IBM DB2 Analytics Accelerator
IBM Germany Research & Development
Reply With Quote
  #8 (permalink)  
Old 08-21-08, 06:27
gvee gvee is offline
www.gvee.co.uk
 
Join Date: Jan 2007
Location: UK
Posts: 10,002
Happier syntax?
Code:
CREATE TABLE table_1 (
   some_id     int         PRIMARY KEY
 , some_value  varchar(10)
 , other_value varchar(10)
);

CREATE TABLE table_2 (
   some_id     int         PRIMARY KEY
 , some_value  varchar(10)
 , other_value varchar(10)
);

INSERT INTO table_1 (some_id, some_value, other_value)
VALUES (1, NULL, 'a');
INSERT INTO table_1 (some_id, some_value, other_value)
VALUES (2, NULL, 'b');
INSERT INTO table_1 (some_id, some_value, other_value)
VALUES (3, NULL, 'c');

INSERT INTO table_2 (some_id, some_value, other_value)
VALUES (1, 'row 1', 'x');
INSERT INTO table_2 (some_id, some_value, other_value)
VALUES (2, 'row 2', 'y');
INSERT INTO table_2 (some_id, some_value, other_value)
VALUES (3, 'row 3', 'z');

SELECT * FROM table_1;
SELECT * FROM table_2;

GO
DROP TABLE table_1;
DROP TABLE table_2;
I'm still struggling to get my head round the update logic - but this is probably down to the FROm method being embedded in my memory!

I'll give this a more thorough read later today, but I have a couple of minor questions that are somewhat unrelated from the UPDATE syntax.
Quote:
Originally Posted by stolze
I would remove the brackets around the tables' correlation names because they don't belong there.
Why should they be removed, I appreciate that they are not needed in this instance, is that the only reason or am I missing something?

Now this may be a large leap in logic, but I predict that the standard method over large resultsets, especially when updating more than one column at a time, could be less efficient than the prorietary method - is this assumption near true?
__________________
George
Twitter | Blog
Reply With Quote
  #9 (permalink)  
Old 08-21-08, 08:00
pootle flump pootle flump is offline
King of Understatement
 
Join Date: Feb 2004
Location: One Flump in One Place
Posts: 14,905
Stolze - I'm like George and predominantly use MS T-SQL and know little of the standard. Is this standard SQL?
Code:
UPDATE table_1 AS t1
SET    ( some_value, other_value ) = ( SELECT t2.some_value, other_value
                                       FROM table_2 AS t2
                                       WHERE t1.some_id = t2.some_id )
???
If so then the infamous UPDATE....FROM would be totally unnecessary if T-SQL supported the standard fully.

In case you are interested (bet you ain't) SET NOCOUNT ON just tells SQL Server not to count, and return, the number of rows affected by the proceeding statements.
__________________
Testimonial:
Quote:
pootle flump
ur codings are working excelent.
Reply With Quote
  #10 (permalink)  
Old 08-21-08, 08:59
stolze stolze is offline
Registered User
 
Join Date: Jan 2007
Location: Jena, Germany
Posts: 2,578
Quote:
Originally Posted by pootle flump
Stolze - I'm like George and predominantly use MS T-SQL and know little of the standard. Is this standard SQL?
Code:
UPDATE table_1 AS t1
SET    ( some_value, other_value ) = ( SELECT t2.some_value, other_value
                                       FROM table_2 AS t2
                                       WHERE t1.some_id = t2.some_id )
???
Yes, this is standard SQL.

Quote:
If so then the infamous UPDATE....FROM would be totally unnecessary if T-SQL supported the standard fully.
Updating multiple values as shown above is a bit independent from what UPDATE ... FROM tries to achieve. UPDATE ... FROM tries to avoid the necessity to specify the same subselect twice: once in the SET clause and once in the WHERE clause of an update statement. However, (and that answers georgev's question, too) any decent system detects that the same subselect has been used there and only executes it once. So the argument of being less efficient doesn't hold any water.
__________________
Knut Stolze
IBM DB2 Analytics Accelerator
IBM Germany Research & Development
Reply With Quote
  #11 (permalink)  
Old 08-21-08, 09:14
stolze stolze is offline
Registered User
 
Join Date: Jan 2007
Location: Jena, Germany
Posts: 2,578
Quote:
Originally Posted by georgev
Happier syntax?
[CODE]
INSERT INTO table_1 (some_id, some_value, other_value)
VALUES (1, NULL, 'a');
INSERT INTO table_1 (some_id, some_value, other_value)
VALUES (2, NULL, 'b');
INSERT INTO table_1 (some_id, some_value, other_value)
VALUES (3, NULL, 'c');
Yes, but too excessive executing 3 statements instead of just 1 ;-)

And the "GO" is also not standard SQL ;-)

Quote:
Why should they be removed, I appreciate that they are not needed in this instance, is that the only reason or am I missing something?
It's not standard SQL. A <correlation name> in a <from clause> is an <identifier>. What identifiers are is defined in subclause 5.4, "Names and identifiers" in the SQL standard (I'm looking at SQL:2003). There, an identifier is either a <regular identifier>, a <delimited identifier>, or a <unicode delimited identifier>. All delimited identifiers have to have double-quotes around them and unicode delimited identifiers have a leading 'U'. Only with delimited identifiers you could have a character like '[' in the identifier name. Since you don't have double-quotes there, it must be a regular identifier, in which case the first character must be one of (cf. Note 58 in SQL:2003 in subclause 5.2):
Quote:
upper-case letters, lower-case letters, title-case letters, modifier letters, other letters, and letter numbers
Only letters and numbers are mentioned there. Thus, the brackets are not part of the identifier (and you didn't use it as such). But the standard syntax says:
Quote:
<table or query name> [ [ AS ] <correlation name> [ <left paren> <derived column list> <right paren> ] ]
The ']' indicate optional arguments in the BNF notation and not characters that could by typed in. Thus, my take on this is that using "table_1 AS [t1]" is a proprietary product extension of T-SQL only.
__________________
Knut Stolze
IBM DB2 Analytics Accelerator
IBM Germany Research & Development
Reply With Quote
  #12 (permalink)  
Old 08-21-08, 09:48
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,084
Quote:
Originally Posted by stolze
Thus, my take on this is that using "table_1 AS [t1]" is a proprietary product extension of T-SQL only.
ding ding ding ding ding

we have a winnah!!!
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #13 (permalink)  
Old 08-28-08, 15:26
dportas dportas is offline
Registered User
 
Join Date: Dec 2007
Location: London, UK
Posts: 732
Quote:
Originally Posted by georgev
I'm mainly a Microsoft SQL Server user so my guess is that, as of version 2005, MERGE is the answer?
What about previous versions?
MERGE is the answer as from SQL Server 2008. It ought to make the atrocious and flawed UPDATE ... FROM obsolete. True, MERGE has a lousy syntax but it avoids the problems of Microsoft's UPDATE and in many cases MERGE is more efficient than the equivalent UPDATE ... FROM.
Reply With Quote
  #14 (permalink)  
Old 09-01-08, 05:09
stolze stolze is offline
Registered User
 
Join Date: Jan 2007
Location: Jena, Germany
Posts: 2,578
MERGE is standard SQL, too. ;-)
__________________
Knut Stolze
IBM DB2 Analytics Accelerator
IBM Germany Research & Development
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

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