Здравствуйте, Grammer, Вы писали:
A>>Нет, не идем. Теперь я уже не понял, что ты понял. Поясни почему надо искать "не max(id) а `Id`=last_insert_id()". max — агрегативная функция sql. Кто такой last_insert_id?
ну и забыл сказать что last_insert_id() такая же функция sql
SELECT LAST_INSERT_ID() FROM $table
только вернет она (из моего прошлого примера) не 10 а 12
то есть следующий индекс с которым бы вставила sql serverная БД если ей не указать явно индекс
Здравствуйте, Grammer, Вы писали:
G>например у тебя 10 записей G>ты добавляешь новую у нее стал id = 11; G>далее ты удалил 11-ую запись — у тебя снова стало 10 записей но если ты еще раз попытаешься вставить запись то её id будет не 11 а 12... то есть образуется пропуск (из-за удаленной записи)
G>то есть я сделаю инсерт у моей новой записи будет id 12 а незадолго до этого я получу max(id) = 10... хотя я смотрю ты тут предложил искать все записи что больше 10 тогда нормально я все равно получу 12
Да, именно так, в том и хитрость.
G>и еще update и delete генеряться commandbuilderom нормально а вот инсерт можно делать только по одной записи иначе будетпопыстка вставить 10 записей с один и тем же индексом... насчет последнего я понятно объяснил? просто это важный момент походу изза него у меня и проблемы
Ничего подобного. Ты вставляешь 20 записей без указания ключа (ибо он автоинкремент). До вставки max(id) = 10 (твой пример), после вставки записи получили значения ключа 12..32 и они все нашлись по условию id > 10.
Никаких last_insert_id тут не надо, забудь эту функцию, она не подходит к твой ситуации.
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Grammer, Вы писали:
G>>например у тебя 10 записей G>>ты добавляешь новую у нее стал id = 11; G>>далее ты удалил 11-ую запись — у тебя снова стало 10 записей но если ты еще раз попытаешься вставить запись то её id будет не 11 а 12... то есть образуется пропуск (из-за удаленной записи)
G>>то есть я сделаю инсерт у моей новой записи будет id 12 а незадолго до этого я получу max(id) = 10... хотя я смотрю ты тут предложил искать все записи что больше 10 тогда нормально я все равно получу 12
A>Да, именно так, в том и хитрость.
G>>и еще update и delete генеряться commandbuilderom нормально а вот инсерт можно делать только по одной записи иначе будетпопыстка вставить 10 записей с один и тем же индексом... насчет последнего я понятно объяснил? просто это важный момент походу изза него у меня и проблемы
A>Ничего подобного. Ты вставляешь 20 записей без указания ключа (ибо он автоинкремент). До вставки max(id) = 10 (твой пример), после вставки записи получили значения ключа 12..32 и они все нашлись по условию id > 10.
A>Никаких last_insert_id тут не надо, забудь эту функцию, она не подходит к твой ситуации.
хм...
вот попытался без commanbuildera сделать:
da = new SqlDataAdapter("SELECT * FROM myTable", conn);
da.InsertCommand = new SqlCommand("INSERT INTO `db`.`contact` (`Id`, `PhoneNumber`) VALUES (`?Id`, ?PhoneNumber); SELECT `Id`, `PhoneNumber` FROM `db`.`contact WHERE (`Id`=last_insert_id())", conn);
da.UpdateCommand = new MySqlCommand("UPDATE `db`.`contact` SET `Id`=?Id, `PhoneNumber`=?PhoneNumber WHERE `Id` <=> ?Original_Id AND `PhoneNumber` <=> ?Original_PhoneNumber; SELECT `Id`, `PhoneNumber` FROM `db`.`contact` WHERE (`Id`=?Original_Id)", conn);
дальше кидаю на форму грид, создаю myTable (empty), ставлю dataSource и добавляю новую строку
имею в гриде одну строку с Id = 0 и phoneNumber = "fooNumber"
conn.Open();
da.Update(myTable)
conn.Close();
с commandbuilderom работает а при таком коде нет
текст insertcommand взял тот который сгенерил commandbuilder
выкидывает exception c ?Id must be defined
что я забыл указать? и вообще кинь кода как ты создаешь da и обновляешь table
что таблиц много и потому хочется чтобы команды генерил commandbuilder?
G>что я забыл указать? и вообще кинь кода как ты создаешь da и обновляешь table
Ты с упорством, достойным лучшего применения пытаешься изменить автоинкрементное поле. Ну не получится это, не получился! Контроль надо этим полем полностью у sql-сервера, так что его не тронь:
INSERT INTO `db`.`contact` (`PhoneNumber`) VALUES (?PhoneNumber)
UPDATE `db`.`contact` SET `PhoneNumber`=?PhoneNumber WHERE `Id` == ?Original_Id AND `PhoneNumber` <=> ?Original_PhoneNumber;
Если ты взглянешь что генерит commanbuiler, то увидишь аналогичную картину.
Что касается получения обновленных записей, с ними можно использовать то, что делает визард при генерации адаптера — select после update.
Что касается получения новых], тут либо использовать last_insert_id, либо потом скопом вытащить все вставленные записи через max(), как я предлагал.
что таблиц много и потому хочется чтобы команды генерил commandbuilder?
G>>что я забыл указать? и вообще кинь кода как ты создаешь da и обновляешь table
A>Ты с упорством, достойным лучшего применения пытаешься изменить автоинкрементное поле. Ну не получится это, не получился! Контроль надо этим полем полностью у sql-сервера, так что его не тронь: A>
A>INSERT INTO `db`.`contact` (`PhoneNumber`) VALUES (?PhoneNumber)
A>UPDATE `db`.`contact` SET `PhoneNumber`=?PhoneNumber WHERE `Id` == ?Original_Id AND `PhoneNumber` <=> ?Original_PhoneNumber;
A>
A>Если ты взглянешь что генерит commanbuiler, то увидишь аналогичную картину.
A>Что касается получения обновленных записей, с ними можно использовать то, что делает визард при генерации адаптера — select после update. A>Что касается получения новых], тут либо использовать last_insert_id, либо потом скопом вытащить все вставленные записи через max(), как я предлагал.
да говорил что много... но я решил проверить что генерит commandbuilder
про упорство может и правда, но я спать спокойно не буду если все не узнаю
а насчет Id ты не прав... я ничего не пытаюсь изменить
наооборот хочу воспользоваться тем что sql сам все сделает
Id генерит commandbuilder и вот что бывает даже если я его удалю
Parameter '?PhoneNumber' must be defined
я просто как то не правильно присваиваю SqlCommand dataadapteru
поэтому и попросил твой код
и еще скажу что когда я создаю da:
da = new SqlDataAdapter("SELECT * FROM contact, conn);
da.Update равно null
da.Delete равно null
da.Insert тоже
далее после
SqlCommandBuilder cb = new SqlCommandBuilder(da);
эти поля остаются пустыми но dataadapter уже знает эти команды и может ими пользоваться
я больше ничего не присваиваю и все работает а просмотрел я комманды след образом
Здравствуйте, Grammer, Вы писали:
G>а насчет Id ты не прав... я ничего не пытаюсь изменить
da.UpdateCommand = new MySqlCommand("UPDATE `db`.`contact` SET `Id`=?Id, `PhoneNumber`=?PhoneNumber WHERE `Id` <=> ?Original_Id
G>Id генерит commandbuilder и вот что бывает даже если я его удалю
Раз id генерится, это означает только одно — он у тебя в таблице на sql-сервере не автоинкрементный! Угадал?
G>покажи как ты без commandbuilder прописываешь update insert и delete команды для dataadaptera
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Grammer, Вы писали:
G>>а насчет Id ты не прав... я ничего не пытаюсь изменить A>
A>da.UpdateCommand = new MySqlCommand("UPDATE `db`.`contact` SET `Id`=?Id, `PhoneNumber`=?PhoneNumber WHERE `Id` <=> ?Original_Id
G>>Id генерит commandbuilder и вот что бывает даже если я его удалю A>Раз id генерится, это означает только одно — он у тебя в таблице на sql-сервере не автоинкрементный! Угадал?
эх неугадал:
вот кусок скрипта:
/*==============================================================*/
/* Table: _Contact */
/*==============================================================*/create table _Contact
(
Id bigint not null AUTO_INCREMENT,
PhoneNumber varchar(50),
)
type = InnoDB;
вот тут результат на лицо:
а вот тут полный текст полученой sql command:
INSERT INTO `spas001`.`_contact` (`Id`, `PhoneNumber`) VALUES (?Id, ?PhoneNumber); SELECT `Id`, `PhoneNumber` FROM `spas001`.`_contact` WHERE (`Id`=last_insert_id())