Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Insert в detail таблицу параметр из master / 11 сообщений из 11, страница 1 из 1
19.04.2016, 16:23
    #39219362
prog_130
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
Добрый вечер! Помогите разобраться с механизмом master-detail.
Используются два IBDataSet

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
    //выборка master
    MDS_Lawsuits->SelectSQL->Clear();
    MDS_Lawsuits->SelectSQL->Add("select ID_LAWSUIT, OWNER_NAME ...");
    MDS_Lawsuits->SelectSQL->Add("from LAWSUITS");
    
    //выборка detail
    DDS_Defendants->SelectSQL->Clear();
    DDS_Defendants->SelectSQL->Add("select ID_DEFENDANT, NAME_DEFENDANT");
    DDS_Defendants->SelectSQL->Add("from DEFENDANTS");
    DDS_Defendants->SelectSQL->Add("where ID_LAWSUITS=:ID_LAWSUIT");

    //добавление detail
    DDS_Defendants->InsertSQL->Clear();
    DDS_Defendants->InsertSQL->Add("insert into DEFENDANTS (NAME_DEFENDANT, ID_LAWSUITS)");
    DDS_Defendants->InsertSQL->Add("values (:NAME_DEFENDANT, :ID_LAWSUIT)");



Выборка производится, так же производится апдейт записи таблицы - detail, вставка, но при вставке в поле ID_LAWSUITS пишется 0 (Для тестирования убрал внешний ключ по полю master-таблицы ID_LAWSUIT). Если перед ApplyUpdates() вывести параметр DDS_Defendants->ParamByName(:ID_LAWSUIT) то значение в нем корректное, что я делаю не так (кроме использования ibdataset для вставки)
...
Рейтинг: 0 / 0
19.04.2016, 16:51
    #39219404
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
Судя по тексту - это в форум по Delphi (и BC++Builder), а не по фаерберду.
...
Рейтинг: 0 / 0
19.04.2016, 16:56
    #39219411
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
prog_130что я делаю не так (кроме использования ibdataset для вставки)
Названия полей выборки и параметров вставки должны совпадать.
...
Рейтинг: 0 / 0
19.04.2016, 17:02
    #39219420
prog_130
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
wadmanНазвания полей выборки и параметров вставки должны совпадать.
Т.е. при вставке я не могу использовать параметр master-таблицы как например в select-запросе?
...
Рейтинг: 0 / 0
19.04.2016, 17:06
    #39219428
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
prog_130wadmanНазвания полей выборки и параметров вставки должны совпадать.
Т.е. при вставке я не могу использовать параметр master-таблицы как например в select-запросе?
Запросы нормальные, видимо я уже шары залил...

Ошибка где-то в другом месте... DataSource у детали назначен?
...
Рейтинг: 0 / 0
19.04.2016, 17:08
    #39219429
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
wadman,

что релиз тройки уже празднуешь?
...
Рейтинг: 0 / 0
19.04.2016, 17:10
    #39219432
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
Симонов Денисчто релиз тройки уже празднуешь?
Официально у коллеги др, а неофициально - да, начал. :)
...
Рейтинг: 0 / 0
19.04.2016, 17:15
    #39219438
prog_130
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
wadman,

Да, все корректно отображается в гридах, проблема со вставкой и именно параметра мастера
...
Рейтинг: 0 / 0
19.04.2016, 17:19
    #39219442
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
prog_130Да, все корректно отображается в гридах, проблема со вставкой и именно параметра мастера
По тому коду, который ты показал, диагноз не поставить.

Просто порекомендую IBQuery + IBUpdateSQLW (а тут упс, ссылка в гугле мертвая на ibase)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
// Copyright (c), 2003. Fanis
// inrus51@poikc.bashnet.ru

// alternate IBUpdateSQL working in sepatate transaction
// useful to make Read and Write operations in different
// transactions, avoiding to re-open IBQuery after data changes.

unit IBUpdateSQLW;

interface

uses SysUtils, Variants, Classes, DB, IB, IBCustomDataSet, IBQuery,IBUpdateSQL, IBDatabase;
type

    TIBUpdateSQLW = class(TIBUpdateSQL)
    private
        FAutoCommit:boolean;
        FUpdateTransaction:TIBTransaction;
        FQueriesW: array[TUpdateKind] of TIBQuery;
        procedure SetUpdateTransaction(Value:TIBTransaction);
    protected
        function  GetQueryW(UpdateKind: TUpdateKind): TIBQuery;
        procedure SQLChangedW(Sender: TObject);
        procedure SetQueryTransaction(UpdateKind: TUpdateKind);
        procedure Notification( AComponent: TComponent; Operation: TOperation); override;
    public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        procedure Apply(UpdateKind: TUpdateKind); override;
        procedure ExecSQLW(UpdateKind: TUpdateKind);
        procedure SetParamsW(UpdateKind: TUpdateKind);
        property QueryW[UpdateKind: TUpdateKind]: TIBQuery read GetQueryW;
    published
        property AutoCommit:boolean read FAutoCommit write FAutoCommit;
        property UpdateTransaction:TIBTransaction read fUpdateTransaction write SetUpdateTransaction;
    end;

procedure Register;

implementation

{ TIBUpdateSQLW }
procedure Register;
begin
    RegisterComponents('Interbase',[TIBUpdateSQLW]);
end;

