Ошибка при редактировании Dataset

Добрый день! Следующая конструкция успешно работала

ContractDataset.Edit();
ContractDataset.ValAsFloat('Amount') = Amount;
ContractDataset.ValAsFloat('BasicAmount') = BasicAmount;
ContractDataset.Post();

т.е. пытаюсь отредактировать запись датасета договора с уже существующим заголовком (заголовок сформирован при импорте из Excel значением по умолчанию), выдает следующие

[09.05.21 10.35.06.698] (E) Ошибка выполнения метода 'SelfOnDatasetAfterPost'. Ошибка сохранения записи. Оригинальное сообщение об ошибке: validation error for column Title, value "*** null ***"
The insert failed because a column definition includes validation constraints.
Error Code: 27
INSERT INTO "tbl_Contract" ("ID", "ContractTypeID", "ContractStatusID", "OwnerID", "StartDate", "DueDate", "BillingFrequencyID", "Amount", "BasicAmount", "ModifiedOn", "ModifiedByID", "AllUpgr", "DocWeek1", "DocWeek2", "DocWeek3", "DocWeek4", "DocWeek5", "CreatedOn", "CreatedByID")
VALUES (:ID, :ContractTypeID, :ContractStatusID, :OwnerID, :StartDate, :DueDate, :BillingFrequencyID, :Amount, :BasicAmount, CURRENT_TIMESTAMP, '{94EDBC92-596F-4957-BA05-96A682F739E5}', :AllUpgr, :DocWeek1, :DocWeek2, :DocWeek3, :DocWeek4, :DocWeek5, CURRENT_TIMESTAMP, '{94EDBC92-596F-4957-BA05-96A682F739E5}') «Call Stack»

ошибок в скрипте нет, т.к. конструкция

ContractDataset.Edit();
ContractDataset.ValAsFloat('Amount') = Amount;
ContractDataset.ValAsFloat('BasicAmount') = BasicAmount;
ContractDataset('Title') = 'Договор';
ContractDataset.Post();

успешно выполняется.

Насколько я правильно понимаю проблема в кодировке заголовка?

TS X25 3/3/0/42 Firebird

Нравится

34 комментария

Добрый день, Павел!

На сколько я могу судить из текста ошибки, она говорит о том, что в БД поле Title NOT NULL, но идет попытка вставить в это поле значение NULL. Нужно или NOT NULL убрать в дизайнере таблицы, или данные откорректировать.

А почему вставка идет, если запись редактируется? И меняются два поля, а вставка идет на все? Вы часом не из администратора этот скрипт выполняете?

Вставка наверное идет потому что датасет пустой.

Да, действительно, поле Title уже заполнено, в скрипте я лишь пытаюсь заполнить поля Amount и BasicAmount, поле Title я вообще не трогаю, оно должно остаться таким как есть

Датасет не пустой, сам так сначало думал, но повторюсь, конструкция

ContractDataset.Edit();
ContractDataset.ValAsFloat('Amount') = Amount;
ContractDataset.ValAsFloat('BasicAmount') = BasicAmount;
ContractDataset('Title') = 'Договор';
ContractDataset.Post();

нормально выполняется на нужной записи

А какой запрос идет если использовать такую конструкцию? Посмотрите если можете профайлером (для MSSQL).

Не получится, у меня firebird. А вообще и правда интересно почему идет insert, если я редактирую запись?

если я не ошибаюсь, то в IBExpert пункт меню Tools, подпункт SQL Monitor может вам помочь

Инсерт идет если датасет пустой. Попробуйте у него вызвать PageRecordsCount() перед вызовом Edit(). Если вернет не 0, то... этого не может быть потому что этого не может быть никогда :)
Посмотрите также состояние датасета передвызовом Edit()

Павел, Underscore a.k.a. задал верный вопрос:

"Underscore a.k.a. _" написал:Вы часом не из администратора этот скрипт выполняете?

Вы часом не из администратора этот скрипт выполняете????!!!

Нет конечно, данный скрипт, а именно функция (я предоставил ее часть) выполняется из Terrasoft, а именно при удалении или добавлении на деталь продукты в договоре.

а событие OnAfterPost - пустое?
Возможно Post вашего Edit'a вызывает какой-то Append?

И что все-таки возвращают PageRecordsCount(), IsActive и State перед вызовом Edit()?

попробуйте заменить строку на

ContractDataset.ValAsStr('Title') = "Договор";

знаю, что отличий почти нет, но попробовать стоит.

Уточние, пожалуйста, в чем отличие ненужно от нужной записи, о которой вы упомянули в посте:

"нормально выполняется на нужной записи"

---Underscore a.k.a.

Перед вызовом edit()

IsActive = False
PageRecordsCount() = 0

"Карло Сергей" написал:Павел, Underscore a.k.a. задал верный вопрос:
"Underscore a.k.a. _" написал:Вы часом не из администратора этот скрипт выполняете?

Коллеги, у меня вчера была похожая проблема... Запускал из администратора (в чем разница, где запускать скрипт?)

Нужно было в CashFlow проставить одинаковое назначение, прописал скрипт:

function Main() {
 
var ds = Services.GetNewItemByUSI('ds_Cashflow');
ds.Open(); 
var R = ds.RecordsCount;
Log.Write(2, R);
while (!ds.IsEOF) {
    ds.Edit();
    ds('Subject') = 'Продажа Товара';
    Log.Write(2, ds('ID'));
    ds.Post();
    ds.GotoNext();
}
ds.Close();
}

