Unix Technical Forum

SELECT works but UPDATE fails. ?

This is a discussion on SELECT works but UPDATE fails. ? within the SQL Server forums, part of the Microsoft SQL Server category; --> I should have said corelation name and not alias, since a lot of products have a CREATE ALIAS construct, ...


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

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #11 (permalink)  
Old 02-29-2008, 08:50 AM
--CELKO--
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

I should have said corelation name and not alias, since a lot of
products have a CREATE ALIAS construct, which the standards do not.

>> Interestingly this all falls apart on UPDATE/DELETE/INSERT target when one looks at updatable views which clearly are derived tables but do what one can reasonably expect: modify the "underlying" table. <<


One of the reasons for the weakness of UPDATE-able views in Standard
SQL was so that they could be defined as a base table with restrictions
on unexposed columns -- must have a DEFAULT, cannot be in the SET
clause, etc. The WITH CHECK OPTION is a real piece of work when you
have nested views and the CASCADE option.

Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #12 (permalink)  
Old 02-29-2008, 08:51 AM
Hugo Kornelis
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

On Fri, 3 Jun 2005 22:41:23 +0000 (UTC), Erland Sommarskog wrote:

>Hugo Kornelis (hugo@pe_NO_rFact.in_SPAM_fo) writes:
>> Erland already pointed out that the proprietary UPDATE FROM syntax
>> differs between products. However, why use proprietary code when you can
>> use ANSI-standard code that will work on almost all databases:
>>
>> update ded_temp
>> set balance = (select sum(b.ln_amt)
>> from ded_temp b
>> where ded_temp.cust_no = b.cust_no
>> and ded_temp.ded_type_cd = b.ded_type_cd
>> and ded_temp.chk_no = b.chk_no
>> group by cust_no, ded_type_cd, chk_no)

>
>Could you please explain what this miserable piece of code means? You
>have two ded_temp in the query, so which ded_temp does ded_temp.cust_no
>refer to?
>
>You will have to excuse, but I think it's poor advice to suggest that
>people should use code that is ambiguous. I don't really care if there
>is wording in ANSI that disamguiates the query, it's still bad practice,


Hi Erland,

Thanks for the feedback. As you know, I always welcome comments to the
posts I make in these groups - I'm here to learn as well as to help.

In this case, though, you're missing the point. The update statement
above is completely non-ambiguous, and that has nothing to do with any
wording in ANSI. It has to do with how table aliases work in SQL Server.

If you supply a table with an alias, you can no longer refer to that
table by it's tablename; you can ONLY use the alias. This is easily
demonstrated:

use pubs
select authors.au_fname
from authors a

Server: Msg 107, Level 16, State 3, Line 1
The column prefix 'authors' does not match with a table name or alias
name used in the query.

As you see, adding the alias 'a' to the table 'authors' doesn't give a
second name to the set, it changes it's only name. BTW, this behaviour
is (briefly) documented in BOL, index item "FROM clause (descibed)":

(quote from Books Online)
> [AS] table_alias
>
> Is an alias for table_name, view_name, or rowset_function, used either
> for convenience or to distinguish a table or view in a self-join or
> subquery. An alias is often a shortened table name used to refer to
> specific columns of the tables in a join. If the same column name exists
> in more than one table in the join, SQL Server requires that the column
> name must be qualified by a table name or alias. (The table name cannot
> be used if an alias is defined).


Note the parenthesed remark at the end of this paragraph


Back to my update statement. The ded_temp table is used twice. The one
in the subquery is aliased as 'b' - column from this occurence of
ded_temp can never be refered to in the form ded_temp.foo - they MUST be
refered to as b.foo (or just foo - but that _would_ be ambiguous!!). The
one in the UPDATE (outside of the subquery) doesn't have an alias, hence
each column ded_temp.bar can ONLY refer to this occurence of the
ded_temp table.



>because for a human the query is about incomprehensible.


I disagree with that as well. Of course, it IS necessary to always
follow the same conventions. These are my favorites:

