Re[33]: Sql и работа с данными
От: Grammer  
Дата: 07.10.05 06:51
Оценка:
Здравствуйте, 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ная БД если ей не указать явно индекс
Re[33]: Sql и работа с данными
От: Andrbig  
Дата: 07.10.05 08:35
Оценка: 2 (1)
Здравствуйте, 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 тут не надо, забудь эту функцию, она не подходит к твой ситуации.
Re[34]: Sql и работа с данными
От: Grammer  
Дата: 07.10.05 09:51
Оценка:
Здравствуйте, 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
Re[35]: Sql и работа с данными
От: Andrbig  
Дата: 07.10.05 10:12
Оценка:
Здравствуйте, Grammer, Вы писали:


G>хм...

G>вот попытался без commanbuildera сделать:

Хм... Кто писал
Автор:
Дата: 06.10.05
что таблиц много и потому хочется чтобы команды генерил 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(), как я предлагал.
Re[36]: Sql и работа с данными
От: Grammer  
Дата: 07.10.05 11:50
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>Здравствуйте, Grammer, Вы писали:



G>>хм...

G>>вот попытался без commanbuildera сделать:

A>Хм... Кто писал
Автор:
Дата: 06.10.05
что таблиц много и потому хочется чтобы команды генерил 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 уже знает эти команды и может ими пользоваться
я больше ничего не присваиваю и все работает а просмотрел я комманды след образом

cb.GetInsertCommand();
cb.GetUpdateCommand();
cb.GetDeleteCommand();


ну и он был таким какой я тебе показал в прошлой мессаге

покажи как ты без commandbuilder прописываешь update insert и delete команды для dataadaptera
Re[37]: Sql и работа с данными
От: Andrbig  
Дата: 07.10.05 12:53
Оценка:
Здравствуйте, 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

sqlDataAdapter1.DeleteCommand = this.sqlDeleteCommand1;
sqlDataAdapter1.InsertCommand = this.sqlInsertCommand1;
sqlDataAdapter1.SelectCommand = this.sqlSelectCommand1;
sqlDataAdapter1.UpdateCommand = this.sqlUpdateCommand1;

sqlSelectCommand1.CommandText = "SELECT pk, f1, f2 FROM ab";
sqlSelectCommand1.Connection = sqlConnection1;

sqlInsertCommand1.CommandText = "INSERT INTO ab(f1, f2) VALUES (@f1, @f2)";
sqlInsertCommand1.Connection = sqlConnection1;
sqlInsertCommand1.Parameters.Add(new SqlParameter("@f1", SqlDbType.Int, 4, "f1"));
sqlInsertCommand1.Parameters.Add(new SqlParameter("@f2", SqlDbType.Int, 4, "f2"));

sqlUpdateCommand1.CommandText = "UPDATE ab SET f1 = @f1, f2 = @f2 WHERE (pk = @Original_pk)";
sqlUpdateCommand1.Connection = sqlConnection1;
sqlUpdateCommand1.Parameters.Add(new SqlParameter("@f1", SqlDbType.Int, 4, "f1"));
sqlUpdateCommand1.Parameters.Add(new SqlParameter("@f2", SqlDbType.Int, 4, "f2"));
sqlUpdateCommand1.Parameters.Add(new SqlParameter("@Original_pk", SqlDbType.Int, 4, ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "pk", DataRowVersion.Original, null));

sqlDeleteCommand1.CommandText = "DELETE FROM ab WHERE (pk = @Original_pk)";
sqlDeleteCommand1.Connection = sqlConnection1;
sqlDeleteCommand1.Parameters.Add(new SqlParameter("@Original_pk", SqlDbType.Int, 4, ParameterDirection.Input, false, ((System.Byte)(0)), ((System.Byte)(0)), "pk", DataRowVersion.Original, null));

Замечу что этот код сделал стандартный визард, причем все правильно. Вот поэтому я им и пользуюсь!
Re[38]: Sql и работа с данными
От: Grammer  
Дата: 07.10.05 13:26
Оценка:
Здравствуйте, 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())



вот так даже не знаю как быть
Re[39]: Sql и работа с данными
От: Andrbig  
Дата: 07.10.05 14:06
Оценка:
Здравствуйте, Grammer, Вы писали:

G>эх неугадал:

G>вот кусок скрипта:

G>/*==============================================================*/
G>/* Table: _Contact                                              */
G>/*==============================================================*/
G>create table _Contact
G>(
G>   Id                             bigint                         not null AUTO_INCREMENT,
G>   PhoneNumber                    varchar(50),
G>)
G>type = InnoDB;



G>вот так даже не знаю как быть


А вот мой скрипт полностью:

CREATE TABLE [ab] (
    [pk] [int] IDENTITY (1, 1) NOT NULL ,
    [f1] [int] NULL ,
    [f2] [int] NULL ,
    CONSTRAINT [PK_ab] PRIMARY KEY  CLUSTERED 
    (
        [pk]
    )  ON [PRIMARY] 
) ON [PRIMARY]

Попробуй его (на вкус ).
Re[18]: Sql и работа с данными
От: akasoft Россия  
Дата: 07.10.05 15:18
Оценка: +1
Здравствуйте, Andrbig, Вы писали:

A>Есть два варианта нормального решения вопроса вставки новых строк:


Есть ещё guid, как уникальный идентификатор строки таблицы. Может генерироваться клиентом, обеспечивает FK.
... << RSDN@Home 1.2.0 alpha rev. 618>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.