M
Marina
Right, and it makes sense that the command builder would be smart enough to
avoid trying to update columns if there were no changes in them. It means
less work for the database server to do, less network traffic.
Otherwise we probably wouldn't need a CommandBuilder object at all. Just
some sort of GenerateCommands method on the adapter, to generate static
update/insert/delete commands on itself.
avoid trying to update columns if there were no changes in them. It means
less work for the database server to do, less network traffic.
Otherwise we probably wouldn't need a CommandBuilder object at all. Just
some sort of GenerateCommands method on the adapter, to generate static
update/insert/delete commands on itself.
Sahil Malik said:Holy moly .. you're right .. I see it now .. it's a minor difference, but
WOW ..
But that is craziness .. Hmm .. !!!
- Sahil Malik [MVP]
ADO.NET 2.0 book -
http://codebetter.com/blogs/sahil.malik/archive/2005/05/13/63199.aspx
----------------------------------------------------------------------------
---------------
Marina said:No, those are *not* identical.
In the first row, you are updating Column1. In the second row, you are
update Column2.
If you were to update both columns, you would see the SET updating both
Column1 and Column2.
So clearly, each row's update statement changes depending on what columns
were updated in it.
--Sahil Malik said:Well the code sample is easy to reproduce .. yeah .. but I wasn't able to
repro your claim that UpdateCommand actually changes as you go ..
So I wrote up the sample as you say below, and here are the update
commands
I got for two rows.
UPDATE [MyTest] SET [Column1] = @p1 WHERE (([MyTestID] = @p2) AND ((@p3 =
1
AND [Column1] IS NULL) OR ([Column1] = @p4)) AND ((@p5 = 1 AND
[Column2]
IS
NULL) OR ([Column2] = @p6)))
UPDATE [MyTest] SET [Column2] = @p1 WHERE (([MyTestID] = @p2) AND ((@p3 =
1
AND [Column1] IS NULL) OR ([Column1] = @p4)) AND ((@p5 = 1 AND
[Column2]
IS
NULL) OR ([Column2] = @p6)))
As you can see, they are identical. DataAdapter, therefore DOES NOT change
UpdateCommands.
Here is one more thing to consider. A DataAdapter is completely blind
to
the
fact that the commands came out of CommandBuilder. So if it does indeed
change commands on the fly, it may even change the commands that I
specified
(not command builder) - which would be completely catastrophic.
Anyway, DataAdapter, does not change UpdateCommand.CommandText.
- Sahil Malik [MVP]
ADO.NET 2.0 book -
http://codebetter.com/blogs/sahil.malik/archive/2005/05/13/63199.aspx
-----------------------------------------------------------------------------------------
No, I am just creating a command builder. I didn't think a sample was
necessary, because reproducing it is so trivial.
Here is code that updates 5 rows. Each row has only 1 column updated, but
it
alternates:
Dim conn As New SqlConnection("Data Source=(local);Initial Catalog=
MyDatabase;user=sa;Password=mypassword")
Dim adap As New SqlDataAdapter("Select top 5 MyKeyColumn,
Column1,
Column2 FROM MyTable", conn)
Dim cb As New SqlCommandBuilder(adap)
Dim dt As New DataTable
adap.Fill(dt)
For i As Integer = 0 To 4
dt.Rows(i)((i Mod 2) + 1) = " " + dt.Rows(i)((i Mod 2) +
1).ToString
Next
adap.Update(dt)
Okay wait a minute ..
In the suggested sample you specify below, how exactly is the
UpdateCommand
being filled in? Are you creating a command builder, then getting
UpdateCommand, and then put that on a DataAdapter?
Y'know a working code sample that repro's what you say below would
be
*really* helpful
- Sahil Malik [MVP]
ADO.NET 2.0 book -
http://codebetter.com/blogs/sahil.malik/archive/2005/05/13/63199.aspx------------------------------------------------------------------------- -
--
---------------
This is trivial to reproduce. Fille a DataTable with 2 rows from a
table
with say 3 columns. The first column is the primary key, the other
columns
can be updated.
Then update the second column in row 1, and the third column in row 2.
Run your program.
You will see that the update statement that runs to update row 1 is
different that that which runs to update row2.
The first update statement includes updating only column 2 (because
column
3
has not changed), and vice versa for row 2. If the statement was
always
the
same, then both columns would always be updated.
Can you provide a repro case for this?
--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
www.betav.com/blog/billva
www.betav.com
www.sqlreportingservices.net
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no
rights.
__________________________________
I've actually used the profiler to trace the statements as they are
being
executed by the dataadapter. They looked like they were
changing
depending on what particular columns each row needed updating.
I didn't say the actual UpdateCommand object was being changed
on
the
adapter (since there isn't even one defined because the
commandbuilder
is
being used)
message
Ah, ADO.NET does NOT change the UpdateCommand or any of the other
action
commands on the fly. They are frozen as set by the CommandBuilder.
ADO
does insert values into the Parameters on the fly, but that's it.
See
my
article on the CommandBuilder for more insight
(http://www.betav.com/msdn_magazine.htm). Many of us are not
particularly happy with the CommandBuilder in V1.0 and 1.1.
It's
somewhat better in 2.0 but I think it should be
avoided--especially
for
complex UPDATE/INSERT operations.
Since you're using SQL Server, you should be using SPs to execute
the
changes and building a tuned UPDATE statement for it to execute
(using
TimeStamp concurrency).
--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and
confers
no
rights.
__________________________________
Thats actually what the problem is. For the row in question (row
with
index of 2, out of 1610), 11 columns have changed values. Most
notably,
the "Country" column has changed from '' to 'USA'. This is
evident
when I introspect the DataRow with the current location set to
the
"Update(...)" call. When I step forward into the Update method,
not
all 11 columns appear in the SQL UPDATE statement. Ripping apart
the
SqlDataAdapter and looking at the UpdateCommand at this time,
I
see
the
UpdateCommand contains all columns.
If the DataAdapter does modify the SQL statement to include only
the
changed columns, then I fear that something is wrong with the
algorithm, or there is a bug. The UpdateCommand definitely lists
all
columns, and, more columns are changed than what is being sent
across
the wire.
I'm bewildered.
Thanks for the help!
-Sean