简体   繁体   中英

How to specify SQL column alias as SqlParameter?

Is it possible to add the alias of a column as an SqlParameter to an SQL command? If so, how is it specified?

As a simplified example, say I have an SQL command that is constructed like this:

SqlCommand GetCommand(string columnName)
{
    string filter = String.Format("SELECT MyColumn1 AS '{0}' FROM MyTable", columnName);

    return new SqlCommand(filter);
}

This command does nothing to prevent an SQL Injection attack, so I want to follow the standard procedure and parameterize the command.

I'm used to converting statements in the WHERE clause to use parameters. The statements look similar to the above, for example:

SqlCommand command("SELECT * FROM MyTable WHERE name = '{0}'", name);

When I convert this, it becomes:

SqlCommand command("SELECT * FROM MyTable WHERE name = @name");
command.Parameters.Add(new SqlParameter("name", SqlDbType.NVarChar) { Value = name });

That works well. Taking the same approach here with the GetCommand() method gives:

SqlCommand GetCommand(string columnName)
{
    string filter = "SELECT MyColumn1 AS @columnName FROM MyTable";

    SqlCommand command = new SqlCommand(filter);
    command.Parameters.Add(new SqlParameter("columnName", SqlDbType.NVarChar) 
        { Value = columnName });

    return command;
}

But, when the command is executed, it results in:

An exception of type 'System.Data.SqlClient.SqlException' occurred in MyApplication.exe but was not handled in user code

Additional information: Incorrect syntax near '@columnName'.

I see there are plenty of questions on SO and the web in general about use of SqlParameter , but seemingly none that touch on their use with column aliases.

There's no indication in Microsoft's SqlParameter documention either. From this, I noticed that the SqlParameter.Direction property defaults to ParameterDirection.Input ; the column alias is used in output, so I tried InputOutput and Output , but it made no difference to the results.

Short answer: you can't .

Column Aliases are not parameterizable. They are identifiers in the SQL language, not values - just like the column name itself, or the table name.

"Get me column X from table Y and name it Z in the result set." None of X, Y or Z are parameterizable.

Note that this is not a limitation of SqlParameter but of the SQL language as implemented by Sql Server.

Parameters are not designed for aliasing TSQL columns. If you need an alias, just give it one in the TSQL. Additionally, the In/Out aspect of the parameter is for cases where the query modifies the parameter during running. Such as an output parameter of a stored procedure.

In truth, what it appears you're trying to do is get a dataset where the returned column name is based upon an inputted value.

I would use a data adapter to fill a data table, and then just rename the column to the desired value.

dataTable.Columns["MyColumn1"].ColumnName = columnName;

You can't parameterize schema names and aliases. If you must have dynamic aliases, you'll need to protect yourself from SQL injection in the application layer.

Consider creating a whitelist of valid aliases, and only select from the whitelist.

If the alias comes from user input, you'll have to validate/sanitize the input.

Edit: It's a bad practice to rely on the application layer to prevent SQL injection attacks. But sometimes business drivers or other reasons force this to happen. My suggestions here are ways to mitigate the risk of SQL injection if you are forced to do this.

Strange thing to do, but you can build some sql with the parameter and then exec it.

Declare @sql VarChar(255)
Set @sql = 'SELECT ClientNumber AS ' + @columnName + ' FROM Ib01'
Exec(@sql)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM