Незаменимые заполнители оператора SQL приводят к «Невозможно обновить« @columnName »; поле не обновляется» - PullRequest
0 голосов
/ 24 сентября 2011

Я пишу код для обновления базы данных с помощью оператора SQL, который имеет некоторые заполнители.Но, похоже, эти заполнители не обновляются.

Я получил следующую ошибку:

Cannot update '@columnName'; field not updateable

Вот метод:

    public void updateDoctorTableField(string columnName, string newValue, string vendorNumber) {
        sqlStatement = "update Doctor set @columnName = @newValue where `VENDOR #` = @vendorNumber;";
        try {
            _command = new OleDbCommand(sqlStatement, _connection);
            _command.Parameters.Add("@columnName", OleDbType.WChar).Value = columnName;
            _command.Parameters.Add("@newValue", OleDbType.WChar).Value = newValue;
            _command.Parameters.Add("@vendorNumber", OleDbType.WChar).Value = vendorNumber;

            _command.ExecuteNonQuery();
        } catch (Exception ex) {
            processExeption(ex);
        } finally {
            _connection.Close();
        }
    }

Ответы [ 2 ]

3 голосов
/ 24 сентября 2011

Не все части запроса являются параметризуемыми.

Невозможно параметризовать имя столбца.Это должно быть указано явно в тексте вашего запроса.

Если это отправлено через пользовательский ввод, вы должны быть осторожны с SQL-инъекцией.На самом деле в любом случае было бы лучше проверить его по белому списку известных допустимых имен столбцов.

1 голос
/ 24 сентября 2011

Причина, по которой язык не допускает параметры для таких вещей, как имена таблиц, имена столбцов и т. Д., В точности та же самая причина, по которой ваша программа на C # не допускает подстановку переменных в коде.По сути, ваш вопрос можно перефразировать следующим образом в программе на C #:

class MyClass
{
    int x;
    float y;
    string z;


    void DoSomething(string variableName)
    {
        this.@variable = ...
    }
}

MyCLass my = new MyClass();
my.DoSomething("x"); // expect this to manuipulate my.x
my.DoSomething("y"); // expect this to manuipulate my.y
my.DoSomething("z"); // expect this to manuipulate my.z

Это, очевидно, не скомпилируется, потому что компилятор не может сгенерировать код.То же самое для T-SQL: компилятор не может сгенерировать код для определения местоположения столбца "@columnName" в вашем случае.И так же, как в C # вы бы использовали рефлексию для такого рода уловок, в T-SQL вы бы использовали динамический SQL для достижения того же.

Вы можете (и должны) использовать QUOTENAME функция при построении динамического SQL для защиты от внедрения SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...