Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > FIBPlus и вставка данных в табл связи справочников


Автор: 4EVERCooL 6.7.2009, 03:01
Продублирую свой пост на sql.ru, может вы охотнее поможете?  smile .

Итак, база данных состоит к примеру из трех таблиц - справочника людей, справочника сертификатов этих людей и таблицы связи "многие ко многим" человек/сертификат.
Представьте себе форму, на ней два грида и два датасета. Один показывает список людей, второй связан с первым по мастер-деталь и показывает список сертификатов у человека, выбранного в данный момент в первом датасете. Первый датасет прекрасно редактируется из делфей, тут проблем нет. Во втором оператор выбора данных такой:
Код


SELECT
d.reg_id,
a.CERT_ID,
   a.CERT_TITLE,
b.ENT_ID,
    b.ENT_TITLE,
    d.ISSUEDON,
    d.VALIDUNTIL,
    d.CERTSCAN,
    d.qualif,
d.employees_emp_id,
d.certificates_cert_id,
d.issuedby_ent_id  
FROM
    MAINTABLE d
left join certificates a on d.certificates_cert_id=a.cert_id
left join issuedby b on d.issuedby_ent_id=b.ent_id 
 
where employees_emp_id=:mas_emp_id
, то есть чтобы данные в гриде нормально выглядели делаем джойн из нескольких таблиц.

А оператор вставки вот такой:
Код

INSERT INTO MAINTABLE(
    REG_ID,
    ISSUEDON,
    VALIDUNTIL,
    CERTSCAN,
    QUALIF,
    EMPLOYEES_EMP_ID,
    CERTIFICATES_CERT_ID,
    ISSUEDBY_ENT_ID
)
VALUES(
    :REG_ID,
    :ISSUEDON,
    :VALIDUNTIL,
    :CERTSCAN,
    :QUALIF,
    :MAS_EMPLOYEES_EMP_ID,
    :MAS_CERTIFICATES_CERT_ID,
    :ISSUEDBY_ENT_ID
)

Компонент доступа как вы догадались - ФИБПлюс. И вот тут затык. Ввожу в новой форме данные сертификата выбранного человека:
procedure TFADDCert.bsSkinButton1Click(Sender: TObject);
Код

begin
Form1.DSCert.Insert;
Form1.DSCert.FieldByName('CERT_TITLE').AsString:=FAddCert.ECerttitle.Text;
Form1.DSCert.FieldByName('ISSUEDON').AsDateTime:=Faddcert.bsSkinDateEdit1.Date;
Form1.DSCert.FieldByName('VALIDUNTIL').AsDateTime:=Faddcert.bsSkinDateEdit2.Date;
Form1.DSCert.FieldByName('QUALIF').asstring:=Faddcert.bsSkinEdit1.Text;
Form1.DSCert.Post;
Form1.DSCert.FullRefresh;

end;


И эта сволочь ругается на то, что не может произвести вставку, поскольку на поле EMPLOYEES_EMP_ID наложено ограничение not null . Так вот мой вопрос. Насколько я понял, добавление суффикса MAS_ к имени поля означает, что ID человека из справочника, выбранного в данный момент в мастер-датасете, будет добавляться АВТОМАТОМ в таблицу связей (поле EMPLOYEES_EMP_ID). Но этого не происходит... Подскажите пожалуйста, что я делаю не так. Заранее сэнкс.  smile 

Автор: Romikgy 6.7.2009, 09:46
имхо мало инфы для корректной помощи ,
хоть бы показал как создавались таблицы и какие поля есть в них
Цитата(4EVERCooL @  6.7.2009,  02:01 Найти цитируемый пост)
добавление суффикса MAS_ к имени поля означает