Выдало сообщение

Что еще более интересно, количество записей в датасете: 1

Проверил: все фильтры отключены, в MS SMS

select count(ID) from tbl_Cashflow
-----------
9609
 
select count(ID) from tbl_Cashflow where AutocalcAmount is null
-----------
0

Обновил в SQL, но все же интересно - почему в датасете только 1 запись?
TS CRM X25 3.3.0.51

--
www.it-sfera.com.ua
Terrasoft Solution Partner

Всем спасибо! Проблема решена.

Вместо

ContractDataset.Edit();
ContractDataset.ValAsFloat('Amount') = Amount;
ContractDataset.ValAsFloat('BasicAmount') = BasicAmount;
ContractDataset.Post();

Написал:

ContractDataset.Open();
ContractDataset.Edit();
ContractDataset.ValAsFloat('Amount') = Amount;
ContractDataset.ValAsFloat('BasicAmount') = BasicAmount;
ContractDataset.Post();
ContractDataset.Close();

Все заработало.

Но вообще я думал, что перед Dataset.Edit() не нужно писать
Dataset.Open()

"Павел Крышкин" написал:IsActive = False
PageRecordsCount() = 0

Ну вот, я же говорил, что у Вас датасет пустой.
Edit() начинает редактирование текущей записи. Если не было открытия датасета, то записей в нем нет.

"Виталий Ковалишин aka samael" написал:Коллеги, у меня вчера была похожая проблема... Запускал из администратора (в чем разница, где запускать скрипт?)

В администраторе почему-то собираются неправильные запросы. Возможно это сделано для сборки запроса в предпросмотре текста запроса в дизайнере запросов. Но если это так, то автору идеи нужно тоже какую-нибудь каку сделать :)

"Underscore a.k.a. _" написал:В администраторе почему-то собираются неправильные запросы. Возможно это сделано для сборки запроса в предпросмотре текста запроса в дизайнере запросов. Но если это так, то автору идеи нужно тоже какую-нибудь каку сделать :)

С этим понятно, а почему в датасете ода запись?

--
www.it-sfera.com.ua
Terrasoft Solution Partner

RecordsCount шлет запрос запрос в базу. Гляньте что за запрос идет если скрипт выполнять из администратора.

"Underscore a.k.a. _" написал:RecordsCount шлет запрос запрос в базу. Гляньте что за запрос идет если скрипт выполнять из администратора.

Спасибо за совет!
Кто-то из программеров забыл убрать:

SELECT TOP 1
[tbl_Cashflow].[ID] AS [ID],
...

В фильтры смотрели, а в TOP - все были уверены, что все гуд!
Исправили :)

--
www.it-sfera.com.ua
Terrasoft Solution Partner

Остается баг с update неясен...

--
www.it-sfera.com.ua
Terrasoft Solution Partner

"Виталий Ковалишин aka samael" написал:Остается баг с update неясен...

Похоже это не баг а фича:)

Благо, что SQL пока не подводит:

UPDATE tbl_Cashflow
SET Subject = 'Продажа Товара'

--
www.it-sfera.com.ua
Terrasoft Solution Partner

Эсли датасет закрытый или пустой -- то на Edit отрабатывает Append.

"Александр Кравчук" написал:Эсли датасет закрытый или пустой -- то на Edit отрабатывает Append.

Но в датасете 1 строка была! + я ж его открывал

...
var ds = Services.GetNewItemByUSI('ds_Cashflow');
ds.Open(); 
...

--
www.it-sfera.com.ua
Terrasoft Solution Partner

"Виталий Ковалишин aka samael" написал:Остается баг с update неясен...

Ну ведь написали:
"Underscore a.k.a. _" написал:В администраторе почему-то собираются неправильные запросы. Возможно это сделано для сборки запроса в предпросмотре текста запроса в дизайнере запросов.

Это именно так. Все связано с тем что если в адиминистраторе мы работаем через Main - то у всех обьектов Connector.IsDesigning = true - в таком случае все объекты ведут себя по другому, в частности датасет всегда возвращает все поля.
В этом случае нужно делать окно, запустать это окно через tscrm.exe /wnd=vashe_okno и на кнопочку в нем выполнять Ваше действие. :) Я именно так всегда и делаю.

Спасибо Александр, за детальное объяснение!

--
www.it-sfera.com.ua
Terrasoft Solution Partner

"Александр Кравчук" написал:В этом случае нужно делать окно

Ну или получается что можно с IsDesigning поиграться. У всех сервисов это свойство доступно и на запись.

"Underscore a.k.a. _" написал:Ну или получается что можно с IsDesigning поиграться. У всех сервисов это свойство доступно и на запись.


  Не выйдет, я уже пробовал.  

Точно , изменение этого свойства у датасета и инсертквери никчему не привело. Но у окон оно вроде работает. Ка-то этот IsDesigning через гланды сделан.

Тот IsDesigning который влияет на отображение всех колонок в Dataset'е не вынесен наружу.

А на что влияет IsDesigning , который вынесен? И почему бы его не сделать тем, который влияет?

Так исторически сложилось. Пока до этого руки не дошли. 

Показать все комментарии