Запросы

Построение запросов

В инструкциях запросов могут указываться критерии отбора точек данных или атрибутов точек данных, а также требуемая обработка результатов. Данным целям служат отдельные части инструкций (предложения = clause), следующие в определенной последовательности (поскольку они логически связаны друг с другом).

При этом необходимо учитывать следующее:

  • Чем меньше таблица, тем выше производительность (рекомендуется использовать фильтры «FROM», «WHERE_DPT» и «_DP»).
  • Следует ограничивать размер таблицы при помощи ключевого слова «FROM».
  • Рекомендуется использовать «WHERE _DPT» (но только с «=» без «LIKE» и/или без «OR»), если предложение «FROM» не обеспечивает возврат точек данных одного типа.
  • В предложении «FROM»: A* существенно быстрее, чем *A.

ПРИМЕР

Нижеуказанный запрос может быть оптимизирован:

dpQuery(«SELECT ‘_online.._value’ FROM ‘*.Devices.**’ WHERE _DPT=\»Station\»», data);

Возможный вариант оптимизации:

Station_*.Devices вместо *.Devices (если все «stations» (напр., установки, оборудование) начинаются со «Station_*»)

ПРИМЕР
 

Пример бесполезного запроса:

dpQueryConnectSingle(«evStatusCB», true, «evStatus», «SELECT ‘_online.._value’ FROM ‘» + reduManagerDpe + «‘ WHERE _DPT = \»_ReduManager\»»);

SELECT

Отбор данных из базы данных.

ВНИМАНИЕ

Поскольку «КАСКАД Цифра» использует идентификаторы, и одному и тому же имени элемента могут соответствовать несколько различных элементов различных типов точек данных (каждый элемент со своим идентификатором), при формировании запросов при помощи инструкции «SELECT» с элементами точек данных в качестве критериев отбора следует применять ограничения по типам точек данных при помощи предложения «WHERE _DPT». В связи с этим использование подобных запросов не допускается:
string strQuery = «SELECT ‘.name:_original.._value, .Datapoint1.Element1:_original.._value’ FROM ‘*'»;

Корректная форма запроса:
string strQuery = «SELECT ‘.name:_original.._value,.Datapoint.Element1:_original.._value’ FROM ‘*’ WHERE _DPT = \»ExampleDp_Float\»»;

Тип точек данных также необходимо указывать в случае, если в предложении «WHERE» указываются имена элементов точек данных, например «WHERE ‘.dpe’ = 1» !

[ALL]

Обеспечивает возврат всех значений из базы данных, текущих и исторических данных, которые соответствуют предложению «FROM».

ВНИМАНИЕ

Из-за большого количества данных возможны длительные задержки! Для ограничения объема опрашиваемых данных с целью уменьшения времени ожидания может использоваться «TIMERANGE«. «ALL» необходимо использовать только в особых случаях!

[ALERT]

Алармы (см. раздел «_alert_hdl«) также отбираются при помощи инструкции «SELECT».

При помощи «SELECT ALERT» может быть организована подписка на изменения относящихся к алармам атрибутов (значения которых также могут быть опрошены с использованием «alertGet*()»). Изменения атрибутов других конфигурационных элементов или конфигурационных элементов «_alert_hdl», которые не относятся к выборке, не приводят к какой-либо реакции в случае изменений значений.

Если аларм не изменялся, выборка (как действие), относящаяся к конфигурационным элементам «_original» и «_online», осуществляется менеджером событий.

Выборка (как действие), относящаяся к конфигурационным элементам, которые обрабатываются менеджером событий («_general», прочие «_alert_hdl»«_u_range» и т.д.), осуществляется менеджером событий.

Выборка (как действие), относящаяся к прочим конфигурационным элементам («_offline»; не относящимся к менеджеру событий конф.элементам; не относящимся к алармам «_original» / «_online»), осуществляется менеджером БД при помощи «dpGetAsynch()».

ПРИМЕЧАНИЕ

Сравнение с двоичной переменной в предложении «WHERE» при «SELECT ALERT» не работает. Пример неработоспособного сравнения:
«SELECT ALERT ‘_alert_hdl.._add_value_5’ FROM ‘myAlarm.’ WHERE ‘_alert_hdl.._add_value_5’ == TRUE»
Вместо вышеуказанной инструкции следует использовать одну из двух нижеприведенных SQL-инструкций:
«SELECT ALERT ‘_alert_hdl.._add_value_5’ FROM ‘myAlarm.’ WHERE ‘_alert_hdl.._add_value_5’ == 1»
«SELECT ALERT ‘_alert_hdl.._add_value_5’ FROM ‘myAlarm.’ WHERE ‘_alert_hdl.._add_value_5’ LIKE \»TRUE\»»

