А>DataSet ds = new DataSet();
А>custDA.Fill(ds, myTableName);
А>//изменение данных
А>custDA.Update(ds, myTableName);
А>custConn.Close();
А>
А>скажите пожалуйста чем будет отличаться если я закрою коннект а потом перед сохранением открою заново вот так
А>SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn); А>custDA.Update(ds, myTableName);
ситуация простая: чем меньшее время ты держишь открытым соединение — тем выше пропускная способность твоего приложения.
Однако, если "изменение данных" — это пара простых операций, то проще все сделать на одном соединении.
На самом деле, для тебя ничем не будет отличаться если не ставил какие-нить специфические опции на подключении, типа set nocount (для SQL Server) и т.п. — они просто сбросятся, и к тому же не факт, что ты получишь повторно именно то же физическое соединение с БД.
Пересоздание адаптера тоже ничем не грозит. Мало того, скажу по секрету, что адаптеру можно дать закрытое соединение. Тогда он его откроет, сделает свое крамольное дело, а потом закроет обратно.
Да хранит вас господь в сухом прохладном месте...
Re[2]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 06:46
Оценка:
Здравствуйте, Козьма Прутков, Вы писали:
КП>Здравствуйте, Аноним, Вы писали:
А>>
А>>DataSet ds = new DataSet();
А>>custDA.Fill(ds, myTableName);
А>>//изменение данных
А>>custDA.Update(ds, myTableName);
А>>custConn.Close();
А>>
А>>скажите пожалуйста чем будет отличаться если я закрою коннект а потом перед сохранением открою заново вот так
А>>SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn); А>>custDA.Update(ds, myTableName); КП>ситуация простая: чем меньшее время ты держишь открытым соединение — тем выше пропускная способность твоего приложения. КП>Однако, если "изменение данных" — это пара простых операций, то проще все сделать на одном соединении. КП>На самом деле, для тебя ничем не будет отличаться если не ставил какие-нить специфические опции на подключении,
нет, никаких специфических опцияй я не выставляю, но дело в том что я работаю через с распределённым приложением:
есть клиенты, есть сервер,
клиенты напрямую общаются с сервером а сервер на прямую с БД
клиент -> сервер(remoting) -> sqlserver
на сервере валяется типизированный DataSet который соответствует базе данных на sql servere...
так вот клиенты добавляют и изменяют записи в этом датасете, и я не могу понять как лучше и надежнее обновлять sqlserverную БД...
зы: клиенты добавляют и изменяют записи довольно часто ... я в замешательстве
КП>типа set nocount (для SQL Server) и т.п. — они просто сбросятся, и к тому же не факт, что ты получишь повторно именно то же физическое соединение с БД. КП>Пересоздание адаптера тоже ничем не грозит. Мало того, скажу по секрету, что адаптеру можно дать закрытое соединение. Тогда он его откроет, сделает свое крамольное дело, а потом закроет обратно.
Здравствуйте, Аноним, Вы писали:
А>скажите пожалуйста чем будет отличаться если я закрою коннект а потом перед сохранением открою заново вот так
А>SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn); А>custDA.Update(ds, myTableName);
Здесь у тебя скорее всего вылетит какой-нибудь эксепшн, ты не указал команд для обновления.
А сконектом не парся SqlDataAdapter сам откроет и закроет коннект если он был закрыт перед вызовом.
А> ну то есть пересоздам dataadapter
Здравствуйте, Аноним, Вы писали:
А>скажите пожалуйста чем будет отличаться если я закрою коннект а потом перед сохранением открою заново вот так
А>SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn); А>custDA.Update(ds, myTableName);
А> ну то есть пересоздам dataadapter
При работе с датаадаптером (во всяком случае с которыми сталкивался я) нет нужды вручную управлять состоянием соединения — Адаптер все сделает сам.
Соединение открывается только для текущей операции после чего сразу закрывается.
DataSet ds = new DataSet();
custDA.Fill(ds, myTableName);
//изменение данных
custDA.Update(ds, myTableName);
custConn.Close();
скажите пожалуйста чем будет отличаться если я закрою коннект а потом перед сохранением открою заново вот так
SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn);
custDA.Update(ds, myTableName);
ну то есть пересоздам dataadapter
Насколько я по памяти помню, DataAdapter оставляет объект Connection в том состоянии после запроса в котором он был до выполнения запроса, тоесть если объект был открыт то он и останеться открытым, если был закрытым то и останется закрытым.
Здравствуйте, DmitryDV, Вы писали:
DDV>Здравствуйте, Аноним, Вы писали:
А>>скажите пожалуйста чем будет отличаться если я закрою коннект а потом перед сохранением открою заново вот так
А>>SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", custConn); А>>custDA.Update(ds, myTableName);
DDV>Здесь у тебя скорее всего вылетит какой-нибудь эксепшн, ты не указал команд для обновления. DDV>А сконектом не парся SqlDataAdapter сам откроет и закроет коннект если он был закрыт перед вызовом.
А>> ну то есть пересоздам dataadapter
ну SqlCommandBuilder создан... exceptionOB не должно быть
на remoting сервере валяется типизированный DataSet который соответствует базе данных на sql servere...
так вот клиенты добавляют и изменяют записи в этом датасете, и я не могу понять как лучше и надежнее обновлять sqlserverную БД...
Здравствуйте, Аноним, Вы писали:
А>зы: клиенты добавляют и изменяют записи довольно часто ... я в замешательстве
Я не уверен, что DataSet который соответствует базе данных на sql servere — подходящее решение. Во-первых, это требует памяти и с ростом базы упрешься в outofmemory. Во-вторых, отсоединенный способ работы с базой хорош для клиентов, но не для сервера (DataSet не потокобезопасен).
Я бы предложил клиентам формировать свой DataSet и изменения из него присылать серваку, который их запишет. При такой схеме клиенты не завязаны друг на друга никак.
Re[4]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 07:24
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>зы: клиенты добавляют и изменяют записи довольно часто ... я в замешательстве
A>Я не уверен, что DataSet который соответствует базе данных на sql servere — подходящее решение. Во-первых, это требует памяти и с ростом базы упрешься в outofmemory. Во-вторых, отсоединенный способ работы с базой хорош для клиентов, но не для сервера (DataSet не потокобезопасен).
A>Я бы предложил клиентам формировать свой DataSet и изменения из него присылать серваку, который их запишет. При такой схеме клиенты не завязаны друг на друга никак.
почему это я упрусь в outofmemory? весь датасет заполняться не будет при загрузке сервера, только определенное количество записей, а нужен он для того что бы синхронизировать действия клиентов...
например регистрация заказов: один клиент формирует у себя заказ, посылает его на remoting server, далее мой remoting сервер сохраняет этот заказ и посылает всем ативным клиентам event с данными об этом заказе ну и соответственно складывает данные у себя. новый подключившийся к серверу клиент запрашивает всю текущую таблицу заказов не подключаясь к sql серверу.
А>почему это я упрусь в outofmemory? весь датасет заполняться не будет при загрузке сервера, только определенное количество записей, а нужен он для того что бы синхронизировать действия клиентов...
А>например регистрация заказов: один клиент формирует у себя заказ, посылает его на remoting server, далее мой remoting сервер сохраняет этот заказ и посылает всем ативным клиентам event с данными об этом заказе ну и соответственно складывает данные у себя. новый подключившийся к серверу клиент запрашивает всю текущую таблицу заказов не подключаясь к sql серверу.
Так "определенное количество" или "вся таблица"? Это разные вещи. Что до примера, то таблица заказов растет, ибо заказы прибывают. Если "вся таблица", то когда-то память кончится. Если "определенное количество", то новым клиентам все равно придется лезть в базу за всей информацией.
А>например регистрация заказов: один клиент формирует у себя заказ, посылает его на remoting server, далее мой remoting сервер сохраняет этот заказ и посылает всем ативным клиентам event с данными об этом заказе ну и соответственно складывает данные у себя
А я бы не стал полагаться на эвенты в ремоутинге, особенно, если от этого будет зависить интегрити данных.
Re[6]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 08:09
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>почему это я упрусь в outofmemory? весь датасет заполняться не будет при загрузке сервера, только определенное количество записей, а нужен он для того что бы синхронизировать действия клиентов...
А>>например регистрация заказов: один клиент формирует у себя заказ, посылает его на remoting server, далее мой remoting сервер сохраняет этот заказ и посылает всем ативным клиентам event с данными об этом заказе ну и соответственно складывает данные у себя. новый подключившийся к серверу клиент запрашивает всю текущую таблицу заказов не подключаясь к sql серверу.
A>Так "определенное количество" или "вся таблица"? Это разные вещи. Что до примера, то таблица заказов растет, ибо заказы прибывают. Если "вся таблица", то когда-то память кончится. Если "определенное количество", то новым клиентам все равно придется лезть в базу за всей информацией.
вся ТЕКУЩАЯ таблица из типизированного датасета...
то есть там (типизированный датасет) храниться не вся таблица заказов а только определенное количество — например 100
и клиент когда подгружается то скачивает всю (состоящую из 100 записей) балицу заказов а н сервере по прежнему их тыщи
Re[6]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 08:11
Оценка:
Здравствуйте, hugo, Вы писали:
H>Здравствуйте, Аноним, Вы писали:
А>>например регистрация заказов: один клиент формирует у себя заказ, посылает его на remoting server, далее мой remoting сервер сохраняет этот заказ и посылает всем ативным клиентам event с данными об этом заказе ну и соответственно складывает данные у себя
H>А я бы не стал полагаться на эвенты в ремоутинге, особенно, если от этого будет зависить интегрити данных.
откуда такие недоверительные отношения к ивентам?
у меня все проходит нормально с ивентами, настоящая проблема в синхронизации данных с sql serverom
Здравствуйте, Аноним, Вы писали:
А>вся ТЕКУЩАЯ таблица из типизированного датасета... А>то есть там (типизированный датасет) храниться не вся таблица заказов а только определенное количество — например 100 А>и клиент когда подгружается то скачивает всю (состоящую из 100 записей) балицу заказов а н сервере по прежнему их тыщи
Стоит ли овчинка выделки? Из-за 100 записей столько проблем поиметь... Неужели так часто подключаются клиенты и вытаскивают эти несчастные 100 записей?
Кстати, есть такой Notification Service, может он тебе подойдет, посмотри.
Re[8]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 08:51
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>вся ТЕКУЩАЯ таблица из типизированного датасета... А>>то есть там (типизированный датасет) храниться не вся таблица заказов а только определенное количество — например 100 А>>и клиент когда подгружается то скачивает всю (состоящую из 100 записей) балицу заказов а н сервере по прежнему их тыщи
A>Стоит ли овчинка выделки? Из-за 100 записей столько проблем поиметь... Неужели так часто подключаются клиенты и вытаскивают эти несчастные 100 записей?
думаю что стоит, хранилище данных может быть не только sql сервер но и другие,
интерфейс к remoting серверу унифицирован...
A>Кстати, есть такой Notification Service, может он тебе подойдет, посмотри.
Здравствуйте, Аноним, Вы писали:
A>>Стоит ли овчинка выделки? Из-за 100 записей столько проблем поиметь... Неужели так часто подключаются клиенты и вытаскивают эти несчастные 100 записей?
А>думаю что стоит, хранилище данных может быть не только sql сервер но и другие, А>интерфейс к remoting серверу унифицирован...
Какое отношение унификация интерфейсов имеет к частоте подключения клиентов? Если клиенты подключаются нечасто, то пусть вытаскивают все по своему унифицированному интерфейсу ради бога.
A>>Кстати, есть такой Notification Service, может он тебе подойдет, посмотри.
А>а что за зверь такой?
Следит за изменениями в ms sql базе и бросает сообщениями при внесении туда изменений.
Re[10]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 09:57
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
A>>>Стоит ли овчинка выделки? Из-за 100 записей столько проблем поиметь... Неужели так часто подключаются клиенты и вытаскивают эти несчастные 100 записей?
А>>думаю что стоит, хранилище данных может быть не только sql сервер но и другие, А>>интерфейс к remoting серверу унифицирован...
A>Какое отношение унификация интерфейсов имеет к частоте подключения клиентов? Если клиенты подключаются нечасто, то пусть вытаскивают все по своему унифицированному интерфейсу ради бога.
я так понял про овчинку относится к типизированому датасету...
вот я и сказал что данные считываться с хранилища и сохраняться туда могут поразному а клиент получует строго определенные данные для этих целей и заполняется типизированный датасет
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Andrbig, Вы писали:
A>>Здравствуйте, Аноним, Вы писали:
A>>>>Стоит ли овчинка выделки? Из-за 100 записей столько проблем поиметь... Неужели так часто подключаются клиенты и вытаскивают эти несчастные 100 записей?
А>>>думаю что стоит, хранилище данных может быть не только sql сервер но и другие, А>>>интерфейс к remoting серверу унифицирован...
A>>Какое отношение унификация интерфейсов имеет к частоте подключения клиентов? Если клиенты подключаются нечасто, то пусть вытаскивают все по своему унифицированному интерфейсу ради бога.
А>я так понял про овчинку относится к типизированому датасету... А>вот я и сказал что данные считываться с хранилища и сохраняться туда могут поразному а клиент получует строго определенные данные для этих целей и заполняется типизированный датасет
То что данные могут по разному считываться и сохраняться — здорово, но к вопросу отношения не имеет. Вопрос — зачем хранить данные на сервере приложений? Клиент стартовал — запрос на сервер приложений — тот выполнил запрос на базу — получил 100 записей — сунул их в типизированный датасет — отдал клиенту.
Re[12]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 12:09
Оценка:
A>То что данные могут по разному считываться и сохраняться — здорово, но к вопросу отношения не имеет. Вопрос — зачем хранить данные на сервере приложений? Клиент стартовал — запрос на сервер приложений — тот выполнил запрос на базу — получил 100 записей — сунул их в типизированный датасет — отдал клиенту.
отдал клиенту и очистил датасет?
а если клиент сохраняет новую запись с автоинкрементным полем тогда как быть?
использовать свое значение локальное автоинкремента он не может
на моем серверной части датасет пуст а сохранять сразу в sql serverenую бд надо прописывать insert команду для каждой таблицы...
Здравствуйте, Аноним, Вы писали:
A>>То что данные могут по разному считываться и сохраняться — здорово, но к вопросу отношения не имеет. Вопрос — зачем хранить данные на сервере приложений? Клиент стартовал — запрос на сервер приложений — тот выполнил запрос на базу — получил 100 записей — сунул их в типизированный датасет — отдал клиенту.
А>отдал клиенту и очистил датасет?
Да. Просто не храни ссылки на датасет и мусорщик его уберет.
А>а если клиент сохраняет новую запись с автоинкрементным полем тогда как быть? А>использовать свое значение локальное автоинкремента он не может А>на моем серверной части датасет пуст а сохранять сразу в sql serverenую бд надо прописывать insert команду для каждой таблицы...
Не очень понял в чем именно проблема. Записывается новая запись, есть автоинкремент — это понятно. Что непонятно? Как получить значение вставленной записи? Использовать ли автоинкремент или генерить самому? Как получить какие ID соответствуют при нескольких строками на запись?
Re[14]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 14:18
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
A>>>То что данные могут по разному считываться и сохраняться — здорово, но к вопросу отношения не имеет. Вопрос — зачем хранить данные на сервере приложений? Клиент стартовал — запрос на сервер приложений — тот выполнил запрос на базу — получил 100 записей — сунул их в типизированный датасет — отдал клиенту.
А>>отдал клиенту и очистил датасет?
A>Да. Просто не храни ссылки на датасет и мусорщик его уберет.
А>>а если клиент сохраняет новую запись с автоинкрементным полем тогда как быть? А>>использовать свое значение локальное автоинкремента он не может А>>на моем серверной части датасет пуст а сохранять сразу в sql serverenую бд надо прописывать insert команду для каждой таблицы...
A>Не очень понял в чем именно проблема. Записывается новая запись, есть автоинкремент — это понятно. Что непонятно? Как получить значение вставленной записи? Использовать ли автоинкремент или генерить самому? Как получить какие ID соответствуют при нескольких строками на запись?
спрошу проще
как в такой случае добавить запись в sql serverную БД ? (в таблице куда надо добавить есть автоинкремент
Здравствуйте, Аноним, Вы писали:
А>спрошу проще А>как в такой случае добавить запись в sql serverную БД ? (в таблице куда надо добавить есть автоинкремент
Добавить проблем нет — добавляешь в датасет, потом адаптер при Update вызывает команду на добавление. Это то что ты хотел услышать или я тебя не понял?
Re[16]: Sql и работа с данными
От:
Аноним
Дата:
05.10.05 14:36
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>спрошу проще А>>как в такой случае добавить запись в sql serverную БД ? (в таблице куда надо добавить есть автоинкремент
A>Добавить проблем нет — добавляешь в датасет, потом адаптер при Update вызывает команду на добавление. Это то что ты хотел услышать или я тебя не понял?
ну я потихоньку подвожу к проблеме
при добавлении в датасет с каким индексом она добавиться (новая строка)
Здравствуйте, Аноним, Вы писали:
А>ну я потихоньку подвожу к проблеме
А>при добавлении в датасет с каким индексом она добавиться (новая строка)
Есть два варианта нормального решения вопроса вставки новых строк:
1. автоинкремент Плюсы: нумерация без пропусков, простота вставки Минусы: сложность получения ID вставленных строк (если их несколько), невозможность сброса нумерации даже при пустой базе
2. генерация ID на сервере, вставка с клиента Плюсы: клиент знает ID вставляемых строк до того, как они попадут в базу (это полезно если есть связанные строки — прописать FK), можно сбросить нумерацию (да и вообще над нумерацией полный контроль) Минусы: возможность образования дыр в нумерации (номер взяли, запись обломилась по каким-то причинам. Впрочем, благодаря контролю над нумерацией это можно решить, если очень мешает )
От того, какое у тебя решение, зависит с каким ID встанет новая строка.
Re[18]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 06:28
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>ну я потихоньку подвожу к проблеме
A>
А>>при добавлении в датасет с каким индексом она добавиться (новая строка)
A>Есть два варианта нормального решения вопроса вставки новых строк:
A>1. автоинкремент A>Плюсы: нумерация без пропусков, простота вставки A>Минусы: сложность получения ID вставленных строк (если их несколько), невозможность сброса нумерации даже при пустой базе
A>2. генерация ID на сервере, вставка с клиента A>Плюсы: клиент знает ID вставляемых строк до того, как они попадут в базу (это полезно если есть связанные строки — прописать FK), можно сбросить нумерацию (да и вообще над нумерацией полный контроль) A>Минусы: возможность образования дыр в нумерации (номер взяли, запись обломилась по каким-то причинам. Впрочем, благодаря контролю над нумерацией это можно решить, если очень мешает )
A>От того, какое у тебя решение, зависит с каким ID встанет новая строка.
второй вариант мне больше нравиться как более правильный, если ты имел ввиду получения следующего id из sql servera, дыр не будет потому что id мы можем получать непосредстевенно перед вставкой, то есть когда строка полностью сформирована, получаем id (get_insert_id, вроде так) и выполняем insert, а вот про первый способ я хотел спросить:
какой именно автоинкремент ты имел ввиду (на моем сервере, sqlservere ...) и если на sql server то как можно сделать инсерт новой строки в sql serverную БД не указывая id?
Здравствуйте, Аноним, Вы писали:
А>второй вариант мне больше нравиться как более правильный, если ты имел ввиду получения следующего id из sql servera, дыр не будет потому что id мы можем получать непосредстевенно перед вставкой, то есть когда строка полностью сформирована, получаем id (get_insert_id, вроде так) и выполняем insert,
Да, генерация из sql-сервера. Если таблиц несколько, то вариантов снова два:
1. на каждую таблицу своя таблица со счетчиком Плюсы: все можно делать в одной транзакции — и получение ID, и вставку Минусы: много таблиц
2. все счетчики сидят в одной таблице (название, последний ID) Плюсы: не надо иметь кучу таблиц, можно сделать одну ХП для получения ID и она подойдет ко всем таблицам Минусы: работу с этой таблицей надо выполнять в отдельной транзакции, чтобы вставки в разные таблицы не мешали друг другу (пересекаясь на генерации ID), и как следствие этого — возможность образования дыр
А>а вот про первый способ я хотел спросить:
А>какой именно автоинкремент ты имел ввиду (на моем сервере, sqlservere ...) и если на sql server то как можно сделать инсерт новой строки в sql serverную БД не указывая id?
Да, автоинкремент как свойство колонки таблицы на sql сервере. Собственно, другого автоинкремента я не знаю.
А в чем проблема с инсертом? Почему собственно нельзя написать оператор инсерт, просто не указав там поля ID?
Re[20]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 07:43
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>второй вариант мне больше нравиться как более правильный, если ты имел ввиду получения следующего id из sql servera, дыр не будет потому что id мы можем получать непосредстевенно перед вставкой, то есть когда строка полностью сформирована, получаем id (get_insert_id, вроде так) и выполняем insert,
A>Да, генерация из sql-сервера. Если таблиц несколько, то вариантов снова два:
A>1. на каждую таблицу своя таблица со счетчиком A>Плюсы: все можно делать в одной транзакции — и получение ID, и вставку A>Минусы: много таблиц
A>2. все счетчики сидят в одной таблице (название, последний ID) A>Плюсы: не надо иметь кучу таблиц, можно сделать одну ХП для получения ID и она подойдет ко всем таблицам A>Минусы: работу с этой таблицей надо выполнять в отдельной транзакции, чтобы вставки в разные таблицы не мешали друг другу (пересекаясь на генерации ID), и как следствие этого — возможность образования дыр
А>>а вот про первый способ я хотел спросить:
А>>какой именно автоинкремент ты имел ввиду (на моем сервере, sqlservere ...) и если на sql server то как можно сделать инсерт новой строки в sql serverную БД не указывая id?
A>Да, автоинкремент как свойство колонки таблицы на sql сервере. Собственно, другого автоинкремента я не знаю.
а как же автоинкремент таблицы типизированного dataseta?
A>А в чем проблема с инсертом? Почему собственно нельзя написать оператор инсерт, просто не указав там поля ID?
да потому что таблиц аж 25
может это и немного но писать почти для каждой insert =((
а commandbuilder сделает все за меня и можно смело вызывать update
Здравствуйте, Аноним, Вы писали:
А>а как же автоинкремент таблицы типизированного dataseta?
От генерации ID на клиенте до катастрофы — один шаг. Никому не посоветую так делать.
A>>А в чем проблема с инсертом? Почему собственно нельзя написать оператор инсерт, просто не указав там поля ID?
А>да потому что таблиц аж 25 А>может это и немного но писать почти для каждой insert =(( А>а commandbuilder сделает все за меня и можно смело вызывать update
Я попробовал — он правильно сгенерил инсерт (не указал автоинкремент). Однако он обломился с update — говорит Select command не вернул ни одного ключевого поля. Похоже, тут надо разбираться.
Лично я написал бы свой commandbuilder, подходящий под все требования конкретной задачи.
Re[22]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 08:24
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>а как же автоинкремент таблицы типизированного dataseta?
A>От генерации ID на клиенте до катастрофы — один шаг. Никому не посоветую так делать.
A>>>А в чем проблема с инсертом? Почему собственно нельзя написать оператор инсерт, просто не указав там поля ID?
А>>да потому что таблиц аж 25 А>>может это и немного но писать почти для каждой insert =(( А>>а commandbuilder сделает все за меня и можно смело вызывать update
A>Я попробовал — он правильно сгенерил инсерт (не указал автоинкремент). Однако он обломился с update — говорит Select command не вернул ни одного ключевого поля. Похоже, тут надо разбираться.
A>Лично я написал бы свой commandbuilder, подходящий под все требования конкретной задачи.
The SelectCommand must also return at least one primary key or unique column. If none are present, an InvalidOperation exception is generated, and the commands are not generated.
это про sqlcommandbuilder
то есть
dataadapter.select(select * from customers, conn);
//в кастомерс обязано быть ключевое поле
//и если оно есть то можно создавать cb
sqlcommandbuilder cb = new sqlcommanbuilder(dataadapter);
тут он генерит для dataadapter insert, update, delete
так вот у меня есть dataTable
dataadapter.Fill(dataTable);
сча у этой таблицы есть автоинкрементное поле
как теперь ты предлагаешь добавить запись?
(что бы можно быловоспользоваться dataadapter.Update(dataTable))
Здравствуйте, Аноним, Вы писали:
А>сча у этой таблицы есть автоинкрементное поле А>как теперь ты предлагаешь добавить запись? А>(что бы можно быловоспользоваться dataadapter.Update(dataTable))
С update проблем нет, вопросы только с insert.
Я попробовал, если поле на sql сделать ключом и автоинкрементом, то все команды генерятся нормально — insert, update, delete. Слушай, если ты так плотно пользуешь commadbuilder, скажи как сделать так, чтобы он в delete и в update включал в условия только ключевые поля, а не все, как он делает сейчас?
Что до твоего вопроса, я бы вероятнее всего отказался от автоинкремента. Мне больше нравится иметь второй вариант. Кстати, именно его ты и пользуешь, только генеришь pk на клиенте, с чем я не согласен.
Re[24]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 09:57
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>сча у этой таблицы есть автоинкрементное поле А>>как теперь ты предлагаешь добавить запись? А>>(что бы можно быловоспользоваться dataadapter.Update(dataTable))
A>С update проблем нет, вопросы только с insert.
при существующем commandbuildere
dataAdapter.Update выполняет не только ведь update
он изменяет в sql бд все переданные методу строки которые помечены как unchaged
A>Я попробовал, если поле на sql сделать ключом и автоинкрементом, то все команды генерятся нормально — insert, update, delete. Слушай, если ты так плотно пользуешь commadbuilder, скажи как сделать так, чтобы он в delete и в update включал в условия только ключевые поля, а не все, как он делает сейчас?
updatecommand and deletecommand and insertcommand commandbuilder генерит в соответствии от команды select переданной dataadapteru на основании которого (dataadaptera)и делается commandbuilder
а дальше можно попробывать вручную изменить updatecommand and deletecommand and insertcommand у dataadaptera
или я не правильно понял вопрос?
A>Что до твоего вопроса, я бы вероятнее всего отказался от автоинкремента. Мне больше нравится иметь второй вариант. Кстати, именно его ты и пользуешь, только генеришь pk на клиенте, с чем я не согласен.
я не генерю id на клиенте...(если ты не имеешь ввиду мой remoting server)
с клиента я лишь передаю данные на сервер (грубо говоря hashtable где ключи имена полей таблицынуи значения их соответственно а по ним могу сформировать строку и вот тут делема как?
все твои ответы мення вели в заблуждение не мог бы ты подробнее начиная с момента получения сервером информации о заказе перед непосредственным добавлением, где надо убирать автоинкремент, чем обновлять и тд
Re[25]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 10:00
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Andrbig, Вы писали:
A>>Здравствуйте, Аноним, Вы писали:
А>>>сча у этой таблицы есть автоинкрементное поле А>>>как теперь ты предлагаешь добавить запись? А>>>(что бы можно быловоспользоваться dataadapter.Update(dataTable))
A>>С update проблем нет, вопросы только с insert.
А>при существующем commandbuildere А>dataAdapter.Update выполняет не только ведь update А>он изменяет в sql бд все переданные методу строки которые не помечены как unchaged
У меня таблица с полями: pk (key, increment), f1, f2. Вот какой update сделал commandbuilder:
UPDATE ab SET f1 = @p1 , f2 = @p2 WHERE ( (pk = @p3) AND ((@p4 = 1 AND f1 IS NULL) OR (f1 = @p5)) AND ((@p6 = 1 AND f2 IS NULL) OR (f2 = @p7)) )
Вопрос: можно ли сделать так, чтобы commandbuilder выдал:
UPDATE ab SET f1 = @p1 , f2 = @p2 WHERE pk = @p3
Меня не устраивал его код. Кроме того, для формирования своего кода он выполняет запрос на сервер — за схемой! Вот поэтому я отказался от commandbuilder-a. У меня не было динамических таблиц, все фиксированное и ходить за неизменной схемой было незачем.
А>я не генерю id на клиенте...(если ты не имеешь ввиду мой remoting server)
Речь идет про sql сервер. Клиентом для него является твой ремотинг-сервер — я про него говорю.
А>все твои ответы мення вели в заблуждение не мог бы ты подробнее начиная с момента получения сервером информации о заказе перед непосредственным добавлением, где надо убирать автоинкремент, чем обновлять и тд
Чтобы говорить подробнее, надо знать подробнее:
1. клиент (твой ремотинг-сервис) добавляет строки в базу (в таблицу sql то бишь). Надо ли ему знать id вставленных строк и зачем?
2. к таблице, которая содержит новые строки (еще на записанным) есть подчиненные таблицы (master-detail)?
Re[26]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 12:01
Оценка:
A>Чтобы говорить подробнее, надо знать подробнее: A>1. клиент (твой ремотинг-сервис) добавляет строки в базу (в таблицу sql то бишь). Надо ли ему знать id вставленных строк и зачем?
надо что бы потом разослать всем клиентам регистрирующим вызовы эту строку с правильным id
A>2. к таблице, которая содержит новые строки (еще на записанным) есть подчиненные таблицы (master-detail)?
нет, таблица польностью без всяких связей и ограничений
Здравствуйте, Аноним, Вы писали:
A>>Чтобы говорить подробнее, надо знать подробнее: A>>1. клиент (твой ремотинг-сервис) добавляет строки в базу (в таблицу sql то бишь). Надо ли ему знать id вставленных строк и зачем?
А>надо что бы потом разослать всем клиентам регистрирующим вызовы эту строку с правильным id
A>>2. к таблице, которая содержит новые строки (еще на записанным) есть подчиненные таблицы (master-detail)?
А>нет, таблица польностью без всяких связей и ограничений
В твоем случае самым простым решением будет автоинкрементный ключ. Открываешь connection, стартуешь транзакцию, находишь максимальный ID (select max(id) from xxx), далее делаешь DataAdapter.Update, потом делаешь select * where ID > того максимального, транзакцию комитишь.
Все, записи у тебя есть, рассылаешь.
Re[28]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 13:15
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
A>>>Чтобы говорить подробнее, надо знать подробнее: A>>>1. клиент (твой ремотинг-сервис) добавляет строки в базу (в таблицу sql то бишь). Надо ли ему знать id вставленных строк и зачем?
А>>надо что бы потом разослать всем клиентам регистрирующим вызовы эту строку с правильным id
A>>>2. к таблице, которая содержит новые строки (еще на записанным) есть подчиненные таблицы (master-detail)?
А>>нет, таблица польностью без всяких связей и ограничений
A>В твоем случае самым простым решением будет автоинкрементный ключ. Открываешь connection, стартуешь транзакцию, находишь максимальный ID (select max(id) from xxx), далее делаешь DataAdapter.Update,
почему update?мне же надо строку вставить...
или ты предлагаешь просто добавлять строку в таблицу и потом вызывать
da.Update c самописным insertcommandom? (гдене надо учитывать id)
а как ты предлагаешь adapter делать?
прописывать сови insert, update, remove commands?
брррррр.... опять запутался
A> потом делаешь select * where ID > того максимального, транзакцию комитишь.
A>Все, записи у тебя есть, рассылаешь.
Здравствуйте, Аноним, Вы писали:
А>брррррр.... опять запутался
Да, действительно запутался. Итак, по порядку.
1. есть база с таблицей, в которой ключевое поле является автоинкрементным
2. на эту таблицу делаешь адаптер, у которого SelectCommand такой: select * from xxx
3. вызываешь commanbuilder с этим адаптером, он генерит три остальные команды. При этом он понимает что поле автоинкрементное и не вклчюет его в update и insert
4. присваиваешь полученные команды в адаптер. Ура! Адаптер готов к работе.
Теперь приходят записи с твоего клиента на ремотинг сервис, где происходит следующее:
1. создаешь пустой датасет
2. добавленные записи у клиента добавляешь в таблицу в датасете
3. открываешь connection, стартуешь транзакцию
4. выполняешь в этой транзакции selct max(id) from xxx, запоминаешь полученное число как N
5. вызываешь DataAdapter.Update
6. выполняешь select * from xxx where id > N
7. комитишь транзакцию
8. полученное на шаге 6 рассылаешь клиентам
С insert-ом стало понятней, идем дальше?
Re[30]: Sql и работа с данными
От:
Аноним
Дата:
06.10.05 14:11
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>брррррр.... опять запутался
A>Да, действительно запутался. Итак, по порядку.
A>1. есть база с таблицей, в которой ключевое поле является автоинкрементным A>2. на эту таблицу делаешь адаптер, у которого SelectCommand такой: select * from xxx A>3. вызываешь commanbuilder с этим адаптером, он генерит три остальные команды. При этом он понимает что поле автоинкрементное и не вклчюет его в update и insert A>4. присваиваешь полученные команды в адаптер. Ура! Адаптер готов к работе.
A>Теперь приходят записи с твоего клиента на ремотинг сервис, где происходит следующее:
A>1. создаешь пустой датасет A>2. добавленные записи у клиента добавляешь в таблицу в датасете A>3. открываешь connection, стартуешь транзакцию A>4. выполняешь в этой транзакции selct max(id) from xxx, запоминаешь полученное число как N A>5. вызываешь DataAdapter.Update A>6. выполняешь select * from xxx where id > N A>7. комитишь транзакцию A>8. полученное на шаге 6 рассылаешь клиентам
A>С insert-ом стало понятней, идем дальше?
да, только я думал что комманды присваивать не надо
во всех примерах в msdn просто создается SqlCommandBuilder cb = new SqlCommandBuilder(da);
и сё...
кстати для вставкин надо искать не max(id) а `Id`=last_insert_id() вот...
а так супер... все понял
идем дальше?
Здравствуйте, Аноним, Вы писали:
А>да, только я думал что комманды присваивать не надо А>во всех примерах в msdn просто создается SqlCommandBuilder cb = new SqlCommandBuilder(da); А>и сё...
Может просто создать SqlCommandBuilder будет достаточно. Я с SqlCommandBuilder не работаю, таких тонкостей не знаю. Проверь.
А>кстати для вставкин надо искать не max(id) а `Id`=last_insert_id() вот... А>а так супер... все понял А>идем дальше?
Нет, не идем. Теперь я уже не понял, что ты понял. Поясни почему надо искать "не max(id) а `Id`=last_insert_id()". max — агрегативная функция sql. Кто такой last_insert_id?
A>Нет, не идем. Теперь я уже не понял, что ты понял. Поясни почему надо искать "не max(id) а `Id`=last_insert_id()". max — агрегативная функция sql. Кто такой last_insert_id?
есть таблица с автоинкрементом на server sqlной БД
при добавлении туда записи генериться id но он != "max(id) from tableName"
можешь попробывать добавлять записи через какой нить sql манагер
например у тебя 10 записей
ты добавляешь новую у нее стал id = 11;
далее ты удалил 11-ую запись — у тебя снова стало 10 записей но если ты еще раз попытаешься вставить запись то её id будет не 11 а 12... то есть образуется пропуск (из-за удаленной записи)
то есть я сделаю инсерт у моей новой записи будет id 12 а незадолго до этого я получу max(id) = 10... хотя я смотрю ты тут предложил искать все записи что больше 10 тогда нормально я все равно получу 12
и еще update и delete генеряться commandbuilderom нормально а вот инсерт можно делать только по одной записи иначе будетпопыстка вставить 10 записей с один и тем же индексом... насчет последнего я понятно объяснил? просто это важный момент походу изза него у меня и проблемы
Здравствуйте, 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())