Параметрированный запрос в Oracle
Я использую Oracle.DataAccess
, а не устаревший System.Data.OracleClient
, и мне, кажется, не удается передать несколько параметров в мой запрос на обновление
Это работает
OracleCommand.CommandText = "UPDATE db SET column1 = :param1 WHERE column2 = 'Y'"
OracleCommand.Parameters.Add(New OracleParameter("param1", "1234"))
Но я хочу иметь возможность передавать несколько параметров
Здесь мой полный код
OracleConn.Open()
OracleCommand = OracleConn.CreateCommand()
OracleCommand.CommandText = "UPDATE db SET column1 = :param1 WHERE column2 = :param2"
OracleCommand.CommandType = CommandType.Text
OracleCommand.Parameters.Add(New OracleParameter("param1", "1234"))
OracleCommand.Parameters.Add(New OracleParameter("param2", "Y"))
OracleCommand.ExecuteNonQuery()
Мой запрос SELECT
работает при передаче нескольких параметров, но не в обновлении
Ответы
Ответ 1
Хотя я не вижу ничего плохого в вашем примере, мне интересно, попадаете ли вы в старую проблему BindByName
. По умолчанию ODP.NET связывает параметры с запросом в том порядке, в котором они добавлены в коллекцию, а не на основе их имени по вашему желанию. Попробуйте установить BindByName
на true
на свой объект OracleCommand
и посмотреть, устраняет ли это проблему.
У меня была эта проблема столько раз, что я использую свой собственный метод factory для создания команд, которые автоматически устанавливают это свойство как true
для меня.
Классическая бесполезная документация Oracle здесь
Ответ 2
Чтобы эмулировать поведение System.Data.OracleClient по умолчанию, вы должны установить OracleCommand для привязки по имени.
OracleCommand.BindByName = True
Ответ 3
Попробуйте обновить свой OracleParameter с указанным типом. Задайте значение объекта перед добавлением его в список параметров.
var param1 = new OracleParameter( "param1", OracleType.Int32 );
param1.Value = "1234";
OracleCommand.Parameters.Add( param1 );
Ответ 4
Попробуйте это, надеюсь, что это сработает. Он компилируется.
Не уверен, что вам также нужно отправить фиксацию...
Я всегда делаю подобные вещи с помощью хранимой процедуры, поэтому у меня есть фиксация после инструкции обновления в хранимой процедуре.
Харви Сатер
OracleConnection ora_conn = new OracleConnection("connection string");
OracleCommand ora_cmd = new OracleCommand("UPDATE db SET column1 = :param1 WHERE column2 = :param2", ora_conn);
ora_cmd.CommandType = CommandType.Text;
ora_cmd.BindByName = true;
ora_cmd.Parameters.Add(":param1", OracleDbType.Varchar2, "1234", ParameterDirection.Input);
ora_cmd.Parameters.Add(":param2", OracleDbType.Varchar2, "Y", ParameterDirection.Input);
ora_cmd.ExecuteNonQuery();
Ответ 5
Первый кодовый блок верен: используйте двоеточие перед именем параметра, но не в первом аргументе для OracleParameter.
Если ошибок не было, может быть, что UPDATE успешно выполняется, он просто не обновляет записи на основе предложения WHERE и его замещаемого значения параметра. Попробуйте сделать это в тестовой таблице без предложения WHERE в UPDATE, чтобы убедиться, что она что-то делает.
Ответ 6
Здесь тип структуры, который я обычно использую (извините, это из памяти):
int rows = 0;
using ( OracleConnection conn = new OracleConnection(connectionString) ) {
using ( OracleCommand cmd = conn.CreateCommand() ) {
cmd.CommandText = "UPDATE table SET column1 = ':p1 WHERE column2 = :p2";
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue(":p1", p1Val);
cmd.Parameters.AddWithValue(":p2", p2Val);
rows = cmd.ExecuteNonQuery();
}
}
Ключевое различие заключается в использовании AddWithValue - я не помню, почему я это использовал, но помню, что у меня были проблемы с некоторыми другими способами его выполнения.