[ALERT SINGLE]

При использовании в предложении SELECT (при применении в «dpQueryConnectSingle()«) производится выборка только того аларма, который вызвал последние изменения в обработчике алармов.

ПРИМЕЧАНИЕ

Возвращаются только сообщения «УСТН.» и «СНЯТ», сообщения о квитировании не возвращаются.

‘Столбцы’ FROM ‘Строки’

Указание данных, подлежащих выборке при помощи «SELECT».

 [FROM ‘DPGROUP’]  

 Использование групп точек данных в качестве критерия отбора.

[REMOTE]

Указание имени системы при работе с распределенными системами.

ВНИМАНИЕ

В случае использования ключевого слова «REMOTE» оно должно указываться перед ключевым словом «WHERE».

В случае использования «REMOTE <имя системы>», во время выполнения программы может наблюдаться следующее поведение функций «dpQueryConnect»:

  1. На момент вызова функции применительно к какой-либо системе, данная система должна быть подключена, в противном случае функция возвращает ошибку.
  2. В случае потери подключения подписка на изменения неактивна.
  3. В случае восстановления подключения к системе, которая уже была подключена ранее, подписка на изменения активируется.

[REMOTE ALL]

Отбор данных из всех систем. Внутренние сообщения рассылаются всем известным и потенциальным будущим системам, в том числе собственной системе.

ВНИМАНИЕ

«REMOTE ALL» может использоваться только в функциях «dpQueryConnect», но не в «dpQuery»! Без использования ключевого слова «REMOTE ALL» функции dpQueryConnectSingle() и dpQueryConnectAll() могут применяться только к ОДНОЙ системе.

В случае использования «REMOTE ALL», во время выполнения программы может наблюдаться следующее поведение функций «dpQueryConnect»:

  1. Функции применяются ко всем подключенным системам
  2. В случае потери подключения подписка на изменения неактивна.
  3. В случае подключения к системе, а также в случае восстановления подключения, подписка на изменения активируется.

[ WHERE ]

Критерий отбора данных (см. также раздел «Ключевые слова SQL«).

[ TIMERANGE () ]

Критерий отбора данных по времени (см. также раздел «Ключевые слова SQL«).

[ SORT BY y1[, y2, …]] или [ORDER BY y1[,y2, …]]

Сортировка отобранных данных (см. также раздел «Ключевые слова SQL«).

[ GROUP BY y1 [, y2, …]]

Группировка отобранных данных (см. также раздел «Ключевые слова SQL«).

[ FIRST | LAST x ]

Дополнительные критерии отбора данных (см. также раздел «Ключевые слова SQL«).

ВНИМАНИЕ

SQL-запрос к БД всегда состоит из «SELECT» и предложения «FROM». Указываемые в квадратных скобках предложения являются необязательными.

Тип запроса определяет его синтаксис. В ключевых словах (например, «SELECT») всегда используются заглавные буквы. Ключевые слова чувствительны к регистру. Строки (strings) заключаются в двойные кавычки («), идентификаторы точек данных заключаются в одинарные кавычки (‘). Могут использоваться знаки подстановки.

ПРИМЕЧАНИЕ

При указании в SELECT нескольких атрибутов, перечисляемых через запятые (‘_original.._value,_alert_hdl.._act_state_color,_online.._stime’), после запятых не должны использоваться пробелы. Данное правило также относится к части «FROM».

Результаты запросов

Результат того или иного типа запроса возвращается в виде двумерного массива, и, следовательно, он может рассматриваться как таблица. Выражение после ключевого слова «SELECT» указывает на подмножество отбираемых данных из источников, указываемых при помощи предложения «FROM», см. пример ниже.

ЗначокПРИМЕР