constructor TIBUpdateSQLW.Create(AOwner: TComponent);
var UpdateKind: TUpdateKind;
begin
    inherited Create(AOwner);
    fAutoCommit:=true;
    for UpdateKind := Low(TUpdateKind) to High(TUpdateKind) do begin
        TStringList(SQL[UpdateKind]).OnChange := SQLChangedW;
    end;
end;

destructor TIBUpdateSQLW.Destroy;
var UpdateKind: TUpdateKind;
begin
    for UpdateKind := Low(TUpdateKind) to High(TUpdateKind) do
        if Assigned(FQueriesW[UpdateKind]) then begin
            FQueriesW[UpdateKind].Free;
            FQueriesW[UpdateKind] := nil;
        end;
    inherited Destroy;
end;


function TIBUpdateSQLW.GetQueryW(UpdateKind: TUpdateKind): TIBQuery;
begin
    if not Assigned(FQueriesW[UpdateKind]) then begin
        FQueriesW[UpdateKind] := TIBQuery.Create(Self);
        FQueriesW[UpdateKind].SQL.Assign(SQL[UpdateKind]);
        SetQueryTransaction(UpdateKind);
    end;
    Result := FQueriesW[UpdateKind];
end;

procedure TIBUpdateSQLW.SQLChangedW(Sender: TObject);
var UpdateKind: TUpdateKind;
begin
    for UpdateKind := Low(TUpdateKind) to High(TUpdateKind) do
        if Sender = SQL[UpdateKind] then begin
            if Assigned(FQueriesW[UpdateKind]) then begin
                FQueriesW[UpdateKind].Params.Clear;
                FQueriesW[UpdateKind].SQL.Assign(SQL[UpdateKind]);
            end;
        Break;
    end;
end;

procedure TIBUpdateSQLW.SetParamsW(UpdateKind: TUpdateKind);
var I: Integer;
    Old: Boolean;
    Param: TParam;
    PName: string;
    Field: TField;
    Value: Variant;
begin
    if not Assigned(DataSet) then Exit;
    with QueryW[UpdateKind] do begin
        for I := 0 to Params.Count - 1 do begin
            Param := Params[I];
            PName := Param.Name;
            Old := CompareText(Copy(PName, 1, 4), 'OLD_') = 0; {do not localize}
            if Old then System.Delete(PName, 1, 4);
            Field := DataSet.FindField(PName);
            if not Assigned(Field) then Continue;
            if Old then
                Param.AssignFieldValue(Field, Field.OldValue)
            else begin
                Value := Field.NewValue;
                if VarIsEmpty(Value) then Value := Field.OldValue;
                Param.AssignFieldValue(Field, Value);
            end;
        end;
    end;
end;

procedure TIBUpdateSQLW.Apply(UpdateKind: TUpdateKind);
begin
    SetParamsW(UpdateKind);
    ExecSQLW(UpdateKind);
end;

procedure TIBUpdateSQLW.ExecSQLW(UpdateKind: TUpdateKind);
begin
    with QueryW[UpdateKind] do begin
        if Assigned(fUpdateTransaction) and not fUpdateTransaction.InTransaction then
            fUpdateTransaction.StartTransaction;
        try
            Prepare;
            ExecSQL;
            if RowsAffected <> 1 then IBError(ibxeUpdateFailed, [nil]);
        finally
            if Assigned(fUpdateTransaction) and FAutoCommit then
            fUpdateTransaction.Commit;
        end;
    end;
end;

procedure TIBUpdateSQLW.SetQueryTransaction(UpdateKind: TUpdateKind);
begin
    if Assigned(FQueriesW[UpdateKind]) then begin
        if Assigned(fUpdateTransaction) then begin
            FQueriesW[UpdateKind].Database := fUpdateTransaction.FindDefaultDatabase;
            FQueriesW[UpdateKind].Transaction := fUpdateTransaction;
        end else
        // inherited
        if (DataSet is TIBCustomDataSet) then begin
            FQueriesW[UpdateKind].Database := TIBCustomDataSet(DataSet).DataBase;
            FQueriesW[UpdateKind].Transaction := TIBCustomDataSet(DataSet).Transaction;
        end;
    end;
end;

procedure TIBUpdateSQLW.Notification(AComponent: TComponent; Operation: TOperation);
var UpdateKind: TUpdateKind;
begin
    inherited Notification( AComponent, Operation);
    if (Operation = opRemove) then begin
        if AComponent = FUpdateTransaction then begin
            FUpdateTransaction := nil;
            for UpdateKind := Low(TUpdateKind) to High(TUpdateKind) do
            SetQueryTransaction(UpdateKind);
        end;
    end;
end;

procedure TIBUpdateSQLW.SetUpdateTransaction(Value:TIBTransaction);
var UpdateKind: TUpdateKind;
begin
    FUpdateTransaction := Value;
    for UpdateKind := Low(TUpdateKind) to High(TUpdateKind) do
        SetQueryTransaction(UpdateKind);
end;

end.

...
Рейтинг: 0 / 0
19.04.2016, 17:38
    #39219469
prog_130
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
Понятно, и на том спасибо.
...
Рейтинг: 0 / 0
20.04.2016, 09:07
    #39219795
prog_130
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Insert в detail таблицу параметр из master
Вообщем, если кому интересно, сегодня на свежую голову подумал и решил проблему просто добавив столбец ID_LAWSUITS в detail - таблицу. А его инициализацию повесил на событие AfterInsert значением столбца master- таблицы, сам столбец скрыл. Думаю, что проблема скорее всего в методе ApplyUpdates(), который пишет кэшированные изменения.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Insert в detail таблицу параметр из master / 11 сообщений из 11, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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