1. In a one-table SELECT, UPDATE or DELETE, use no alias and no prefixes
for the column names.
2. In a two-or-more-table SELECT, use aliases for ALL tables and prefix
ALL column names with the appropriatie alias.
3. In a proprietary UPDATE FROM or DELETE FROM, use aliases for ALL
tables and prefix ALL column names with the appropriatie alias (except
the columns on the left of the = symbol in the SET clause). Use the
alias after the UPDATE or DELETE keyword, not the table name. Do not
omit the table to be updated or deleted from the FROM list, even though
SQL Server allows this. And don't use this syntax for single-table
UPDATE or DELETE operations.
4. In an ANSI UPDATE or DELETE with subquery (or subqueries), don't use
an alias for the table to be updated or deleted (not allowed!), but do
use aliases for all tables in the subqueries. Prefix ALL column names
with either the apppropriate prefix, or the tablename of the table to be
updated or deleted.
5. Use ANSI standard constructions, unless there is a good reason to
choose proprietary SQL. Always document the reason for the use of
proprietary SQL.

With the guidelines above, queries such as the one above are far from
incomprehensible. (Though I'd normally use UPPERCASE for all keywords,
CamelCase for table and column names, lowercase for aliases and
different indentation - but I was in a lazy mood when I made my first
post in this thread - too lazy to change the existing capitalization and
layout).


>(And I would
>not be surprised if more than one engine gets lost on the query above,
>so I would not even trust the elusive compatibility.)


Since I know only SQL Server, I'll have to take your word for it.

OTOH, any RDBMS that claims entry-level SQL-92 or above *should* be able
to understand this statement.


>The ANSI standard does not provide a place to put in an alias, and
>that is a serious shortcoming. In this case, it leads to the nonsese
>above. In other cases, imagine that you have a table by the of
>instrumentclearingmarketplaces - writing that over and over again
>is completely out of the question.


The same "problem" occurs with long column names. Using drag and drop
from object editor, copy/paste, programmable macro keys and/or mnemonics
while typing and search&replace when done are easy solutions.


>> BTW, you can also omit the GROUP BY clause, since the subquery will only
>> match rows for one set of (cust_no, ded_type_cd, chk_no) anyway - this
>> might even give you some performance gain!

>
>For some real serious peformance gain, this is likely to be a true
>winner:
>
> UPDATE ded_temp
> SET balance = b.ln_amt
> FROM ded_temp a
> JOIN (SELECT cust_no, ded_type_cd, chk_no, ln_amt = sum(b.ln_amt)
> FROM ded_temp
> GROUP BY cust_no, ded_type_cd, chk_no) AS b
> ON a.cust_no = b.cust_no
> AND a.ded_type_cd = b.ded_type_cd
> AND a.ded_temp.chk_no = b.chk_no
>
>I can give no guarantees, but my experience is that a join with a derived
>table results in a lot more effecient plan, than a correlated subquery.


You are very probably right - I have seen numerous occasions where the
proprietary UPDATE FROM far outperformed the ANSI equivalent. If
performance is the main objective, then UPDATE FROM might be the better
choice. But performance is not always the main objective. If the tables
are small, then nobody will care if it takes 3 ms or 6 ms. If the app
will have to run on multiple platforms (or even if the app is written
with the idea that one day, it *might* be ported), ANSI standard code
should be used unless it'd become a real performance killer.

And finally - if the table to be updated happens to be a view with an
INSTEAD OF trigger, then the proprietary UPDATE FROM syntax can not be
used, so you'll HAVE TO use the ANSI standard equivalent, whether you
like it or not.

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #13 (permalink)  
Old 02-29-2008, 08:51 AM
Erland Sommarskog
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

Hugo Kornelis (hugo@pe_NO_rFact.in_SPAM_fo) writes:
> In this case, though, you're missing the point. The update statement
> above is completely non-ambiguous, and that has nothing to do with any
> wording in ANSI. It has to do with how table aliases work in SQL Server.


