mchlcmprch Ответов: 4

Sqlite.net... получите последний идентификатор вставки...


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

           String connString = "Data Source=" + Properties.Resources.dataSource;
                SQLiteConnection conn = new SQLiteConnection(connString);

                SQLiteCommand cmd = new SQLiteCommand(conn);
                
                cmd.CommandText = "insert into lyrics (song, lyrics) values (@title, @words);";
                cmd.Parameters.AddWithValue("@title", _title);
                cmd.Parameters.AddWithValue("@words", _words);
                
                SQLiteCommand cmd_id = new SQLiteCommand(conn);
                cmd_id.CommandText = "select last_insert_rowid() as id from lyrics";
                
                conn.Open();
                cmd.ExecuteNonQuery();

<big>                _id = (int) cmd_id.ExecuteScalar(); <--- the code gags on this telling me I am not getting a valid value!!! 
</big>                //cmd_id.
                conn.Close();
                conn.Dispose();
                return true;


Любые предложения будут оценены по достоинству... Я был по всему Google с этим (именно там я получил код, который у меня есть)...

Спасибо

Майкл

4 Ответов

Рейтинг:
2

R. Hoffmann

Как насчет присвоения возвращаемого значения из ExecuteScalar() временной переменной типа Object, а затем просмотра в отладчике, чтобы увидеть, что возвращается?

Иначе говоря:

object val = cmd_id.ExecuteScalar();
_id = (int)val; // Set a breakpoint here, and examine the contents of val


Возможно, вы получаете обратно значение DbNull, указывающее на то, что ваш запрос не был выполнен должным образом. Или, возможно, значение, которое возвращается с помощью last_insert_rowid() не относится к типу int.


Рейтинг:
1

mchlcmprch

Отладчик показывает, что я получаю длинную спину. Хммм... наверное, мне нужно вернуться к базовому классу и изменить _id с int на long. Определение таблицы Sqlite - "целое число"... Предположим, мне нужно посмотреть документацию Sqlite, чтобы понять, что это на самом деле означает.

Спасибо за вклад!

Майкл


R. Hoffmann

Круто, рад, что все улажено :)

Member 11631592

его возвращение 0 в _id помогите пожалуйста

Рейтинг:
1

Jym_M

Проблема заключается в следующем: вы думаете, что last_insert_rowid() возвращает информацию из вашего целочисленного столбца первичного ключа, а не возвращает значение в скрытом поле rowid. Вы можете увидеть эту информацию, если запросите таблицу "SELECT rowid, * FROM your_table".

Поэтому, чтобы действительно получить поле первичного ключа, вы должны запросить его. (это также помогает, если вы не используете целое число .. то есть номерной знак)

Выберите my_primary_key из my_table
Где rowid in (select DISTINCT (last_insert_rowid()) FROM my_table);

last_insert_rowid() вернет набор записей с x записями (x = количество строк в таблице), поэтому distinct делает его немного быстрее.


Рейтинг:
0

mchlcmprch

Хорошо, спасибо за это "объектное" предложение. На самом деле я получал и возражал обратно с "правильным" ответом. Изменил свой код, как показано ниже, и все, кажется, работает...

cmd_id.CommandText = "select last_insert_rowid() as id from lyrics";
conn.Open();
cmd.ExecuteNonQuery();
System.Object temp = cmd_id.ExecuteScalar();
_id = int.Parse (temp.ToString());


Есть ли "более аккуратный","более чистый" способ сделать это преобразование?

Спасибо
Майкл


R. Hoffmann

Это зависит от того: если вы получаете обратно строку из ExecuteScalar, то вы не получите ее намного аккуратнее, чем то, что у вас есть сейчас. Вы можете избавиться от переменной temp и поставить cmd_id.ExecuteScalar().ToString() непосредственно входит в вызов синтаксического анализа, но это все. Вы, возможно, захотите, чтобы добавить код, чтобы справиться с DBNulls, когда там последний код для получения.

Однако посмотрите, каков на самом деле тип возвращаемого значения (в разделе отладчик). Возможно, вы все еще можете использовать свой исходный код, но с правильным типом (т. е. не int). Может быть, это тип uint или что-то еще. например, _id = (uint) cmd_id.Executescalar так();

harshadcse

Рабочий код..

Спасибо..