Страница 1 из 1

Как использовать Order by в Vip

Добавлено: 12 окт 2004, 12:08
savov
Здравствуйте все! Может будете любезны, подскажите чего-нибудь человеку. Проблема такая. Пишу интерфейс, таблица содержит много записей, но некоторые из них имеют одинаковые значения полей (год, месяц, номер наряда, подразделение). Мне их надо сгруппировать по этим полям и отобразить уже сгруппированные. Пробую использовать Order by в логической таблице, но не получается - таблица выходит пустой, хотя в обычном SQL запрос отрабатывает правильно.
Вот текст интерфейса:

#include galnet.inc
end;
Interface ReestrVirab 'Выбор нарядов' DoAccept,EscClose,cyan;
show at (2,2,120,25);
// Таблица нарядов (только заголовки, без показа работ)
Table Struct TNarayd
( nRec : comp
,tnNarayd : String
,tMonth : Integer
,tYear : Integer
,tcPodr : comp
,tPodrName : String
,tFIO : String
,tSmena : Integer
,tNBrig : String
,tCBrig : Comp
,tcPerson : comp
)
with index
( TableNr = nRec,
TableNar = tnNarayd,
TablecPodr =tcPodr,
TablecPer = tcPerson
) ;


var nmonth, monthold,r: Integer;
var NYear, yearold, smena, smenaold: Integer;
var numnar, NamePodr,numold: String;
var nrecpodr,cpodrold: Comp;
rnarayd, rvirab: Integer;

Create view t1
As select *
From Virab, katpodr, katmc, brigad, normtmr, lschet, persons
WHERE ((
//root==virab.nrec and
virab.cmc == katmc.nrec and
virab.cpodr ==katpodr.nrec and
virab.cBrig == Brigad.nrec and
virab.cto == normtmr.nrec and
virab.cperson ==persons.nrec
)) Order by virab.year, virab.month, virab.nnarayd;
//если Order стоит, то таблица пустая получается, если убрать, то не группируются

create view t2 as select * from tnarayd;