Yes, I know that there are such rules. But my main point is that I as
a human have a difficult to understand what the query means. You and
I may know the alias rules by heart, but not everyone may feel fully
confident in them. Something is not working properly, and the support
person freaks out on this query, thinking this must be where the error
is, and wastes time, because some purist put ANSI compliance ahead of
clarity.

By the way, I think these rules were introduced in 6.5, but I don't know
what would have happened with this statement in 6.0 or 4.x.

> Use the alias after the UPDATE or DELETE keyword, not the table name.


I much prefer to use the table name, since at this point the reader may
not know what "a" stands for. There is one exception, and that is if
you self-join against the table being updated/deleted to. If you are on
SQL 7 or 6.5 it's a different matter: here you need to use the alias,
as soon as you use the newer ANSI-join syntax.

> 4. In an ANSI UPDATE or DELETE with subquery (or subqueries), don't use
> an alias for the table to be updated or deleted (not allowed!), but do
> use aliases for all tables in the subqueries. Prefix ALL column names
> with either the apppropriate prefix, or the tablename of the table to be
> updated or deleted.


And I say: always use an alias, and add a FROM clause if only to
introduce an alias.

> 5. Use ANSI standard constructions, unless there is a good reason to
> choose proprietary SQL. Always document the reason for the use of
> proprietary SQL.


That would be a lot of comments. Do you really write a comment everytime
you use + for string concatenation? Every time you create a temp table?

Of course, if there is a clearly outspoken desire to be portable, then
there is a point with it. But in many most situations, portability is
not on the agenda. Being ANSI-compliant in such case only means that
you work with your RDBMS with one hand tied behind your back. And
if the day comes when you actually will have to target another engine,
you find that that nice ANSI-compliant syntax will have to be rewritten
anyway, because the new engine did not support that syntax anyway.

And even if the engine supports the syntax, you may find that the
performance did not port. You know, customers do not that make much
distinction between a syntax error and a query that runs longer than
their patience permits them.

>>(And I would
>>not be surprised if more than one engine gets lost on the query above,
>>so I would not even trust the elusive compatibility.)

>
> Since I know only SQL Server, I'll have to take your word for it.


Note that I didn't say that there are such engines. I only speculated
that there could be, since this is a case which really invites to bugs.

>>The ANSI standard does not provide a place to put in an alias, and
>>that is a serious shortcoming. In this case, it leads to the nonsese
>>above. In other cases, imagine that you have a table by the of
>>instrumentclearingmarketplaces - writing that over and over again
>>is completely out of the question.

>
> The same "problem" occurs with long column names. Using drag and drop
> from object editor, copy/paste, programmable macro keys and/or mnemonics
> while typing and search&replace when done are easy solutions.


No, the problem is not the same with long column names, because they
are not repeated over and over again over the query. And the problem
is not about typing the code. Again, it is about reading the code.

> You are very probably right - I have seen numerous occasions where the
> proprietary UPDATE FROM far outperformed the ANSI equivalent. If
> performance is the main objective, then UPDATE FROM might be the better
> choice. But performance is not always the main objective. If the tables
> are small, then nobody will care if it takes 3 ms or 6 ms.


So we should use one syntax for small tables, and one for big tables?
What if that small table becomes big one day? Frankly, that is far more
likely that the code will be ported.

Most production databases have considerable amounts of data, but
development environments are offer lesser-scale, so developers are
not always directly made aware of performance issues. Better to learn
them to use something that provides best performance in most cases.

I remember one such stored procedure where we slashed execition time
from 4 minutes to a couple of seconds by replacing correlated subqueries
with derived tables in two update statments.

--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #14 (permalink)  
Old 02-29-2008, 08:53 AM
Hugo Kornelis
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

On Mon, 6 Jun 2005 22:31:07 +0000 (UTC), Erland Sommarskog wrote:

