Приклади SQL-запитів для функцій QuerySQL та Query

Геодезична інформаційна система 6 та Геодезична інформаційна система 6 Агро

Модератори: NickS, feNICKs

Аватар користувача
NickS
Повідомлень: 1393
З нами з: 04 квітня 2008, 12:21

Приклади SQL-запитів для функцій QuerySQL та Query

Повідомлення NickS » 25 січня 2012, 16:32

Тут вы можете выставлять или просить сделать sql-запросы для использования в отчётных формах или для других целей в GIS6.

Например, готовый запрос для функции QuerySQL, который выводит список смежеств в таблице данных, которую можно перебрать в бэнде:
QUERYSQL( 'Select * From Vector V, Point P, Polygon L Where V.ID_Point = P.ID_Point And P.ID_Polygon = L.ID_Polygon And L.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' Order by L.ID_Polygon, V.Litera');

LeViK
Повідомлень: 63
З нами з: 25 січня 2012, 09:52
Звідки: BeerDyansk

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення LeViK » 25 лютого 2012, 11:39

Код: Виділити все

  QUERY( 'Select P.* From NotePoint P, Note N Where P.ID_Note = N.ID_Note  And N.PenStyle = 159  And N.ID_Type = 3 And N.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' Order by P.ID_NotePoint');

Запрос создает базу с точками двойных линий, только вот не вытаскивает углы <DM1.Query."DCut"> Самому их пересчитывать не хочется. Что не так?

LeViK
Повідомлень: 63
З нами з: 25 січня 2012, 09:52
Звідки: BeerDyansk

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення LeViK » 27 лютого 2012, 10:42

Возможно ли включение запроса Query в тело цикла while, с учетом того что запрос используется в другой чисти кода, и из этой базы вытягиваются значения?

Аватар користувача
NickS
Повідомлень: 1393
З нами з: 04 квітня 2008, 12:21

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення NickS » 27 лютого 2012, 14:16

LeViK писав:

Код: Виділити все

  QUERY( 'Select P.* From NotePoint P, Note N Where P.ID_Note = N.ID_Note  And N.PenStyle = 159  And N.ID_Type = 3 And N.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' Order by P.ID_NotePoint');

Запрос создает базу с точками двойных линий, только вот не вытаскивает углы <DM1.Query."DCut"> Самому их пересчитывать не хочется. Что не так?

1. Надо начинать писать условие с заглавного и далее по связям. В Вашем случае, вы находите все объекты для текущего участка, потому условие N.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' должно быть вначале, тоесть описание связей следует слева направо.
2. Связь надо начинать с самого участка:

Код: Виділити все

O.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' and N.ID_Object = O.ID_Object

3. Увы, для косметических слоёв, мы не расчитываем углы чтобы не ухудшить быстродействие. Потому, если уж они надо, то прийдётся их вручную расчитывать.
4. Желательно сделать два запроса: в первом перебирать сами линии, а во втором перебирать координаты каждой из линий.
Для этого:
В основном коде главный запрос, чтобы создать таблицу двойных линий:

Код: Виділити все

QuerySQL('Select N.* From Object O, Note N Where O.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' and N.ID_Object = O.ID_Object and N.PenStyle = 159 and N.ID_Type = 3');

Потому для MasterData источником будет QuerySQL, в свойствах поставте "Печатать, если Detail пустой", а в OnBeforePrint прописать второй SQL-запрос:

Код: Виділити все

Query('Select P.* From Object O, Note N, NotePoint P Where O.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' and N.ID_Object = O.ID_Object and P.ID_Note = ' + IntToStr(<DM1.QuerySQL."ID_Note">) + ' and N.PenStyle = 159 and N.ID_Type = 3 Order by P.ID_NotePoint');


Это всё нужно для правильной реализации той задачи, которую Вы планируете сделать. А теперь, чтобы подсчитать дирекционные углы, нужно в отчётную форму вставить такую функцию:

Код: Виділити все

function CalcRump( XF, YF, XN, YN: Double): Double;
Var
   DX, DY : Double;
begin
   DX := XN -XF;
   DY := YN -YF;

   If (DX = 0) Then
      Begin
         If (DY < 0) Then
           Result := -90
         Else
           Result := 90;
      End
   Else
      Result := (180 / Pi) *ArcTan( DY /DX);

   If DX >= 0 Then
      Begin
         If DY >= 0 Then
            Result := Result
         Else
            Result := 360 +Result;
      End
   Else
      Begin
         If DY > 0 Then
            Result := 180 +Result
         Else
            Result := 180 +Result;
      End;
end;


Где CalcRump( X1, Y1, X, Y); - выполнение функции и X1, Y1 - предшествующая координата, а Х, Y - текущая.
Вот отчётная форма, в которой показаны все описанные действия.
dcut.zip
Пример отчётной формы
(1.68 Кіб) Завантажено 11 разів


LeViK писав:Возможно ли включение запроса Query в тело цикла while, с учетом того что запрос используется в другой чисти кода, и из этой базы вытягиваются значения?

Можно, конечно, но не забывайте, что при следующем выполнении функций, Query или QuerySQL созданные ими таблицы пересоздаются.

Сейчас мы добавили новые возможности в отчётные формы. Теперь можно создавать неограниченное количество запросов любой сложности и создавать и вызывать их. Это инструменты "Компоненти BDE" и "Компоненти ADO".

LeViK
Повідомлень: 63
З нами з: 25 січня 2012, 09:52
Звідки: BeerDyansk

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення LeViK » 27 лютого 2012, 15:42

NickS писав:1. Надо начинать писать условие с заглавного и далее по связям. В Вашем случае, вы находите все объекты для текущего участка, потому условие N.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' должно быть вначале, тоесть описание связей следует слева направо.

Спасибо за такой разжёванный ответ. Я несколько неправильно выразился. Я не диррекционные углы пытаюсь вывести, меня интересуют правые углы между линией двух точек снятых GPS-ом и точками участка снятых с этих двух точек. Я знаю как это сделать, вычислить через теорему косинусов угол между тремя точками, арккосинуса в паскале нет, но ничего уже нашел, потом проблема в угле, он будет всегда острый, а не правый, поэтому надо задать условие прямой и посмотреть будет ли угол больше 180°.
В ступор же зашел когда не смог выбрать правильные координаты для каждой линии. Конечную координату нашел просто, начальную после второй будет тоже просто, а вот со второй пока мучаюсь. Ну ничего всё будет пучком 8-)

Аватар користувача
NickS
Повідомлень: 1393
З нами з: 04 квітня 2008, 12:21

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення NickS » 27 лютого 2012, 16:05

LeViK писав:арккосинуса в паскале нет, но ничего уже нашел

Да, но его можно представить такой формулой:

Код: Виділити все

Arctan(Sqrt(1-sqr(x))/x);

LeViK
Повідомлень: 63
З нами з: 25 січня 2012, 09:52
Звідки: BeerDyansk

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення LeViK » 28 лютого 2012, 14:20

Вот есть пример запроса для баз BDE


Select P.*
From
Object O,
NotePoint P, Note N
Where O.ID_Object = <DM1.QbObject."ID_Object">
And N.ID_Object = O.ID_Object
AND P.ID_Note = N.ID_Note
And N.PenStyle = 159
And N.ID_Type = 3
Order by P.ID_NotePoint

Как подставить значение ID_Object текущего участка?

feNICKs
Повідомлень: 412
З нами з: 13 січня 2012, 16:03
Контактна інформація:

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення feNICKs » 28 лютого 2012, 15:34

LeViK писав:Вот есть пример запроса для баз BDE


Select P.*
From
Object O,
NotePoint P, Note N
Where O.ID_Object = <DM1.QbObject."ID_Object">
And N.ID_Object = O.ID_Object
AND P.ID_Note = N.ID_Note
And N.PenStyle = 159
And N.ID_Type = 3
Order by P.ID_NotePoint

Как подставить значение ID_Object текущего участка?

Не совсем понятен вопрос... т.к. Nick описал выше данный пример... Вам просто необходимо данный запрос записать в сроку и в части где вставляете номер записи текущего участка переводите значение ID_Object в сроку. Например, ADOQuery1.SQL('Select P.* ... O.ID_Object=' + IntToStr(<DM1.QbObject."ID_Object">) + 'And .... Order by P.ID_NotePoint'); и т.д.

Аватар користувача
NickS
Повідомлень: 1393
З нами з: 04 квітня 2008, 12:21

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення NickS » 28 лютого 2012, 17:45

LeViK писав:Вот есть пример запроса для баз BDE


Select P.*
From
Object O,
NotePoint P, Note N
Where O.ID_Object = <DM1.QbObject."ID_Object">
And N.ID_Object = O.ID_Object
AND P.ID_Note = N.ID_Note
And N.PenStyle = 159
And N.ID_Type = 3
Order by P.ID_NotePoint

Как подставить значение ID_Object текущего участка?


Если Вы выполняете его для отчётной формы и используете таблицу ADO (именно её рекомендую использовать), тогда надо в коде задавать этот запрос, так как и с помощью функций Query и QuerySQL - одной строкой. В Вашем случае:

Код: Виділити все

TableADO.SQL.Text := 'Select P.* From Object O, NotePoint P, Note N Where  O.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' And N.ID_Object = O.ID_Object AND P.ID_Note = N.ID_Note And N.PenStyle = 159 And N.ID_Type = 3 Order by P.ID_NotePoint';

где TableADO - название Вашей таблици.

Не забываем, чтобы использовать эту таблицу в коде, надо уже так как в среде программирования Delphi открывать и закрывать её:
TableADO.Open - открывает таблицу, иначе, не открыв, будет ошибка, если к ней обратитесь.
В конце выполнения отчёта, все таблици не забыть закрыть:
TableADO.Close.

Другие функции, которые могут пригодится:
TableADO.Next - переход на следующую запись
TableADO.EOF - проверка конца таблици
TableADO.RecordCount - выводит количество записей в таблице
TableADO.First - переход на первую запись

feNICKs
Повідомлень: 412
З нами з: 13 січня 2012, 16:03
Контактна інформація:

Re: Примеры SQL-запросов для функций QuerySQL и Query

Повідомлення feNICKs » 29 лютого 2012, 09:32

LeViK писал(а):
Я создал запрос АДО (ну или БДЕ), подключил к нему бенд, и вручную записал запрос в параметре SQL обїекта запрос АДО в инспекторе заработало только при определённых значениях:

Select P.*
From NotePoint P, Note N
Where P.ID_Note = N.ID_Note And N.PenStyle = 159 And N.ID_Type = 3
And N.ID_Object = 23067
Order by P.ID_NotePoint

Когда же попытался каким-то образом поменять значение 23067 на значение поля бд или переменной ни чего не получилось
Когда же записываю в тело основного кода строку (при удалённых значениях параметра SQL объекта ADOQuery1)
ADOQuery1.SQL('Select P.* From NotePoint P, Note N Where P.ID_Note = N.ID_Note And N.PenStyle = 159 And N.ID_Type = 3 And N.ID_Object = ' + IntToStr(<DM1.QbObject."ID_Object">) + ' Order by P.ID_NotePoint');
ставит указатель после ADOQuery1.SQL и пишет слишком много параметров. Вот меня и интересует как нормально подключить переменную (или поле бд) в запрос БДЕ/АДО


Проверил сам запрос, все работает, просто в части кода нужно присваивать сроку-запрос - ADOQuery1.SQL.Add('Запрос'); или как писал Nick - ADOQuery1.SQL.Text:='Запрос';
П.С. В своем предыдущем примере я перепутал и написал пример для Query/QuerySQL. Вот мой пример:

With ADOQuery1 Do
Begin
SQL.CLear;
SQL.Add('Select P.* From NotePoint P, Note N Where (P.ID_Note = N.ID_Note) And (N.PenStyle = 9) And (N.ID_Type = 3) And (N.ID_Object='+IntToStr(<DM1.QbObject."ID_Object">)+' ) Order by P.ID_NotePoint');
Open;
End;

procedure Page1OnAfterPrint(Sender: TfrxComponent);
begin
ADOQuery1.Close;
end;