powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Row changed between retrieve and update
25 сообщений из 26, страница 1 из 2
Row changed between retrieve and update
    #38147451
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется база данных Access.
В таблице 2 поля: id (autonumber), name (string)
Код на открытии окна:

dw_1.SetTransObject(sqlca)
dw_1.Retrieve()
dw_1.InsertRow(0)

//Теперь пишем имя 111 и жмем на кнопочку сохранить:
dw_1.Update()

// Все отлично. Все сохраняется. Теперь вносим изменение в имя. Например, пишем 111333 и опять жмем на сохранить. Получаем ошибку.

Проблема в автономере. Первый раз (при статусе New!) база сама поставила номер. Во второй раз номер NULL.
Если сделать dw_1.SetItem(1, 'id', max_number_from_db), то, в зависимости от Key Modification получим другие ошибки:
Use Delete then Insert - нельзя удалить строку, где id is NULL.
Use Update - нельзя изменять автономер. Но id по-видимому, все равно NULL.

Как победить? Делать Retrieve() после сохранения нельзя. Insert напрямую в базу данных тоже нельзя.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38147544
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
уберите id (автономер) из updateable columns
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38147550
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, забыл : для id установлено identity?
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38147605
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulJBуберите id (автономер) из updateable columns
Не помогает. Проблема в NULL.
для id установлено identity? - Нет
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38147701
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автордля id установлено identity? - Нет
Установите ...
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38147747
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
... и проверьте значение колонки в DW после первого апдейта.
Когда вставляете запись insertrow(0) - id= null
После апдейта (INSERT-а) - id в DW должно быть автоматически заполнено значением (автономер), полученным из базы.
Если этого нет, то каким-то образом сразу после апдейта (INSERT-а) получите идентификатор, вставьте его в поле DW id и не забудьте сделать dw.resetupdate().
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38147990
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PaulJB... и проверьте значение колонки в DW после первого апдейта.
Когда вставляете запись insertrow(0) - id= null
После апдейта (INSERT-а) - id в DW должно быть автоматически заполнено значением (автономер), полученным из базы.
Если этого нет, то каким-то образом сразу после апдейта (INSERT-а) получите идентификатор, вставьте его в поле DW id и не забудьте сделать dw.resetupdate().

Установите ... - Рояля не играет :(

проверьте значение колонки в DW после первого апдейта - NULL

Проблема в автономере. Первый раз (при статусе New!) база сама поставила номер. Во второй раз номер NULL.
Если сделать SetItem, то...
(мы с этого начали - см. первый пост).
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38148072
alexis glinski
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а через что к базе коннект?
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38148112
Фотография spas2001
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
C Access есть определенный геморрой в этом плане
Поставьте для update properties - Key Columns
Modification - Use Update,
Primary Key - id
Identity column - id
И уберите id из обновления
Но как показала практика - работает такая фишка через раз
Я делал абсолютно левую таблицу где получал именно значение для ключа, а доставал примерно так
Код: sql
1.
2.
3.
4.
5.
6.
7.
	DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA ;
				
				ls = "SELECT @@IDENTITY FROM "+upper(as_tablename)
				PREPARE SQLSA FROM :ls;
				OPEN DYNAMIC my_cursor ;
				FETCH my_cursor INTO :ll_id ;
				CLOSE my_cursor ;


Ну или попроще
Код: sql
1.
select  @@identity into :ll_id from my_table


А потом работал как с уникальным значением
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38148490
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если после dw_1.SetItem(1, 'id', max_number_from_db) значение колонки остается NULL, то метод не отработал.
Или значение есть, а ошибка осталась?

А у Вас есть возможность узнать: какое значение будет иметь поле с автономером перед инсертом.
Например в ASA есть возможность узнать будущее значение поля с autoincrement перед INSERT-ом.
Если такая возможность есть, то задача решается просто, но при усдлвии, что Access позволяет изменять поле с автономером.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38148697
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RiskaИмеется база данных Access.
В таблице 2 поля: id (autonumber), name (string)
Код на открытии окна:

dw_1.SetTransObject(sqlca)
dw_1.Retrieve()
dw_1.InsertRow(0)

//Теперь пишем имя 111 и жмем на кнопочку сохранить:
dw_1.Update()

// Все отлично. Все сохраняется. Теперь вносим изменение в имя. Например, пишем 111333 и опять жмем на сохранить. Получаем ошибку.
...
Когда вставили пустую строку (т.е. когда id - autonumber и нет больше обязательных полей типа NOT NULL) нужно изменить статус этой строки. А потом через select получить max(id) и уже для этого значения внести изменения в строку и потом их сохранить.

P.S. судя из вышесказанного, autonumber - операция, которая только мешает и вносит проблемы ;)
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149015
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получить номер можно и до и после Update(). Но что толку-то?
Еще раз объясню проблему.
Вставили строку, написали имя (в id ничего не пишем). Сделали Update().
Все прошло хорошо. Строка сохранилась, но в DW в строке осталось пустое место в id.
Из базы данных селектом получаем этот номер. Делаем SetItem. Теперь номер этот виден в DW(можно добавить AcceptText()).
Делаем Update() - получаем ошибку "id is NULL".
Такое впечатление, что база данных просто игнорирует все, что связано с автономером.