>Hugo Kornelis (hugo@pe_NO_rFact.in_SPAM_fo) writes:
>> In this case, though, you're missing the point. The update statement
>> above is completely non-ambiguous, and that has nothing to do with any
>> wording in ANSI. It has to do with how table aliases work in SQL Server.

>
>Yes, I know that there are such rules. But my main point is that I as
>a human have a difficult to understand what the query means.


Hi Erland,

I don't have those difficulties, but if you do, then I can see that
you'd rather avoid this syntax. But I do not agree that posting this
code amounts to "poor advice".

You could even defend the opposite: it's better that people get their
first glimpse of that syntax here, where they can ask questions about
it, then while debugging some poorly documented code in a
mission-critical database.

> You and
>I may know the alias rules by heart, but not everyone may feel fully
>confident in them.


Yes, I agree that the ANSI compliant UPDATE statement could be confusing
for inexperienced SQL Server users. But the T-SQL UPDATE statement comes
with a much bigger risk in the hands of less experienced people: a small
mistake in the subquery could easily result in inpredictabe results,
that might be correct in test, but wrong in production - without any
warning from SQL Server!! The ANSI compliant version with the same
mistake would throw an error, forcing the programmer or DBA to review
the code.


(snip)
> because some purist put ANSI compliance ahead of
>clarity.


I am not a purist. In performance-critical parts of my DB's, I use what
performs best. In other parts, I use ANSI, unless I feel that there is a
huge gain in readability and maintainability (e.g. when more columns
have to be set, I generally prefer a joined UPDATE over repeating the
same subquery over and over again).

Let's agree to disagree on the readability of ANSI-standard UPDATE
statements, but let's also agree to not call each other names over this,
okay?


Another difference of opinion:

>> Use the alias after the UPDATE or DELETE keyword, not the table name.

>
>I much prefer to use the table name, since at this point the reader may
>not know what "a" stands for. There is one exception, and that is if
>you self-join against the table being updated/deleted to.


This exception is exactly the reason why I always use the alias after
the UPDATE or DELETE keyword - if you have to do it in some cases,
better be consequent and do it in all cases. Besides, it's a good
reminder that the T-SQL version of the UPDATE / DELETE syntax is used!


>> 5. Use ANSI standard constructions, unless there is a good reason to
>> choose proprietary SQL. Always document the reason for the use of
>> proprietary SQL.

>
>That would be a lot of comments. Do you really write a comment everytime
>you use + for string concatenation? Every time you create a temp table?


You've got me there!

What I meant to write was: document it when you CHOOSE to use T-SQL
instead of ANSI SQL. String concatenation, date and time handling, temp
tables and lots of other things can only be done with proprietary code,
so there's no need to document them. UPDATE FROM and DELETE FROM can
always be replaced by ANSI-compliant code, just as code that uses the
TOP keyword - those are the cases that I always document.

(snip parts I agree with)

>>>(And I would
>>>not be surprised if more than one engine gets lost on the query above,
>>>so I would not even trust the elusive compatibility.)

>>
>> Since I know only SQL Server, I'll have to take your word for it.

>
>Note that I didn't say that there are such engines. I only speculated
>that there could be, since this is a case which really invites to bugs.


I'll counter-speculate that machines would have far less trouble with
this than humans. If an RDBMS has trouble with this statement, then my
guess is that it either has trouble with all correlated subqueries in
update statements (whether with or without alias), or that is has
trouble with all queries that mix aliased and non-aliased tables. In
both cases, the product would disqualify as serious DB in my book.

(snip parts I agree with)

>> If
>> performance is the main objective, then UPDATE FROM might be the better
>> choice. But performance is not always the main objective. If the tables
>> are small, then nobody will care if it takes 3 ms or 6 ms.

>
>So we should use one syntax for small tables, and one for big tables?