dpQuery(«SELECT ‘KF.DT.AT’ FROM ‘DP.EL'», tab);

Переменная «tab» типа «dyn_dyn_anytype» позволяет возвращать значения любого типа.

Как правило, результат запроса имеет следующий вид:

Таблица: Результат запроса

 Столбец 1Столбец 2
Строка 1 KF.DT.AT
Строка 2DP.ELЗначение DP.EL: KF.DT.AT с индексом списка 1
Строка 3DP.ELЗначение DP.EL: KF.DT.AT с индексом списка 2
:::
Строка xDP.ELЗначение DP.EL: KF.DT.AT с индексом списка x

Первая строка играет особую роль. Первый столбец пустой, начиная со второго столбца первой строки в заголовок столбца возвращается маркировка из части «SELECT» запроса (конфигурационные элементы, возможно с элементами).

Опрошенные значения находятся в строках, начиная со второй. Столбец 1 содержит имя области отбора данных. Полученные в результате выполнения запроса значения сохраняются и индексируются во втором столбце.

ЗначокПРИМЕР

В следующем примере используются точка данных «mld_bit» типа «ExampleDp_Bit» и точка данных «mld_float» типа «ExampleDp_Float».

Рисунок: Точки данных «mld_bit» и «mld_float»

Пример запроса на получение значений mld_float.:_online.._value и mld_float.:_online.._stime с выводом результата:

main(){string start='»‘+»1998.10.27 00:00:00.000″+'»‘;string stop='»‘+»1998.10.27 14:50:35.000″+'»‘;dyn_dyn_anytype tab;int length, run;dpQuery(«SELECT ‘_online.._value’,’_online.._stime’ FROM
  ‘mld_float’ TIMERANGE(\»»+start+»\»,\»»+stop+»\»,1,1)»,tab);length=dynlen(tab);DebugN(«Length :»,length);for (run=1; run<=length;run++){DebugN(tab[1]);DebugN(tab[2]);DebugN(tab[3]);setValue(«Tab2″,»appendLine»,dynlen(tab),»Column 1″, tab[run][1],»time», tab[run][2],»value»,tab[run][3]);}}

Более подробная информация об использовании «TIMERANGE» и о формате переменных «start» и «stop» представлена в разделе «Ключевые слова SQL».

Таблица: Результат запроса

 123
1Type:0 Sys:0 Dp:0 El:0 Conf:29 Det:0 Attr:0:_online.._valueType:0 Sys:0 Dp:0 El:0 Conf:29 Det:0 Attr:0:_online.._stimeType:0 Sys:0 Dp:0 El:0 Conf:29 Det:0 Attr:0
2System1: mld_float.Type:1 Sys:1651 Dp:1 El:0 Conf:0 Det:0 Attr:026Mon Jun 22 08:59:34 1998 473
3System1: mld_float.Type:0 Sys:1 Dp:1651 El:1 Conf:0 Det: 0 Attr:024Mon Jun 22 08:59:35 1998 476

Различия между значениями и алармами

В отличие от выборки по значениям (например, «dpQuery(SELECT…)»), в случае выборки по алармам (например, «dpQuery(SELECT ALERT…)») формируется дополнительный столбец, в котором находятся времена алармов. Т.е. при выборке «по значениям» фактические значения находятся в столбце 2, а в случае выборки «по алармам» значения находятся в третьем столбце. При выборке по алармам первое значение находится в ячейке [2][3], следующее — в ячейке [3][3], …, [n][3] ( n = последняя строка; 2 <= n).

ЗначокПРИМЕР

main(){string start='»‘+»1998.10.27 00:00:00.000″+'»‘;string stop='»‘+»1998.110.01 11:00:00.000″+'»‘;dyn_dyn_anytype tab;int length, run;dpQuery(«SELECT ALERT ‘_alert_hdl.._value’, ‘_alert_hdl..text’
  FROM ‘mld_float’ TIMERANGE(\»»+start+»\»,}\»»+stop+»\»,1,1)»,tab);length=dynlen(tab);DebugN(«Length :»,length);for (run=1; run<=length;run++){DebugN(tab[1]);DebugN(tab[2]);DebugN(tab[3]);setValue(«Tab2″,»appendLine»,dynlen(tab),»Column 1″, tab[run][1],»time», tab[run][2],»Value»,tab[run][3],»Text», tab[run][4] );}}

Более подробная информация об использовании «TIMERANGE» и о формате переменных «start» и «stop» представлена в разделе «Ключевые слова SQL».

Таблица: Результат запроса

 1234
1Type:0 Sys:0 Dp:0 El:0 Conf:0 Det:0 Attr:0Type: 0 Sys: 0 Dp: 0 El: 0 Conf: 0 Det: 0 Attr: 0:_alert_hdl..value Type: 0 Sys: 0 Dp:0 El: 0 Conf: 23 Det: 0 Attr: 131675:_alert_hdl..text Type:0 Sys:0 Dp:0 El:0 Conf:23 Det:0 Attr:2621940
2System1:mld_float. Type:27 Sys:1 Dp:1651 El:1 Conf:0 Det:0 Attr:0Mon Jun 22 09:20:34 1998 650System1:mld_float.: alert_pro.3Type:1 Sys:1651 Dp:1 El:3 Conf:23 Det:0 Attr:0261 LANG:0 «Текст при превышении порога»;
3System1:mld_float. Type:27 Sys:1 Dp:1651 El:1 Conf:0 Det:0 Attr:0Mon Jun 22 09:20:35 1998 680System1:mld_float.: alert_pro.3Type:1 Sys:1651 Dp:1 El:3 Conf:23 Det:0 Attr:0241 LANG:0 «Текст при значении ниже порога»;

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

