ЛТ: Удаление синомимов

Приемы и подходы, обмен опытом

Модераторы: Screw, larin

Ответить
Hershy
рег.отделение
Сообщения: 64
Зарегистрирован: Вт, 03/03/2009 07:53
Имя Фамилия: Николай Воронцов
Откуда: Галактика-Урал
Контактная информация:

ЛТ: Удаление синомимов

Сообщение Hershy »

Подскажет кто-нибудь почему

Код: Выделить всё

Interface i015qwerty '' Cyan;

    var deleteresult : LONGINT;

    CREATE VIEW AS
    SELECT * FROM
                 DOGOVOR
                 ,SYNONYM DOGOVOR     DUBL
                 ,SYNONYM KATORG      K1
                 ,SYNONYM KATORG      K2
                 ,SYNONYM KATORGDESCR KD1
                 ,SYNONYM KATORGDESCR KD2
                 ,SYNONYM KATORGDESCR KDNAME1
                 ,SYNONYM KATORGDESCR KDNAME2
                 ,SYNONYM ATTRDOG     A1
                 ,SYNONYM ATTRDOG     A2
                 ,ATTRVAL
                 ,ATTRNAM
                 ,ATTRDOG
    WHERE ((
        'J_C' == DOGOVOR.DESCR
        AND        DOGOVOR.CMYORG   /== K1.NREC
        AND        DOGOVOR.CORG     /== K2.NREC
        AND        K1.NREC          /== KD1.CREC
        AND        K2.NREC          /== KD2.CREC
        AND        KD1.CGROUP       /== KDNAME1.NREC
        AND        KD2.CGROUP       /== KDNAME2.NREC
        AND        DOGOVOR.CDOGOVOR  == DUBL.CDOGOVOR
        AND        DOGOVOR.CORG      == DUBL.CORG
        AND        DOGOVOR.DDOC      == DUBL.DDOC
        AND        DOGOVOR.NODOC     == DUBL.NODOC
        AND        DOGOVOR.DBEG      == DUBL.DBEG (noindex)
        AND        DOGOVOR.DEND      == DUBL.DEND (noindex)
        AND        DOGOVOR.SUMMA     == DUBL.SUMMA (noindex)
        AND        DOGOVOR.CMYORG    == DUBL.CMYORG (noindex)
        AND        DOGOVOR.CVIDDOG   == DUBL.CVIDDOG (noindex)
        AND        DOGOVOR.NODOC_EXT == DUBL.NODOC_EXT (noindex)
        AND        DOGOVOR.NREC      == A1.CDOGOVOR
        AND        DUBL.NREC          == A2.CDOGOVOR
    ))
    AND KDNAME1.NAME = 'Некоммерческое партнерство'
    AND KDNAME2.NAME = 'Некоммерческое партнерство'
    AND A1.SUBJECT1 = A2.SUBJECT1
    AND DOGOVOR.NREC <> DUBL.NREC
    AND DOGOVOR.TIDK = 401
    AND DOGOVOR.NREC = 281474976715722 // для отладки
    ;
    HandleEvent
        cmInit:{
            StartNewVisual(vtIndicatorVisual, vfThread+vfScreenBottom+vfTimer, 'Проверка', RecordsInTable(tnDOGOVOR));
            _loop DOGOVOR {
                NEXTVISUAL;
                SetVisualHeader(if(DOGOVOR.TIDK = 400, 'Договор №','Ут.соглашение №')+DOGOVOR.NODOC+' от '+DOGOVOR.DDOC);
                _loop DUBL {
                    _loop ATTRNAM WHERE ((1707 == ATTRVAL.WTABLE)) {
                        delete ATTRVAL where ((ATTRNAM.WTABLE == ATTRVAL.WTABLE
                                           AND DUBL.NREC == ATTRVAL.CREC
                                           AND ATTRNAM.NREC == ATTRVAL.CATTRNAM));
                    }
                    delete ATTRDOG where ((DUBL.NREC == ATTRDOG.CDOGOVOR));
                }
                if((deleteresult := delete DUBL)<>0){}else{}//пробовал еще delete ALL DUBL - тот же результат
                message(deleteresult) ;
            }
            STOPVISUAL('Проверка данных завершена',0);
            Message('Удаление завершено');
            closeinterface(cmOK);
        }
    End; //HandleEvent