handleevent
CmInit:
{
if getfirst virab= tsOK
{
monthold:=0;
yearold:=0;
numold:='';
cpodrOld:=0;
smenaold:=0;
_loop virab
{
if ((t1.virab.month<>monthold) or (t1.virab.year<>yearold) or (t1.virab.nnarayd<>numold) or
(t1.virab.cpodr<>cpodrold))
{
monthold:=t1.virab.month;
yearold:=t1.virab.year;
numold:=t1.virab.nnarayd;
cpodrOld:=t1.virab.cpodr;
Insert tnarayd set tnarayd.tnnarayd:=t1.virab.nnarayd, tnarayd.tmonth:=t1.virab.month, tnarayd.tsmena:=Integer(t1.virab.nsmena),
tnarayd.tyear:=t1.virab.year, tnarayd.tcpodr:=t1.virab.cpodr, tnarayd.tPodrname:=t1.katpodr.name,
tnarayd.tcbrig:=t1.virab.cbrig;
}
getnext virab;
};
};
getfirst tnarayd;
RescanPanel(#TNarayd);
};
end;


Panel P1;

screen vibgr
show at(1,20,,);

BUTTONS

cmgNew; cmgRed;
<<
<.Новый наряд.> <.Редактировать.>
>>
end;//screen


Browse BVirab show at(1,1,,19);
table TNarayd;
Fields
TNarayd.tyear 'Год':[4], Protect;
TNarayd.tmonth 'Месяц': [2], Protect;
TNarayd.tPodrname 'Подразделение': [40], Protect;
Tnarayd.tSmena 'Смена':[5], Protect;
TNarayd.tNNarayd 'Наряд' :[10], Protect;
TNarayd.tNBrig 'Бригада':[19], Protect;
TNarayd.tFIO 'Исполнитель':[40], Protect;
end;


handleevent
cmPick :
{
}
cmgNew:
{ nmonth:=0; nyear:=0; numnar:='';nrecpodr:=0; NamePodr:='';
RunInterface('GetNaraydParam',nmonth,nyear,numnar, nrecpodr, NamePodr, smena);
If (nmonth<>0) and (nyear<>0) and (numnar<>'')
{
Insert TNarayd set tnarayd.tnnarayd:=numnar, tnarayd.tmonth:=nmonth,
tnarayd.tyear:=nyear, tnarayd.tcpodr:=nrecpodr, tnarayd.tpodrname:=NamePOdr, tnarayd.tsmena:=smena;
Insert Virab set Virab.nnarayd:=numnar, Virab.month:=nmonth,
Virab.year:=nyear, Virab.cpodr:=nrecpodr, virab.nsmena:=String(smena)};

RescanPanel(#TNarayd);
}
cmDefault:
{ReReadRecord;
}
cmgRed:
{
RunInterface('Virab',tnarayd.tnnarayd,tnarayd.tmonth,tnarayd.tyear,tnarayd.tcpodr,String(tnarayd.tsmena));
RescanPanel(#TNarayd);
}
cmCheckField:
{
}
end; // HandleEvent


end;// panel

end. // interface
Почему не работает Order by?????? ???

Re: Как использовать Order by в Vip

Добавлено: 12 окт 2004, 13:50
oiko
А в таблице virab существует составной индекс типа:
virab01=year+month+nnarayd?

в скл тебе выдается предупреждение вроде "нет индекса работает на внешней выгрузке"?

Re: Как использовать Order by в Vip

Добавлено: 12 окт 2004, 15:00
savov
Нет, при переброске запсроса в SQL никаких ошибок не высвечивается, запрос отрабатывается нормально, упорядоченно. Ошибка в интерфейсе высвечивается: "отсутствует позиция в таблице 0".
Составного индекса в табл. virab нет.

Re: Как использовать Order by в Vip

Добавлено: 12 окт 2004, 15:32
savov
НЕт, индекса такого нет. Но прикопировании в SQL все работает и сортируется, ошибок нет. Ошибка в интерфейсе выскакивает "отсутствует запись в таблице 0".

Re: Как использовать Order by в Vip

Добавлено: 12 окт 2004, 15:46
oiko
а что это за таблица я ее в словаре не нашел

Re: Как использовать Order by в Vip

Добавлено: 12 окт 2004, 16:57
savov
таблица мно добавлена в словарь самостоятельно

Re: Как использовать Order by в Vip

Добавлено: 12 окт 2004, 18:13
savov
После опытов пришел к выводу, что обязательно должны быть соответствующие индексы, иначе не работает, хотя транслирует и в SQL отрабатывает без ошибок (и без индексов!!!).Добавление индексов исправляет дело.

Re: Как использовать Order by в Vip

Добавлено: 12 окт 2004, 19:11
ecasoft
Объявите составной индекс согласно нужной сортировки, а затем просто в секции FROM после таблицы укажите его имя в скобках - таблица будет отсортирована по этому индексу в интерфейсе. Никаких ORder by не надо.

Order используется обычно в интерфейсах, когда надо переключать порядок динамически по какому-то событию (нажатию кнопки).

Re: Как использовать Order by в Vip

Добавлено: 13 окт 2004, 10:43
Maverick
Как правильно замечено выше, Order by в интерфейсах используется для переключения порядка или задания явной сортировки при существующем индексе, если порядок индексирования не виден явно из условий подцепки.
В описанном случае из SQL работает данная вещь по одной простой причине - т.к. нет индекса указанного в Order By, то происходит "внешняя выгрузка", т.е. строится несортированная таблица, выгружается в физически создаваемый временный файл, там сортируется, а потом выдается на экран в виде отсортированных данных.
При отработке в интерфейсе данного запроса внешней выгрузки, вернее обратной загрузки не происходит, т.к. интерфейс понятия не имеет об этом - в результате имеем пустую таблицу. И все из-за несуществующего идекса.
Отсюда вывод:
В таблице, которую ты создал необходимо завести индекс, соответствующий ключу, описанному в Order By и открывать эту таблицу, в скобках после описания указывая этот индекс (по имени)...
Например так
Create View vSort As Select * From KatSopr (KatSopr01) ...
Где KatSopr - табла, KatSopr01- существующий индекс.
В принципе индекс можно в описании не указывать, а задавать его при работе с этой таблой...
Но в обоих случаях нужно помнить, что может возникнуть прикладная ошибка, когда в описании таблиц указывается один индекс, а в описании подцепок используется другой индекс, не совпадающий с указанным ранее.
Пример ошибки
Допустим у table1 есть индекс t01=Field1+Filed2 и индекс t02=Field2+Field1
тогда
если описание такое:
Create View vTest
As Select *
From
Table1(t01)
Where
((
myField2 == table1.Field2 And
myField1 == table1.Field1
));
то скопилируется нормально, но при вызове данного интерфейса в момент его инициализации возникнет ошибка с указанием что имеется нарушение использования индексов...

-----
Best regards your Maverick

Re: Как использовать Order by в Vip

Добавлено: 13 окт 2004, 21:29
vadm
я использую:
bounds tbNAME ordered by FieldNAME
подключаешь баундс где надо и вперед... :)

Re: Как использовать Order by в Vip

Добавлено: 28 окт 2004, 18:18
фунт
на самом деле все работает просто Вы делаете _LOOP по таблице virab, хотя уже произошла внешняя выгрузка и как бы все узлы пропали осталась просто таблица включающая все поля из секции as select (Вы там написали "*")
в вашем случае необходимо делать просто
if (t1.GetFirst = tsOk)
t1._LOOP
{...
monthold:=t1.month; // БЕЗ t1.virab. !!!
yearold:=t1.year;
numold:=t1.nnarayd;
cpodrOld:=t1.cpodr;
Insert tnarayd set tnarayd.tnnarayd:=t1.nnarayd, tnarayd.tmonth:=t1.month, tnarayd.tsmena:=Integer(t1.nsmena), ...

но на самом деле описаное Вами действие можно сделать вообще одной командой
insert into tnarayd
(
поля таблицы tnarayd по порядку через запятую,
)
select
поля в том же полядке через запятую,
from virab
/*where
((
если нужно условие ))*/
order by virab.year, virab.month, virab.nnarayd;

Re: Как использовать Order by в Vip

Добавлено: 28 окт 2004, 18:20
фунт
что бы не выдавалось сообщение о внешней выгрузке нужно писать как то так...
order external by
- лучше уточните в asdk

Re: Как использовать Order by в Vip

Добавлено: 29 окт 2004, 08:52
Goblin
Фунт, а у тебя за какое число ASDK ?

Re: Как использовать Order by в Vip

Добавлено: 29 окт 2004, 10:27
Den
На самом деле Insert.Into..select поддерживается еще с Атлантиса 3.03 (ниже из ASDK):

Оператор Insert … Select

Для оптимизации времени разработки прикладного кода, а так же для ускорения работы ПК Галактика и повышения совместимости с языком SQL предлагается использовать оператор копирования содержимого выборки (оператор select) в произвольную таблицу, в том числе и в таблицу в памяти.

Синтаксис

“INSERT”
[ <параметры_визуализации> ]
[ “INTO” ]
<имя_таблицы>
[ “(” <список_полей> “)” ]
“SELECT” <оператор_выборки>
[ “IGNORE_ERRORS (” <список_кодов> “)”]
“;”

Ниже разъясняются отдельные элементы оператора.

<параметры визуализации>
параметры визуализации итераций по таблице, по синтаксису и реализации совпадающие с параметрами визуализации операторов модификации;

<имя таблицы>
узел логической таблицы, в который будет вставлена выборка;

<список полей>
перечислены поля таблицы, в которые производится вставка значений из соответствующих позиций в операторе “SELECT”;

<оператор выборки>
любой “SELECT” оператор выборки языка VIP.

<список кодов>
список кодов ошибок (числа или идентификаторы ts-констант, разделенные запятыми), которые будут игнорироваться в процессе исполнения оператора


При перечислении полей в элементе <список полей> необходимо позиционное соответствие между полями в нем и значениями полей в элементе <оператор выборки>, при этом примитивные преобразования типов могут быть выполнены компилятором автоматически. Если элемент <список полей> опущен, то значения из оператора выборки должны соответствовать всем полям таблицы назначения в соответствии с описанием структуры таблицы.

Если в операторе выборки отсутствуют вычисляемые выражения (в качестве элементов выборки используются константы и поля таблиц базы данных), и если драйвер базы данных реализует соответствующую функцию, то весь оператор может быть выполнен на сервере базы данных без пересылки данных между сервером и клиентом.

Примечание

В рассматриваемом операторе INSERT..SELECT <оператор выборки> представляет собой отдельную логическую таблицу, которая не связана ни с логическими таблицами интерфейса, ни с ограничениями, накладываемыми на них в тот или иной момент времени. А это значит, что все ограничения на <оператор выборки> необходимо задавать внутри него самого.

Re: Как использовать Order by в Vip

Добавлено: 03 ноя 2004, 16:58
savov
Спасибо всем за консультацию!