Группы точек данных

Начиная с версии 2.11 существует возможность использования групп точек данных в качестве критерия отбора. Синтаксис:  

 SELECT … FROM ‘DPGROUP(<gName>)’ WHERE …

или

SELECT … FROM ‘{DPGROUP(<g1>),DPGROUP(<g2>)}’ WHERE …

В запросе должна использоваться внутренняя точка данных для групп. Применение знаков подстановки при работе с группами не поддерживается. Существует возможность комбинирования групп с точками данных.

ПРИМЕР

«SELECT ‘_original.._value’ FROM ‘DPGROUP(_DpGroup00006_Public)'»

ПРИМЕЧАНИЕ

Не допускается использование пробелов после запятых, разделяющих две группы точек данных или точки данных.

Распределенные системы

При использовании SQL применительно к распределенным системам, в запросах необходимо использовать дополнительную запись:

…REMOTE ‘имя_системы’

Предложение «REMOTE» должно располагаться в конце инструкции SQL. Может быть указано имя только одной системы. Имя должно быть заключено в одинарные кавычки.

…REMOTE ALL

Предложение «REMOTE ALL» должно располагаться в конце инструкции SQL. Использование этого предложения обеспечивает выборку из всех систем. Внутренние сообщения рассылаются всем известным и будущим системам, в том числе собственной системе. Функция обратного вызова (указываемая, например, в «dpQueryConnectAll()») вызывается при каждом ответе.

ЗначокВНИМАНИЕ

При использовании функции «dpQueryConnectSingle()» совместно с предложением «REMOTE», распределенная система должна быть указана в конфигурационном файле.

ПРИМЕР

«SELECT ‘_original.._value,_online.._stime’ FROM ‘ExampleDP_Arg1.’ REMOTE ‘System2′»

ПРИМЕР

query = «SELECT ‘_original.._value’ FROM ‘ExampleDP_Arg*’ REMOTE ALL»;

dpQueryConnectAll(«work»,true,»Dist test»,query);

Обработка

Внутренняя обработка запроса осуществляется согласно последовательности ключевых слов. В первую очередь выполняется выборка из базы данных («SELECT» или «SELECT ALERT»), при этом незамедлительно учитываются условия, связанные с типами точек данных или атрибутами, явно указанными в перечне столбцов. На следующем этапе проверяются все прочие условия. После этого в полученной промежуточной таблице может быть выполнена сортировка. После сортировки определяется число строк возвращаемого результата. Каждая возвращаемая строка, по мере возможности, всегда полностью заполняется действующими на настоящий момент времени значениями.

В случае подписки на изменения текущих значений, актуализация таблицы осуществляется каждый раз при получении нового значения. Сортировка принимается во внимание в том случае, когда в качестве результата требуется вся таблица. Ограничения по количеству строк в данном режиме не поддерживаются.

«GROUP BY» применяется только при отсутствии подписки на изменения значений. При этом отсортированная таблица результатов обрабатывается построчно, запись в групповую таблицу добавляется для каждой группы. При использовании статистической функции перед ключевым словом «FROM» И при отсутствии предложения «GROUP BY», при обработке запроса возвращается одна строка с суммарной информацией по всей таблице результатов.

Символы «{» и «}» в части «FROM» могут использоваться для задания дополнительных критериев отбора (ограничивающего характера) по точкам данных.

ЗначокПРИМЕР

string start=»1998.10.28 12.30.00.000″

string stop=»1998.10.30 12.45.00.000″

dpQuery(«SELECT ‘SUM(_online.._value)’ FROM ‘{alt_bit,alert_float}’
  WHERE _DPT = \»ExampleDP_Float\»
  TIMERANGE(\»»+start+»\»,\»»+stop+»\», 1, 0)
  ORDER BY 0 GROUP BY SECS(10)», tab);

ЗначокПРИМЕЧАНИЕ

В списке { } могут использоваться знаки подстановки, например, Example*{Arg?}.

В примере выше сначала отбираются и сохраняются во внутренней таблице результатов все принадлежащие временному интервалу start — stop значения всех точек данных типа ExampleDP_Float. На втором этапе формируются суммы полученных значений, после чего они сортируются согласно их величинам и сохраняются в группах с Dt = 10 секунд.

Более подробная информация о TIMERANGE или статистических функциях представлена в разделе «Ключевые слова SQL».

См. также описания функций «isAnswer()» и «isRefresh()«.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *