tags:

views:

90

answers:

7

well, the question is clear i hope, the code is this:

string sql = "delete from @tabelnaam";
            SqlCommand sc = new SqlCommand();

                sc.Connection = getConnection();
                sc.CommandType = CommandType.Text;
                sc.CommandText = sql;
                SqlParameter param = new SqlParameter();

                param.Direction = ParameterDirection.Input;
                param.ParameterName = "@tabelnaam";
                param.Value  = tableName;

                sc.Parameters.Add(param);
                OpenConnection(sc);
                sc.ExecuteScalar();

tableName is supplied to this function.

I get the exception:

Must declare the table variable @tabelnaam
+3  A: 

IIRC, you cant use a substitute the table name for a parameter.

Rather build the SQL string containing the correct table name.

leppie
doesn't that lead to sql injection?
Michel
@Michel: How do you come to that conclusion?
leppie
@leppie - of course it is a sql injection risk if the source of the string is via an untrusted source (such as user input). What if I entered the following "table name": "MyTable; DROP DATABASE MyDb".
Rob Levine
+1  A: 

Make to changes

rather than using paramter use this

string sql = string.format( "delete from {0}",tableName);

make use of executenonquery intead of ExecuteScalar

sc.ExecuteNonQuery();
Pranay Rana
doesn't that lead to sql injection?
Michel
you can avoide this by validating the tablename properly
Pranay Rana
A: 

I dont think you can parameterize the table name. From what I have read you can do it via Dynamic sql and calling sp_ExecuteSQL.

Steve
huh? so i can do this 'select * from client where name = @name' but i can't do this: 'delete from @table'?
Michel
@michel - exactly.
Rob Levine
[surprised] thanks for the comment
Michel
A: 

Your SQL is incorrect, you are deleting from a table variable yet you haven't defined that variable.

Update: as someone has pointed out, you are trying to dynamically build a query string but have inadvertantly used SQL parameters (these do not act as place holders for string literals).

Adam
Thanks for the edit, didn't spot that :)
Adam
i'm not sure i know what you mean.
Michel
The @tableName syntax you used followed by the comm.Parameters collection gave you something called "Parameterized SQL". The command was trying to put a "value" into the @tableName instead of the string literal that you intended. You simply wanted to build a chunk of SQL without any parameters using a string.
Adam
+1  A: 

As mentioned by others, you can't parameterise the table name.

However, as you rightly mention in comments on other answers, using simple string manipulation potentialy introduces a SQL injection risk:

If your table name input is fro an untrusted source, such as user input, then using this:

string sql = string.format( "DELETE FROM {0}",tableName);

leaves you open to the table name "myTable; DROP DATABASE MyDb" being inserted, to give you:

DELETE FROM myDb; DROP DATABASE MyDB

The way round this is to delimit the table name doing something such as this:

string sql = string.format("DELETE FROM dbo.[{0}]", tableName);

in combination with checking that the input does not contain either '[' or ']'; you should probably check it also doesn't contain any other characters that can't be used as a table name, such as period and quotes.

Rob Levine
You mean `dbo.` not `do.`? Tables can live in other schemas, though.
Rup
@Rup - I did - good spot, thank you. It's true, they can live in other schemas. I am just trying to impress the idea upon the OP to keep things *as restricted as possible*. If the tables are in other schemas, then this would need relaxing, but *only if* that is the case.
Rob Levine
A: 

You cannot parameterise the table name, you have to inject it into the command text.

What you can and should do is protect yourself against SQL injection by delimiting the name thus:

public static string Delimit(string name) {
    return "[" + name.Replace("]", "]]") + "]";
}

// Construct the command...
sc.CommandType = CommandType.Text;
sc.CommandText = "delete from " + Delimit(tableName);
sc.ExecuteNonQuery();

See here and here for more background info.

Christian Hayter