End.
Так вот, почему delete DUBL не отрабатывает? Т.е. дубликаты не удаляются, хотя ATTRVAL и ATTRDOG сносятся как нужно.
В саппорте запускаю запрос, выводит 8 договоров, которые являются дубликатами.
Заране спасибо!
Hershy
рег.отделение
Сообщения: 64
Зарегистрирован: Вт, 03/03/2009 07:53
Имя Фамилия: Николай Воронцов
Откуда: Галактика-Урал
Контактная информация:

Сообщение Hershy »

Еще дополнение

сделал так:

Код: Выделить всё

    HandleEvent
        cmInit:{
            StartNewVisual(vtIndicatorVisual, vfThread+vfScreenBottom+vfTimer, 'Проверка', RecordsInTable(tnDOGOVOR));
            markers := InitMarker('', 8, 100, 10);

            _loop DOGOVOR {

                NEXTVISUAL;
                SetVisualHeader(if(DOGOVOR.TIDK = 400, 'Договор №','Ут.соглашение №')+DOGOVOR.NODOC+' от '+DOGOVOR.DDOC);
                _loop DUBL {
                    _loop ATTRNAM WHERE ((1707 == ATTRVAL.WTABLE)) {
                        delete ATTRVAL where ((ATTRNAM.WTABLE == ATTRVAL.WTABLE
                                           AND DUBL.NREC == ATTRVAL.CREC
                                           AND ATTRNAM.NREC == ATTRVAL.CATTRNAM));
                    }
                    delete ATTRDOG where ((DUBL.NREC == ATTRDOG.CDOGOVOR));
                    InsertMarker (markers, DUBL.NREC);
                }
            }
            message('В маркере '+GetMarkerCount(markers));
            if((deleteresult := delete DOGOVOR WHERE FoundMarker(markers, DOGOVOR.NREC))<>0){}else{}
            message(deleteresult);

            DoneMarker(markers, '');
            STOPVISUAL('Проверка данных завершена',0);
            Message('Удаление завершено');
            closeinterface(cmOK);
        }
    End; //HandleEvent
все равно delete DOGOVOR не удаляет, хотя deleteresult равно таки 0.
Hershy
рег.отделение
Сообщения: 64
Зарегистрирован: Вт, 03/03/2009 07:53
Имя Фамилия: Николай Воронцов
Откуда: Галактика-Урал
Контактная информация:

Сообщение Hershy »

Ну вот, наконец-то, в результате плясок с бубном выявили в чем проблема

Значит так, есить интерфейс

Код: Выделить всё

