Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > Получить ID только что вставленной строки


Автор: Artorius 14.11.2007, 20:42
Стоит такая задача, вставить запись в таблицу и получить референс только что вставленной записи.
Пишу на C# (Framework 2.0) под Oracle.
Подозреваю, что применяемый мною метод не самый элегантный. Может кто нибудь знает более короткий и эфективный?

Код

public virtual bool MakeOperation(OracleTransaction RunningTransaction)
        {
            bool Result = false;
            OracleCommand Command;
            OracleDataReader DataReader;

            string CommandText = " insert into table1            \n" + 
                                 " values ( table1_seq.nextval,  \n" + 
                                 "          :Param1,             \n" +
                                 "          :Param2              \n";

            Command = new OracleCommand(CommandText, RunningTransaction.Connection);
            Command.Parameters.AddWithValue(":Param1"    , Param1Value);
            Command.Parameters.AddWithValue(":Param2"    , Param2Value);

            Command.Transaction = RunningTransaction;
            try
            {
                if (Command.ExecuteNonQuery() == 1)
                {
                    Command = new OracleCommand(" select table1_seq.currval Reference from DUAL ", 
                                                RunningTransaction.Connection,
                                                RunningTransaction);

                    DataReader = Command.ExecuteReader(CommandBehavior.SingleResult);

                    if (DataReader.Read())
                        fReference = DataReader.GetInt32(DataReader.GetOrdinal("Reference"));

                    Result = fReference > 0;
                }
            }
            catch
            {
                RunningTransaction.Rollback();
                return Result;
            }
            
            return Result;
        }

Автор: Papirus 15.11.2007, 16:22
Может аналогия поможет, т.к. про Оракл сказать ничего не могу. В SQL server можно делать так:

Код

{
           ...
            System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
           cmd.CommandText = "Insert Into MyTable set Field1 = @f1...; Select scope_identity()";
            Int32 id = cmd.ExecuteScalar(); 
        }


Вот это выражение "; Select scope_identity()" после точки с запятой и возвращает последний сгенерированный БД id (значение счетчика) после вставки данных.

Автор: Artorius 16.11.2007, 19:18
Не получилось так - не понравилась ему ";" между SQL-командами. 
Кстати Oracle вообще очень нервно реагирует на точку с запятой в командах... это естественно в коде на C#, в оболочке конечно все отрабатывает хорошо.

Есть метод OracleCommand.ExecuteOracleNonQuery(out OracleString), возвращающий ID строки в OracleString. Потом по этому ID можно получить быстрый (быстрее чем поиск по первичному ключу) доступ к строке. Но так как тут есть последовательность, у меня сомнения появляются, будет ли такой запрос работать быстрее чем запрос к последовательности...

Автор: alik_voodoo 19.11.2007, 17:57
Для этого можно банально запустить отдельный ExecuteReader, который находит в нужной тебе таблице максимальный ID.

Автор: Enuviel 20.11.2007, 13:18
Цитата

Не получилось так - не понравилась ему ";" между SQL-командами. 
Кстати Oracle вообще очень нервно реагирует на точку с запятой в командах... это естественно в коде на C#, в оболочке конечно все отрабатывает хорошо.

Oracle клиент  не работает с пакетными SQL запросами, в отличии от SQL клиента, вот и реагирует нервно. 

Автор: Artorius 21.11.2007, 19:45
Enuviel, это я уже понял smile


alik_voodoo, именно так и делаю, и именно то, что ExecuteReader отдельный мне и не нравится

Ладно, спасибо всем, а отдельное спасиб Papirus'у, за напоминание про ExecuteScalar() - я про него подзабыл)) - с ним код чуть проще получется.

Автор: Gesha 26.11.2007, 09:54
Код

            OracleConnection con = ...constr...;
            OracleTransaction txn = con.BeginTransaction(IsolationLevel.ReadCommitted);

            cmd = new OracleCommand(" insert into table (field1, ...) values (param1,...) returning ID into :ID", con);
            cmd.CommandType = CommandType.Text;
            cmd.BindByName = true;
            cmd.Parameters.Add(...);
              ....
            cmd.Parameters.Add("ID", OracleDbType.Int32, ParameterDirection.Output);
            cmd.ExecuteNonQuery();
            int ID = Convert.ToInt32(cmd.Parameters["ID"].Value);
            ....

  

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)