No, that's not what I meant. A good DB uses standardized code in most
cases (and in our case, your standard for UPDATE statements is different
from mine - but as long as each of us sticks to his own standard, that's
fine <g>). But for the long-running performance-hurting queries and
statements, we pull every trick that we know, in order to squeeze the
last bit of performance out of it - if necessary even at the expense of
standard constructions, readability and maintainability.

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #15 (permalink)  
Old 02-29-2008, 08:53 AM
Erland Sommarskog
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

Hugo Kornelis (hugo@pe_NO_rFact.in_SPAM_fo) writes:
> You could even defend the opposite: it's better that people get their
> first glimpse of that syntax here, where they can ask questions about
> it, then while debugging some poorly documented code in a
> mission-critical database.


Not all people read the newsgroups or other SQL forums. In facr, I would
suspect most people don't.

> Yes, I agree that the ANSI compliant UPDATE statement could be confusing
> for inexperienced SQL Server users. But the T-SQL UPDATE statement comes
> with a much bigger risk in the hands of less experienced people: a small
> mistake in the subquery could easily result in inpredictabe results,
> that might be correct in test, but wrong in production - without any
> warning from SQL Server!!


That's another red herring. With the same argument you should use
JOIN clauses in your SELECT either, but always get your values with
subqueries in the column list.

> The ANSI compliant version with the same mistake would throw an error,
> forcing the programmer or DBA to review the code.


Considet:

UPDATE tbl
SET col = (SELECT SUM(o.somecol)
FROM othertbl o
JOIN tbl t WHERE t.keycol = o.keycol)

Exactly which error will be raised here?

Sure, the result is not predictable - we know that the entire table
will be thrashed.

And, yes, I've seen people who have posted queries like this. and who
other just messed up, or have not grasped the correlated subqueries.

And this brings to another great advantage with the FROM syntax: you
use the same idiom for UPDATE/DELETE as you do for SELECT. If you are
uncertain whether your conditions are correct, you can easily transform
your UPDATE to a SELECT.

Again, I'm putting emphasis on the cognitive side of things.

>>Note that I didn't say that there are such engines. I only speculated
>>that there could be, since this is a case which really invites to bugs.

>
> I'll counter-speculate that machines would have far less trouble with
> this than humans. If an RDBMS has trouble with this statement, then my
> guess is that it either has trouble with all correlated subqueries in
> update statements (whether with or without alias), or that is has
> trouble with all queries that mix aliased and non-aliased tables. In
> both cases, the product would disqualify as serious DB in my book.


Maybe it would. But SQL 6.0 was such a database. There you could say:

SELECT a.col, tbl.col FROM tbl a

> Let's agree to disagree on the readability of ANSI-standard UPDATE
> statements, but let's also agree to not call each other names over this,
> okay?


Any time I see someone touting the ANSI syntax for UPDATE and DELETE,
I will reserve the right to bump in. Unless portability is a true and
serious concern, and just theoretical "it could happen", the ANSI
syntax has so serious problems - both in itself, and specific to
SQL Server - that it is in my opinion poor advice to suggest it
instead of the FROM syntax which is clearer, easier to understand,
and usually also more performant on SQL Server.

--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #16 (permalink)  
Old 02-29-2008, 08:53 AM
Serge Rielau
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

Erland Sommarskog wrote:
> Any time I see someone touting the ANSI syntax for UPDATE and DELETE,
> I will reserve the right to bump in. Unless portability is a true and
> serious concern, and just theoretical "it could happen", the ANSI
> syntax has so serious problems - both in itself, and specific to
> SQL Server - that it is in my opinion poor advice to suggest it
> instead of the FROM syntax which is clearer, easier to understand,
> and usually also more performant on SQL Server.
>

Just an FYI the ANSI syntax to solve the problem is

MERGE INTO <target>
USING <source>
ON <join codition>
WHEN MATCHED THEN UPDATE SET ...

IMHO The UPDATE with the double query is tough for many users to
understand, before MERGE the UPDATE FROM problem was a FAQ in
c.d.ibm-db2. UPDATE FROM is also supported by Informix XPS, btw.