Interface i015qwerty '' Cyan;

    var deleteresult,markers : LONGINT;

    CREATE VIEW V1
    SELECT * FROM
                 SYNONYM dogovor     DUBL
                 ,SYNONYM KATORG      K1
                 ,SYNONYM KATORG      K2
                 ,SYNONYM KATORGDESCR KD1
                 ,SYNONYM KATORGDESCR KD2
                 ,SYNONYM KATORGDESCR KDNAME1
                 ,SYNONYM KATORGDESCR KDNAME2
                 ,SYNONYM ATTRDOG     A1
                 ,SYNONYM ATTRDOG     A2
                 ,SYNONYM dogovor     D2
    WHERE
    ((
        'J_C' /== d2.DESCR
        AND        d2.CMYORG   /== K1.NREC
        AND        d2.CORG     /== K2.NREC
        AND        K1.NREC          /== KD1.CREC
        AND        K2.NREC          /== KD2.CREC
        AND        KD1.CGROUP       /== KDNAME1.NREC
        AND        KD2.CGROUP       /== KDNAME2.NREC
        AND        d2.Cdogovor  == DUBL.Cdogovor
        AND        d2.CORG      == DUBL.CORG
        AND        d2.DDOC      == DUBL.DDOC
        AND        d2.NODOC     == DUBL.NODOC
        AND        d2.DBEG      == DUBL.DBEG (noindex)
        AND        d2.DEND      == DUBL.DEND (noindex)
        AND        d2.SUMMA     == DUBL.SUMMA (noindex)
        AND        d2.CMYORG    == DUBL.CMYORG (noindex)
        AND        d2.CVIDDOG   == DUBL.CVIDDOG (noindex)
        AND        d2.NODOC_EXT == DUBL.NODOC_EXT (noindex)
        AND        d2.NREC      == A1.Cdogovor
        AND        DUBL.NREC          == A2.Cdogovor
    ))    
    AND KDNAME1.NAME = 'Некоммерческое партнерство'
    AND KDNAME2.NAME = 'Некоммерческое партнерство'
    AND A1.SUBJECT1 = A2.SUBJECT1
    AND d2.NREC <> DUBL.NREC
    AND d2.TIDK = 401
    AND d2.NREC = 281474976715722 // для отладки
    ;
    CREATE VIEW V2
    SELECT * FROM ATTRDOG;
    HandleEvent
        cmInit:{
            markers := InitMarker('', 8, 100, 10);
            _loop d2 {
                _loop DUBL {
                    InsertMarker (markers, DUBL.NREC);
                }
            }
            message('В маркере '+GetMarkerCount(markers));
            var c : LONGINT;
            c := GetMarkerCount(markers);
            var i : LONGINT;
            for(i := 0; i < c; i++){
                var com : COMP;
                GetMarker (markers, i, com);
                message('УРАААА - Нашли  '+String(com,0,0));
                if((getfirst Dubl WHERE ((com /== Dubl.NREC))) = tsOK){
                     if((deleteresult := delete DUBL WHERE ((com /== Dubl.NREC))) = 0){
                     }else{}
                     message('deleteresult='+deleteresult);
                }else{
                    message('Не нашли D2 c номером записи '+String(com,0,0));
                }
                if((V2.getfirst ATTRDOG WHERE ((com /== ATTRDOG.Cdogovor))) = tsOK){
                     if((deleteresult := V2.delete ATTRDOG WHERE ((com /== ATTRDOG.Cdogovor))) = 0){
                     }else{}
                     message('deleteresult1='+deleteresult);
                }else{
                    message('Не нашли Cdogovor c номером записи '+String(com,0,0));
                }
            }
            DoneMarker(markers, '');
            closeinterface(cmOK);
    }
    End; //HandleEvent
End.
В данной версии все работает отлично, НО. Как только я делаю вот так

Код: Выделить всё