к чему это вообще не понятно ((

Автор: former 6.7.2009, 12:44
Цитата(4EVERCooL @  6.7.2009,  03:01 Найти цитируемый пост)
И эта сволочь ругается

Необходимо у компонентов DataSet настроить AutoUpdate Options (см. офф. документацию стр. 106).

Цитата(Romikgy @  6.7.2009,  09:46 Найти цитируемый пост)
к чему это вообще не понятно (( 

Romikgy, прочти в офф. руководстве стр. 39.

Автор: Romikgy 6.7.2009, 14:14
former
Цитата(former @  6.7.2009,  11:44 Найти цитируемый пост)
прочти в офф. руководстве стр. 39. 

к чему офф руководство ?

Автор: Akella 6.7.2009, 14:49
Цитата(4EVERCooL @  6.7.2009,  03:01 Найти цитируемый пост)
, то есть чтобы данные в гриде нормально выглядели делаем джойн из нескольких таблиц.

Может сделать лучше без соединений, но с lookup-полями smile ?

Автор: former 6.7.2009, 15:50
Цитата(Romikgy @  6.7.2009,  14:14 Найти цитируемый пост)
к чему офф руководство ? 

к FIBPlus

Автор: 4EVERCooL 6.7.2009, 16:42
Цитата(Akella @ 6.7.2009,  14:49)
Цитата(4EVERCooL @  6.7.2009,  03:01 Найти цитируемый пост)
, то есть чтобы данные в гриде нормально выглядели делаем джойн из нескольких таблиц.

Может сделать лучше без соединений, но с lookup-полями smile ?


Думаю, что не лучше. Официально ведь рекомендуетсяв Firebird использовать именно соединения smile. А вот про autoupdate options почитаем. Я так думаю в свойстве AutoParamstofield собака порылась  smile . Сейчас все работает через хранимую процедуру которой я перегонял данные из экселевского файла - она как нельзя лучше подошла к этому делу, но просто хотел до конца разобраться с возможностями FIBPlus.

Автор: Akella 6.7.2009, 17:18
Цитата(4EVERCooL @  6.7.2009,  16:42 Найти цитируемый пост)
Думаю, что не лучше. Официально ведь рекомендуетсяв Firebird использовать именно соединения

Думаю, что ничего у тебя не выйдет. Ну или придётся попотеть.

Автор: 4EVERCooL 6.7.2009, 17:33
Цитата(Akella @ 6.7.2009,  17:18)
Цитата(4EVERCooL @  6.7.2009,  16:42 Найти цитируемый пост)
Думаю, что не лучше. Официально ведь рекомендуетсяв Firebird использовать именно соединения

Думаю, что ничего у тебя не выйдет. Ну или придётся попотеть.

А почему?  smile . Я кстати в FB даже и не знаю как делать лукап  smile . Ну нету там такого типа поля, как в том же аксессе.

Автор: Romikgy 6.7.2009, 20:08
Цитата(former @  6.7.2009,  11:44 Найти цитируемый пост)
прочти в офф. руководстве стр. 39. 

прочитал 
Код

1) Прописываем  у  MDS  в  SelectSQL  запрос 
select id, name  from clients
2) Прописываем  у  DDS  в  SelectSQL  запрос 
select * from orders where client_id = :mas_id.
3) У детального датасета DDS  присваиваем в свойство DataSource ссылку на  MasterSrc.

имхо возможно что из за того проблемка что в руководстве запрос простой , а у автора
Цитата(4EVERCooL @  6.7.2009,  02:01 Найти цитируемый пост)
SELECT
d.reg_id,
a.CERT_ID,
   a.CERT_TITLE,
b.ENT_ID,
    b.ENT_TITLE,
    d.ISSUEDON,
    d.VALIDUNTIL,
    d.CERTSCAN,
    d.qualif,
d.employees_emp_id,
d.certificates_cert_id,
d.issuedby_ent_id  
FROM
    MAINTABLE d
left join certificates a on d.certificates_cert_id=a.cert_id
left join issuedby b on d.issuedby_ent_id=b.ent_id 
 
where employees_emp_id=:mas_emp_id

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

Автор: Bose 6.7.2009, 22:52
AutoUpdateOptions тут не причём.

1й вариант - добавить второму(detail) датасету обработчик события OnBeforePost с кодом:
Код

  if DSCert.FieldByName('MAS_EMPLOYEES_EMP_ID').IsNull then
    DSCert.FieldByName('MAS_EMPLOYEES_EMP_ID').Value := ИмяПервогоДатасета.FieldByName('mas_emp_id').Value;


2й вариант - добавить в код вставки записи строку:
Код

begin
Form1.DSCert.Insert;
Form1.DSCert.FieldByName('CERT_TITLE').AsString:=FAddCert.ECerttitle.Text;
Form1.DSCert.FieldByName('ISSUEDON').AsDateTime:=Faddcert.bsSkinDateEdit1.Date;
Form1.DSCert.FieldByName('VALIDUNTIL').AsDateTime:=Faddcert.bsSkinDateEdit2.Date;
Form1.DSCert.FieldByName('QUALIF').asstring:=Faddcert.bsSkinEdit1.Text;
  if Form1.DSCert.FieldByName('MAS_EMPLOYEES_EMP_ID').IsNull then
    Form1.DSCert.FieldByName('MAS_EMPLOYEES_EMP_ID').Value := ИмяПервогоДатасета.FieldByName('mas_emp_id').Value;
Form1.DSCert.Post;
Form1.DSCert.FullRefresh;
end;


3-й вариант. Будет работать при условии, что master-detail сделано через свойство DataSource+MasterField(или как они там называются). Изменить SQL для вставки на следующий.:
Код

INSERT INTO MAINTABLE(
    REG_ID,
    ISSUEDON,
    VALIDUNTIL,
    CERTSCAN,
    QUALIF,
    EMPLOYEES_EMP_ID,
    CERTIFICATES_CERT_ID,
    ISSUEDBY_ENT_ID
)
VALUES(
    :REG_ID,
    :ISSUEDON,
    :VALIDUNTIL,
    :CERTSCAN,
    :QUALIF,
    :employees_emp_id,
    :MAS_CERTIFICATES_CERT_ID,
    :ISSUEDBY_ENT_ID
)


Автор: Akella 7.7.2009, 08:06
Цитата(4EVERCooL @  6.7.2009,  17:33 Найти цитируемый пост)
Я кстати в FB даже и не знаю как делать лукап

Ты, по-моему, даже не имеешь представления, что такое lookup и с чем его едят.

Автор: former 7.7.2009, 09:11
Цитата(Bose @  6.7.2009,  22:52 Найти цитируемый пост)
AutoUpdateOptions тут не причём.

Очень даже причем. Набросал небольшой пример.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)