Cheers
Serge
--
Serge Rielau
DB2 SQL Compiler Development
IBM Toronto Lab
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #17 (permalink)  
Old 02-29-2008, 09:01 AM
Hugo Kornelis
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

Hi Erland,

Sorry for picking up an old discussion. I've been planning to respond to
this the whole week, but other things just kept interfering. And yet, I
do want to respond to some of your points.


On Tue, 7 Jun 2005 23:11:31 +0000 (UTC), Erland Sommarskog wrote:

>Hugo Kornelis (hugo@pe_NO_rFact.in_SPAM_fo) writes:
>> You could even defend the opposite: it's better that people get their
>> first glimpse of that syntax here, where they can ask questions about
>> it, then while debugging some poorly documented code in a
>> mission-critical database.

>
>Not all people read the newsgroups or other SQL forums. In facr, I would
>suspect most people don't.


But since this started over what advice I should or should not give in
the newsgroups, it's safe to assume that the people reading my advice do
read the groups.


>> Yes, I agree that the ANSI compliant UPDATE statement could be confusing
>> for inexperienced SQL Server users. But the T-SQL UPDATE statement comes
>> with a much bigger risk in the hands of less experienced people: a small
>> mistake in the subquery could easily result in inpredictabe results,
>> that might be correct in test, but wrong in production - without any
>> warning from SQL Server!!

>
>That's another red herring. With the same argument you should use
>JOIN clauses in your SELECT either, but always get your values with
>subqueries in the column list.


No. JOIN clauses might result in undesired results (but so could
subqueries, or any other code), but not in unpredictable code. The
UPDATE FROM syntax and TOP without ORDER BY are the only constructions
where the result on the same starting data might change if the optimizer
picks a different plan.


>> The ANSI compliant version with the same mistake would throw an error,
>> forcing the programmer or DBA to review the code.

>
>Considet:
>
> UPDATE tbl
> SET col = (SELECT SUM(o.somecol)
> FROM othertbl o
> JOIN tbl t WHERE t.keycol = o.keycol)
>
>Exactly which error will be raised here?


None, as this is not the kind of mistake I refered to.

>Sure, the result is not predictable - we know that the entire table
>will be thrashed.


The result IS predictable. Wrong, perhaps (probably) - but predictable
and repeatable. If I know the data in the tables, I can predict the
result of this query - and you can add, remove or change indexes, add or
remove processors or memory or even use hints to force funny execution
plans, but none of these changes will change the execution plan.

The kind of mistake I was talking about is illustrated in the query
below:

ALTER TABLE titles
ADD sold_in char(4)
go
-- ANSI standard - will consistently throw an error
UPDATE titles
SET sold_in = (SELECT s.stor_id
FROM sales AS s
WHERE s.title_id = titles.title_id)
go
-- T-SQL proprietary - no error, no warning
UPDATE t
SET sold_in = s.stor_id
FROM titles AS t
JOIN sales AS s
ON s.title_id = t.title_id
go
SELECT title_id, sold_in
FROM titles
go
-- Same query, but force another execution plan
-- Now, the same query suddenly yields different results
UPDATE t
SET sold_in = s.stor_id
FROM titles AS t
INNER HASH JOIN sales AS s
ON s.title_id = t.title_id
go
SELECT title_id, sold_in
FROM titles
go


(snip)
>And this brings to another great advantage with the FROM syntax: you
>use the same idiom for UPDATE/DELETE as you do for SELECT. If you are
>uncertain whether your conditions are correct, you can easily transform
>your UPDATE to a SELECT.
>
>Again, I'm putting emphasis on the cognitive side of things.


You're right there - transforming a working SELECT to a working T-SQL
UPDATE is lots easier than creating the equivalent ANSI UPDATE. (But I
can tell you from experience that the latter also becomes a routine job
after the first 50 or so).
I personally believe that a good programmer should master both versions:
the ANSI version becuas he might be required to write portable code, or
might get himself in a situation where even SQL Server doesn't like the
T-SQL version, and the T-SQL syntax because he might need it to optimize
poor performing parts of the code.