Interface i015qwerty '' Cyan;

    var deleteresult,markers : LONGINT;

    CREATE VIEW V1
    SELECT * FROM
                 SYNONYM dogovor     DUBL
                 ,SYNONYM KATORG      K1
                 ,SYNONYM KATORG      K2
                 ,SYNONYM KATORGDESCR KD1
                 ,SYNONYM KATORGDESCR KD2
                 ,SYNONYM KATORGDESCR KDNAME1
                 ,SYNONYM KATORGDESCR KDNAME2
                 ,SYNONYM ATTRDOG     A1
                 ,SYNONYM ATTRDOG     A2
                 ,SYNONYM dogovor     D2
    WHERE
    ((
        'J_C' /== d2.DESCR
        AND        d2.CMYORG   /== K1.NREC
        AND        d2.CORG     /== K2.NREC
        AND        K1.NREC          /== KD1.CREC
        AND        K2.NREC          /== KD2.CREC
        AND        KD1.CGROUP       /== KDNAME1.NREC
        AND        KD2.CGROUP       /== KDNAME2.NREC
        AND        d2.Cdogovor  == DUBL.Cdogovor
        AND        d2.CORG      == DUBL.CORG
        AND        d2.DDOC      == DUBL.DDOC
        AND        d2.NODOC     == DUBL.NODOC
        AND        d2.DBEG      == DUBL.DBEG (noindex)
        AND        d2.DEND      == DUBL.DEND (noindex)
        AND        d2.SUMMA     == DUBL.SUMMA (noindex)
        AND        d2.CMYORG    == DUBL.CMYORG (noindex)
        AND        d2.CVIDDOG   == DUBL.CVIDDOG (noindex)
        AND        d2.NODOC_EXT == DUBL.NODOC_EXT (noindex)
        AND        d2.NREC      == A1.Cdogovor
        AND        DUBL.NREC          == A2.Cdogovor
    ))    
    AND KDNAME1.NAME = 'Некоммерческое партнерство'
    AND KDNAME2.NAME = 'Некоммерческое партнерство'
    AND A1.SUBJECT1 = A2.SUBJECT1
    AND d2.NREC <> DUBL.NREC
    AND d2.TIDK = 401
    AND d2.NREC = 281474976715722 // для отладки
    ;
    HandleEvent
        cmInit:{
            markers := InitMarker('', 8, 100, 10);
            _loop d2 {
                _loop DUBL {
                    InsertMarker (markers, DUBL.NREC);
                    delete ATTRDOG WHERE ((DUBL.NREC /== ATTRDOG.Cdogovor));
                }
            }
            message('В маркере '+GetMarkerCount(markers));
            var c : LONGINT;
            c := GetMarkerCount(markers);
            var i : LONGINT;
            for(i := 0; i < c; i++){
                var com : COMP;
                GetMarker (markers, i, com);
                message('УРАААА - Нашли  '+String(com,0,0));
                if((getfirst Dubl WHERE ((com /== Dubl.NREC))) = tsOK){
                     if((deleteresult := delete DUBL WHERE ((com /== Dubl.NREC))) = 0){
                     }else{}
                     message('deleteresult='+deleteresult);
                }else{
                    message('Не нашли D2 c номером записи '+String(com,0,0));
                }
            }
            DoneMarker(markers, '');
            closeinterface(cmOK);
    }
    End; //HandleEvent
End.
т.е. по сути дела, я удаляю ATTRDOG до удаления договоров, используя вьюшку интерфейса для получения CDOGOVOR.
Далее удаляю договора, которые позиционируются через найденный в маркере номер записи. И на это, как мне кажется, я имею право, ведь написано в мануале:
Если вызван оператор навигации с конструкцией where, то на время своего выполнения он отменяет текущую подцепку для таблицы в которой происходит поиск /перебор записей и если найденная запись не попадает в текущую подцепку, то модификатор возвращает статус tsOk, но текущая запись становится невалидной.
Дак вот, после такого удаления ATTRDOG, договора в коде

Код: Выделить всё

                if((getfirst Dubl WHERE ((com /== Dubl.NREC))) = tsOK){
                     if((deleteresult := delete DUBL WHERE ((com /== Dubl.NREC))) = 0){
                     }else{}
                     message('deleteresult='+deleteresult);
                }else{
                    message('Не нашли D2 c номером записи '+String(com,0,0));
                }
вообще не позиционируются, т.е. таких договоров, по мнению интерфейса нет, хотя если в саппорте проверить и тоже запросом, то договор на месте.
Пробовал вот так сделать:

Код: Выделить всё

                if((getfirst Dubl WHERE ((com /== Dubl.NREC))) = tsOK){
                     delete ATTRDOG WHERE ((com /== ATTRDOG.Cdogovor));
                     if((deleteresult := delete DUBL WHERE ((com /== Dubl.NREC))) = 0){
                     }else{}
                     message('deleteresult='+deleteresult);
                }else{
                    message('Не нашли D2 c номером записи '+String(com,0,0));
                }
удаляет ATTRDOG, но после этого договора не удаляет, хотя говорит, что deleteresult = 0, а если сделать вот так