Если после первого Update сделать dw_1.Retrieve(), то проблема решается.
Но делать Retrieve на все строки нельзя, а ReselectRow опять таки выдает ошибку "NULL".
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149097
maniac85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, победить можно просто убрав с поля счетчик
руками делать номер: SELECT max(id) INTO :li_maxid FROM table;
прибавлять единицу, ну и т.д.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149126
maniac85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RiskaИз базы данных селектом получаем этот номер. Делаем SetItem. Теперь номер этот виден в DW(можно добавить AcceptText()).
Делаем Update() - получаем ошибку "id is NULL".
Такое впечатление, что база данных просто игнорирует все, что связано с автономером.я правда не проверял, но думаю что оно сравнивает с original buffer'ом а в DW виден все таки primary buffer (даже и с accepttext'ом)
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149131
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maniac85да, победить можно просто убрав с поля счетчик
руками делать номер: SELECT max(id) INTO :li_maxid FROM table;
прибавлять единицу, ну и т.д.
Это и ежу понятно :)
Как со счетчиком устаканить?
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149136
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maniac85RiskaИз базы данных селектом получаем этот номер. Делаем SetItem. Теперь номер этот виден в DW(можно добавить AcceptText()).
Делаем Update() - получаем ошибку "id is NULL".
Такое впечатление, что база данных просто игнорирует все, что связано с автономером.я правда не проверял, но думаю что оно сравнивает с original buffer'ом а в DW виден все таки primary buffer (даже и с accepttext'ом)
А это идея! Сейчас проверю.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149163
maniac85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Riskamaniac85пропущено...
я правда не проверял, но думаю что оно сравнивает с original buffer'ом а в DW виден все таки primary buffer (даже и с accepttext'ом)
А это идея! Сейчас проверю.все равно в original buffer значение нельзя поменять
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149178
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мы победили!!! Спасибо!
Нужно было сделать
Код: sql
1.
dw_1.Object.id.Original[current_row] = max_number_from_db
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149188
maniac85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чо, можно оказывается?
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149258
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВсе прошло хорошо. Строка сохранилась, но в DW в строке осталось пустое место в id.
Из базы данных селектом получаем этот номер. Делаем SetItem. Теперь номер этот виден в DW(можно добавить AcceptText()).
Как я писал выше, обязательно после SetItem сделайте resetupdate() - в этом секрет.
Этот метод скажет ДВ что он не обновлялся, потому что так и есть.
Попробую обьяснить детальнее:
Когда Вы вставили строку в ДВ, и затем обновили ее поля у нее статус= NewModified и при Update будет вызван INSERT.
Для инсерта значение в поле ID по барабану и поэтому все Ок.
По идее, после отработки INSERT ДВ предполагает, что заполнилось поле Identitycolumn (оно же и KeyColumn), но этого не произошло и оно осталось NULL.
При этом статус строки в ДВ = NotModified .
Вы меняете значение поля ID на номер. Статус строки = DataModified .
Update будет вызывать UPDATE ... WHERE id = NULL, потому что ДВ подставляет предыдущее значение и это логично. Вы бы делали также, если бы писали руками UPDATE.
В этом месте нам надо его (ДВ) "обмануть" - это и сделает метод resetupdate().
После ResetUpdate, перед следующим Update(), ДВ будет думать, что ничего не происходило, т.е. поля не менялись.
Последовательность действий такая:
- insertrow(0)
- setitem(row, 'name','bla bla bla')
- update()
- получаем значение ID
- setitem(row, 'id', <значение>)
- resetupdate()
- ...
Теперь измените какое либо поле и выполните Update() снова.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149672
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как я писал выше, обязательно после SetItem сделайте resetupdate() - в этом секрет.
После ResetUpdate, перед следующим Update(), ДВ будет думать, что ничего не происходило, т.е. поля не менялись.

Это ничего не дает. В строке id как было, так и осталось NULL.
После изменения "name" в UPDATE опять будет Error: "... id is NULL".
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38149811
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понял ...
Вы выполнили:
dw_1.SetItem( row, 'ID', max_number_from_db) // этот номер в поле ID сохранился (появился)?
dw_1.resetupdate() // Этот номер max_number_from_db из поля ID исчез? O_o

Заметьте, dw_1.update() между этими вызовами нет - и это очень важно.

В целом, строкой: dw_1.Object.id.Original[current_row] = max_number_from_db Вы сделали тоже самое, что я делал методами DW.
Как говорится - "Те же яйца, только в профиль ..." :)
Просто, иногда, DotNotation не подходит и приходится использовать стандартные методы.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38150115
Фотография Riska
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ResetUpdate() просто обнуляет флаги. Никакого отношения к id эта функция не имеет.
Т.е. естественно, что номер остается. Но проблема в том, что, как высказался предыдущий оратор,
Код: sql
1.
я правда не проверял, но думаю что оно сравнивает с original bufferом а в DW виден все таки primary buffer (даже и с accepttextом)


А в оригинале был NULL (когда мы вставили строку). После dw_1.Update() база автоматом добавила номер, а в DW этот номер не попал. И ни какие игры с флагами этот номер в оригинальный буфер не принесут.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38150169
PaulJB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну ладно ... думаю, дальнейший спор не уместен - главное, что Вы решили свою проблему :)
Может это разные методв работы ДВ с разными БД, но у меня такой метод прокатывал на ASA.
...
Рейтинг: 0 / 0
Row changed between retrieve and update
    #38151866
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RiskaКак со счетчиком устаканить? Пробовали?
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Row changed between retrieve and update
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]