>> Let's agree to disagree on the readability of ANSI-standard UPDATE
>> statements, but let's also agree to not call each other names over this,
>> okay?

>
>Any time I see someone touting the ANSI syntax for UPDATE and DELETE,
>I will reserve the right to bump in.


By all means, do. People *should* know both variants!

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #18 (permalink)  
Old 02-29-2008, 09:04 AM
Erland Sommarskog
 
Posts: n/a
Default Re: SELECT works but UPDATE fails. ?

Hugo Kornelis (hugo@pe_NO_rFact.in_SPAM_fo) writes:
>>Not all people read the newsgroups or other SQL forums. In facr, I would
>>suspect most people don't.

>
> But since this started over what advice I should or should not give in
> the newsgroups, it's safe to assume that the people reading my advice do
> read the groups.


Person A reads your post on the net and follows your advice. A quits
his job to move elsewhere, and B comes in and looks at it says "What
the ****?"

> No. JOIN clauses might result in undesired results (but so could
> subqueries, or any other code), but not in unpredictable code. The
> UPDATE FROM syntax and TOP without ORDER BY are the only constructions
> where the result on the same starting data might change if the optimizer
> picks a different plan.


Any SELECT without an ORDER BY is unpredicatble. It may not be unpredicatble
in the relational realm, since it deals with unordered sets. However, in
real life order matter in many cases. For instance a programmer might
program his SELECT statement that is supposed to return one row incorrectly.
His client program reads that only row that is supposed to be there.
Sometimes that happens to be the row he is actually looking for. And
one day it is not.

>>Sure, the result is not predictable - we know that the entire table
>>will be thrashed.

>
> The result IS predictable. Wrong, perhaps (probably) - but predictable
> and repeatable.


Sorry, I did of course mean to say "is predictable". For once I had one
"not" too many.

And my point is that is irrelevant whether incorrect code is unpredictable
or not. An incorrect result is incorrect, no matter it is predictable
or not.


Now, since last it has occurred to me that I actually have access to
MySQL. So I ran this on MySQL 4.1:

CREATE TABLE tbl (a int NOT NULL,
b int NOT NULL,
total int NULL);
CREATE TABLE tbl2 (a int NOT NULL,
total int NULL);
INSERT tbl2(a) SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
INSERT tbl (a, b)
SELECT 1, 1 UNION ALL SELECT 1, 2 UNION ALL SELECT 1, 3 UNION ALL
SELECT 2, 11 UNION ALL SELECT 2, 21 UNION ALL SELECT 2, 23 UNION ALL
SELECT 3, 101 UNION ALL SELECT 3, 102 UNION ALL SELECT 3, 103;
UPDATE tbl
SET total = (SELECT SUM(b.b)
FROM tbl b
WHERE b.a = tbl.a);
UPDATE tbl2
SET total = (SELECT SUM(b.b)
FROM tbl b
WHERE b.a = tbl2.a);
SELECT * FROM tbl;
SELECT * FROM tbl2;
DROP TABLE tbl;
DROP TABLE tbl2;

(Each statement was a batch of its own it seems.)

The UPDATE of tbl2 worked fine. But the UPDATE of tbl, with the unreadable
syntax that started this thread, failed:

ERROR 1093 (HY000): You can't specify target table 'tbl' for update in
FROM clause

Now, on http://sql-info.de/mysql/gotchas.html you can find a quite a few
issues with MySQL that quite hilarious. So of course, you could disqualify
it as "unserious DBMS". Nveertheless, MySQL has gained quite some
popularity, and is definitely a competitor to SQL Server in the low-end
market, and to some extent in the middle-range as well.

How you actually would write that UPDATE in MySQL, I don't know. But
I have not tried to find out either.

--
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
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
Forum Jump


All times are GMT. The time now is 11:37 AM.


Powered by vBulletin® Version 3.6.5
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0
www.UnixAdminTalk.com