Код: Выделить всё

                if((getfirst Dubl WHERE ((com /== Dubl.NREC))) = tsOK){
                     if((deleteresult := delete DUBL WHERE ((com /== Dubl.NREC))) = 0){
                            delete ATTRDOG WHERE ((com /== ATTRDOG.Cdogovor));
                     }else{}
                     message('deleteresult='+deleteresult);
                }else{
                    message('Не нашли D2 c номером записи '+String(com,0,0));
                }
тогда удаляет договора, а ATTRDOG не удаляет

И еще заметили такую вещь, что если указать вот так

Код: Выделить всё

                if((getfirst DOGOVOR WHERE ((com /== DOGOVOR .NREC))) = tsOK){
                     if((deleteresult := delete DOGOVOR WHERE ((com /== DOGOVOR .NREC))) = 0){
                     }else{}
                     message('deleteresult='+deleteresult);
                }else{
                    message('Не нашли DOGOVOR c номером записи '+String(com,0,0));
                }
то даже с закоментированным полностью _loop d2 {} удаления не происходит, так же как и если поставить вместо DOGOVOR синоним D2, т.е. удаление почему-то проходит только с синонимом DUBL

В чем ошибка, в Атлантисе, Галактике или вообще в моем ДНК???
Аватара пользователя
Screw
топ-софт
Сообщения: 73
Зарегистрирован: Пт, 14/09/2007 22:54
Имя Фамилия: Виталий Корзюк
Откуда: ТопСофт
Контактная информация:

Сообщение Screw »

Полагаю, причина в вот этой группе ограничений:

Код: Выделить всё

    ...
    AND KDNAME1.NAME = 'Некоммерческое партнерство' 
    AND KDNAME2.NAME = 'Некоммерческое партнерство' 
    AND A1.SUBJECT1 = A2.SUBJECT1 
    AND d2.NREC <> DUBL.NREC 
    AND d2.TIDK = 401 
    AND d2.NREC = 281474976715722 // для отладки
Условия, накладываемые на логическую таблицу, труднопредсказуемы. Скажите-ка, что случится, если удалить текущую запись из A1 (непосредственно или через синоним)? Достаточно нарушения любого из перечисленных условий для того, чтобы сделать все узлы ЛТ невалидными, а их данные - недоступными. Я сильно всё упрощаю, но суть от этого не меняется: condition-ы, наложенные на ЛТ в целом - зло. Постарайтесь обойтись узловыми условиями.

Кстати, с какой целью Вы используете жесткие подцепки при позиционировании и удалении? Я имею в виду такие примеры кода:

Код: Выделить всё

getfirst DOGOVOR WHERE ((com /== DOGOVOR .NREC))
...
delete ATTRDOG WHERE ((com /== ATTRDOG.Cdogovor))
...
Hershy
рег.отделение
Сообщения: 64
Зарегистрирован: Вт, 03/03/2009 07:53
Имя Фамилия: Николай Воронцов
Откуда: Галактика-Урал
Контактная информация:

Сообщение Hershy »

Виталий, спасибо за ответ, хоть кто-то обратил внимание :)

Это все понятно, про сломанную ЛТ после удаления А1, даже и претендовать на это не собираюсь, однако, меня интересует не это, а вот что:

После того как мы сделали все, что необходимо с ЛТ, т.е. она нам больше не нужна, мы начинаем удалять записи, которые выбрали с использованием ЛТ и положили в маркер. Получается в этом случае:

Код: Выделить всё

delete ATTRDOG WHERE ((com /== ATTRDOG.Cdogovor)) 
ЛТ вообще никак не должна влиять на удаление, ведь указана WHERE и тут без разницы валидна ЛТ интерфейса или нет, позиционирование-то заново происходит при удалении (или я ошибаюсь). И если я ошибаюсь, тогда где можно про это прочесть?

А жесткая сцепка появилась в результате плясок с бубном, всякое делал с кодом, "авось" так сказать

Еще раз спасибо за ответ
Ответить