Wednesday, July 27, 2011

C#: System.Data.SqlClient.SqlException : Must declare the table variable

So now I'm doing more and more in C# I'm trying to do it properly. As in not just taking my old habits and writing it in C# code, but using all sorts of C# proper style. Since a lot of my work is with databases right now, this means I'm experimenting a lot with LINQ and proper SQL queries.

I used to build SQL queries as pure strings, just passing in the variables directly as string concatenations. This is unsafe. Hugely so. Imagine if someone jimmied your input code? They could put whatever they want into that query. This isn't too big a problem for me, as my code runs as a background service hidden on a computer behind about 30,000 firewalls that's probably ever only going to be accessed by me and my boss.

But still, the proper way to do it is to set up a query in advance and pass in parameters, which is basically an abstraction layer of variables in the SQL query. Observe:

backupQuery = "SELECT tableData FROM @storageTableName WHERE dataSource = @dataSource AND dbName = @dbName AND tableName = @tableName";
backupCommand = new SqlCommand(backupQuery, backupConnection);
backupCommand.Parameters.Add(new SqlParameter("@storageTableName", _backupTableName));
backupCommand.Parameters.Add(new SqlParameter("@dataSource", _config.dataSource));
backupCommand.Parameters.Add(new SqlParameter("@dbName", _config.database));
backupCommand.Parameters.Add(new SqlParameter("@tableName", tableConfig.name));

At runtime, everything with an "@" before it gets replaced by the variables in the parameters. Very nice. It looks all proper. But when running it, I'd constantly get this:

System.Data.SqlClient.SqlException was caught
Message=Must declare the table variable "@storageTableName".
Source=.Net SqlClient Data Provider
ErrorCode=-2146232060
Class=16

Joy. Lots of Googling and head scratching lead me to this forum.

In a nutshell, although parameters are an excellent way of using variables in SQL code, they can't be used for table names. So in the, I had to rewrite my initial string query as:
backupQuery = "SELECT tableData FROM " + _backupTableName + " WHERE dataSource = @dataSource AND dbName = @dbName AND tableName = @tableName";
I'm sure there's a good reason for this that I don't know about, but it's kind of annoying.

No comments:

Post a Comment