Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does UPDATE .WRITE() only work if I use [column].WRITE(), but not [table].[column].WRITE()?

I'm executing an UPDATE .WRITE() statement and have found out that it obviously only works if you define it like this:

string sql = "UPDATE [dbo].[Table] SET [Column].WRITE(@data, @offset, @count) WHERE ...";
...
sqlCommand.ExecuteNonQuery();

However, if I use [dbo].[Table].[Column].WRITE(...) or [Table].[Column].WRITE(...), an exception is thrown:

Incorrect syntax near 'WRITE'.

Stack trace:
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   ...

Why is that? It doesn't seem very consistent with the usual way one would construct SQL statements. Is there any point for this seemingly exceptional convention, where you are obviously not allowed to explicitly specify table name and schema?

like image 673
w128 Avatar asked Mar 24 '23 06:03

w128


1 Answers

It doesn't seem very consistent ...

It is actually consistent with the rest of the SET clause:

SET
    { column_name = { expression | DEFAULT | NULL }
      | { udt_column_name.{ { property_name = expression
                            | field_name = expression }
                            | method_name ( argument [ ,...n ] )
                          }
      }
      | column_name { .WRITE ( expression , @Offset , @Length ) }
      | @variable = expression
      | @variable = column = expression
      | column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
      | @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression
      | @variable = column { += | -= | *= | /= | %= | &= | ^= | |= } expression
    } [ ,...n ] 

That is, it's never valid, in the SET clause, to specify a table or schema on the left side of the assignment (You can, of course, reference other tables by full name or alias, in the expressions on the right hand side). The table to update has already been identified between UPDATE and SET.

like image 151
Damien_The_Unbeliever Avatar answered Mar 25 '23 22:03

Damien_The_Unbeliever