Использование ПОДД СМЭВ ========================== .. _sql_syntax: SQL-синтаксис ----------------- Регламентированные SQL-запросы, регистрируемые в ПОДД СМЭВ должны соответствовать следующему синтаксису. .. _tab_sql_syntax: .. table:: SQL-синтаксис +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | № | Описание | Пример запроса | +====+===============================================+=======================================================================================+ | | **Числовые типы данных** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 1 | Типы данных INTEGER и SMALLINT | ``SELECT CAST(1 AS INT)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 2 | Типы данных REAL, DOUBLE PRECISION и FLOAT | ``SELECT CAST(1 AS FLOAT)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 3 | Типы данных DECIMAL и NUMERIC | ``SELECT CAST(1 AS NUMERIC)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 4 | Арифметические операторы | ``SELECT 10+1, 9-2, 8*3, 7/2`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 5 | Числовые сравнения | ``SELECT 1 WHERE 1 < 2`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 6 | Неявные преобразования между числовыми типами | ``SELECT int_column FROM t WHERE int_column = 1.00`` | | | данных | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Символьные типы данных** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 7 | Тип данных CHARACTER | ``SELECT CAST(‘1111111111111111111111111111111111111111111’ AS CHAR)`` | | | | | | | Длина по умолчанию 30 | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 8 | Тип данных CHARACTER VARYING | ``SELECT CAST(‘1111111111111111111111111111111111111111111’ AS VARCHAR)`` | | | | | | | Длина по умолчанию 30 | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 9 | Символьные строки | ``SELECT ''`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 10 | Функция CHARACTER_LENGTH | ``SELECT character_length(char_column) FROM t`` | | | | | | | убирает завершающие пробелы из значений | | | | CHARACTER перед подсчётом символов | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 11 | Функция OCTET_LENGTH | ``SELECT octet_length(char_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 12 | Функция SUBSTRING | ``SELECT substring(char_column FROM 1 FOR 1) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 13 | Конкатенация символьных строк | ``SELECT ‘a’ || ‘b’ FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 14 | Функции UPPER и LOWER | ``SELECT upper(‘a’),lower(‘B’) FROM t`` | | | | | | | | ``SELECT int_column FROM t WHERE int_column > (SELECT DISTINCT (int_column) FROM t)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 15 | Функция TRIM | ``SELECT trim(‘a ‘) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 16 | Неявные преобразования между типами | ``SELECT char_column FROM t WHERE char_column > varchar_column`` | | | символьных строк | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 17 | Функция POSITION | ``SELECT position(‘A’ IN char_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 18 | Сравнения символов | ``SELECT char_column FROM t WHERE char_column > ‘a’`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Идентификаторы** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 19 | Идентификаторы с разделителями | ``SELECT 1 AS «t47»`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 20 | Идентификаторы в нижнем регистре | ``SELECT 1 AS t48`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 21 | Завершающее подчёркивание | ``SELECT 1 AS t49_`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Базовое определение запросов** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 22 | SELECT DISTINCT | ``SELECT DISTINCT int_column FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 23 | Предложение GROUP BY | ``SELECT DISTINCT int_column FROM t GROUP BY int_column`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 24 | GROUP BY может содержать колонки не из | ``SELECT DISTINCT char_column FROM t GROUP BY lower(char_column)`` | | | <списка выборки> | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 25 | Элементы списка выборки могут | ``SELECT int_column AS K FROM t ORDER BY K`` | | | переименовываться | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 26 | Предложение HAVING | ``SELECT count(*) FROM t HAVING count(*) > 0`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 27 | Корреляционные имена в предложении FROM | ``SELECT K.column FROM t AS K`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 28 | Переименование колонок в предложении FROM | ``SELECT column FROM t AS x(q, c)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Базовые предикаты и условия поиска** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 29 | Предикат сравнения | ``SELECT column FROM t WHERE 0 = 0`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 30 | Предикат BETWEEN | ``SELECT column FROM t WHERE ‘ ‘ BETWEEN ‘’ AND ‘’`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 31 | Предикат IN со списком значений | ``SELECT column FROM t WHERE char_column IN (‘a’, upper(‘a’))`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 32 | Предикат LIKE | ``SELECT column FROM t WHERE char_column LIKE ‘_’`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 33 | Предложение ESCAPE в предикате LIKE | ``SELECT column FROM t WHERE ‘abc’ LIKE ‘abcX_’ ESCAPE ‘X’`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 34 | Предикат NULL | ``SELECT column FROM t WHERE char_column IS NOT NULL`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 35 | Предикаты количественного сравнения | ``SELECT column FROM t WHERE char_column = ANY (SELECT char_column FROM t)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 36 | Предикат EXISTS | ``SELECT column FROM t WHERE NOT EXISTS (SELECT char_column FROM t)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 37 | Подзапросы в предикате сравнения | ``SELECT column FROM t WHERE int_column > (SELECT max (int_column) FROM t)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 38 | Подзапросы в предикате IN | ``SELECT column FROM t WHERE char_column IN (SELECT char_column FROM t)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 39 | Подзапросы в предикате количественного | ``SELECT column FROM t WHERE char_column >= ALL(SELECT char_column FROM t)`` | | | сравнения | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 40 | Коррелирующие подзапросы | ``SELECT column FROM t WHERE int_column = (SELECT int_column FROM t2 WHERE t2.char_ | | | | column = t.char_column)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 41 | Условие поиска | ``SELECT column FROM t WHERE 0 <> 0 OR ‘a’ < ‘b’ AND int_column IS NOT NULL`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Простые выражения с запросами** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 42 | Табличный оператор UNION DISTINCT | ``SELECT column FROM t UNION DISTINCT SELECT column1 FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 43 | Табличный оператор UNION ALL | ``SELECT column FROM t UNION ALL SELECT column1 FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 44 | Табличный оператор EXCEPT DISTINCT | ``SELECT column FROM t EXCEPT DISTINCT SELECT column1 FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 45 | Колонки, объединяемые табличными операторами, | ``SELECT char_column FROM t UNION SELECT 5`` | | | могут иметь разные типы данных | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 46 | Табличные операторы в подзапросах | ``SELECT column FROM t WHERE ‘a’ IN (SELECT char_column FROM t UNION SELECT | | | | char_column FROM t)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Функции множеств** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 47 | AVG | ``SELECT avg(int_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 48 | COUNT | ``SELECT count(int_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 49 | MAX | ``SELECT max(int_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 50 | MIN | ``SELECT min(int_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 51 | SUM | ``SELECT sum(int_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 52 | Дополнение ALL | ``SELECT sum(ALL int_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 53 | Дополнение DISTINCT | ``SELECT sum(DISTINCT int_column) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 54 | Оператор SELECT, возвращающий одну строку | ``SELECT count(*) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Базовая поддержка курсоров** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 55 | Колонки ORDER BY, отсутствующие в списке | ``SELECT int_column FROM t ORDER BY char_column`` | | | выборки | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 56 | Выражения значений в предложении ORDER BY | ``SELECT int_column FROM t ORDER BY -int_column`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 57 | Поддержка NULL (NULL вместо значений) | ``SELECT int_column FROM t WHERE int_column IS NULL`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Базовое соединение таблиц** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 58 | Внутреннее соединение (но не обязательно с | ``SELECT a.int_column FROM t a JOIN t b ON a.int_column = b.int_column`` | | | ключевым словом INNER) | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 59 | Ключевое слово INNER | ``SELECT a.int_column FROM t a JOIN t b ON a.int_column = b.int_column`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 60 | LEFT OUTER JOIN | ``SELECT a.int_column, b.int_column FROM t a LEFT OUTER JOIN t b ON a.int_column = | | | | b.int_column`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 61 | RIGHT OUTER JOIN | ``SELECT a.int_column, b.int_column FROM t a RIGHT OUTER JOIN t b ON a.int_column = | | | | b.int_column`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 62 | Внешние соединения могут быть вложенными | ``SELECT a.int_column FROM t a LEFT OUTER JOIN t b ON a.int_column = b.int_column | | | | LEFT OUTER JOIN t2 c ON a.int_column = c.int_column`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 63 | Внутренняя таблица с левой или правой стороны | ``SELECT t2.int_column FROM (t2 LEFT OUTER JOIN t ON t.int_column = t2.int_column) j | | | внешнего соединения может также участвовать | INNER JOIN t2 ON j.int_column = t2.int_column`` | | | во внутреннем соединении | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 64 | Поддерживаются все операторы сравнения (а не | ``SELECT column FROM t WHERE 0 = 1 OR 0 > 1 OR 0 < 1 OR 0 <> 1`` | | | только =) | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Базовая поддержка даты и времени** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 65 | Тип данных DATE (включая поддержку строк | ``SELECT ‘2012-07-12’ AS "DATE"`` | | | DATE) | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 66 | Тип данных TIME (включая поддержку строк | ``SELECT ‘1:2:3’ AS "TIME"`` | | | TIME) с точностью до секунд как минимум с 0 | | | | знаков после запятой | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 67 | Тип данных TIMESTAMP (включая поддержку строк | ``SELECT ‘2012-07-12’ AS "TIMESTAMP"`` | | | TIMESTAMP) с точностью до секунд как минимум | | | | с 0 и 6 знаками после запятой | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 68 | Предикаты сравнения с типами данных DATE, | ``SELECT column FROM t3 WHERE date_column = date_column AND time_column = time_column | | | TIME и TIMESTAMP | AND timestamp_column = timestamp_column`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 69 | Явное приведение (CAST) между типами | ``SELECT cast(date_column AS VARCHAR(10)) FROM t3`` | | | даты/времени и типами символьных строк | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 70 | CURRENT_DATE | ``SELECT current_date FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 71 | LOCALTIME | ``SELECT localtime FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 72 | LOCALTIMESTAMP | ``SELECT localtimestamp FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Расширенная поддержка даты и времени** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 73 | FOR SYSTEM_TIME (запрос данных, актуальных на | ``SELECT column FROM t FOR SYSTEM_TIME AS OF 'YYYY-MM-DD hh:mm:ss'`` | | | указанную дату и время) | | | | | ``SELECT column FROM t FOR SYSTEM_TIME AS OF TIMESTAMP 'YYYY-MM-DD hh:mm:ss'`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | | Указание «TIMESTAMP» опционально | | | 74 | Вычисление интервала (c указанием единиц | ``select ('YYYY-MM-DD hh:mm:ss' - 'YYYY-MM-DD hh:mm:ss') MONTH`` | | | времени: YEAR, MONTH, DAY, HOUR, MINUTE, | | | | SECOND) | | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 75 | Функция CAST | ``SELECT cast(int_column AS INT) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | **Выражение CASE** | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 76 | Простой оператор CASE | ``SELECT CASE WHEN 1 = 0 THEN 5 ELSE 7 END FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 77 | Оператор CASE с условиями | ``SELECT CASE 1 WHEN 0 THEN 5 ELSE 7 END FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 78 | NULLIF | ``SELECT nullif(int_column, 7) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 79 | COALESCE | ``SELECT coalesce(int_column,7) FROM t`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 80 | Длинные идентификаторы | ``SELECT 1 AS A12345678901234567890123456789`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 81 | Спецсимволы Unicode в идентификаторах | ``SELECT 1 AS Я12345678901234567890123456789`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 82 | Спецсимволы Unicode в текстовых строках | ``SELECT U&'\6553'`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 83 | Национальные символы | ``SELECT 'Я'`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 84 | Скалярные значения подзапросов | ``SELECT int_column FROM t WHERE int_column = (SELECT count(*) FROM t)`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ | 85 | Расширенный предикат NULL | ``SELECT column FROM t WHERE row(int_column, int_column) IS NOT NULL`` | +----+-----------------------------------------------+---------------------------------------------------------------------------------------+ .. _query_examples: Примеры запросов с использованием SQL-синтаксиса, поддерживаемого ПОДД СМЭВ ---------------------------------------------------------------------------- Далее приведены примеры SQL-выражений Регламентированных SQL-запросов. Необходимо учитывать, что возможность выполнения соответствующих синтаксических конструкций зависит от их поддержки со стороны ПО Витрины данных. .. _tp_quert_example: Запрос с использованием табличных выражений ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: with cte as ( select shortname, regioncode, oktmo from fias.addrobj where formalname = ‘Москва’ ) select * from cte .. _base_operators_query: Запросы с использованием базовых операторов 1. Запрос с использованием EXCEPT: .. code-block:: select oktmo from fias.addrobj EXCEPT select kod2 from oktmo.oktmo 2. Запрос с использованием INTERSECT: .. code-block:: select oktmo from fias.addrobj INTERSECT select kod2 from oktmo.oktmo 3. Запросы с использованием UNION: .. code-block:: select oktmo from fias.addrobj UNION select kod2 from oktmo.oktmo 4. Запросы с использованием ORDER BY: .. code-block:: select shortname, formalname from fias.addrobj where aolevel = 1 order by formalname .. code-block:: select shortname, formalname from fias.addrobj where aolevel = 1 order by formalname desc 5. Запрос использованием GROUP BY, HAVING: .. code-block:: select ao.regioncode, count(*) N from fias.addrobj ao left join oktmo.oktmo o on o.kod2 = ao.oktmo where o.kod2 is null group by ao.regioncode having COUNT(*) > 3000 order by N desc .. _specifying_version: Указание в запросе версии Витрины ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: select * from egrul.1.0.legalentity select * from egrul.2.0.legalentity Результат может содержать разное количество возвращаемых атрибутов в соответствии со структурой таблицы "legalentity" Витрины "egrul" версий 1.0 и 2.0. .. _join_query: Запросы с использованием JOIN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: select le.short_name, rc.region_full_name from egrul.legalentity le join egrul.region_codes rc on le.region_code = rc.region_code .. code-block:: SELECT ao.oktmo, o.name, o.kod from fias.addrobj ao JOIN oktmo.oktmo o on ao.oktmo = o.kod2 WHERE ao.offname = ‘Москва’ AND o.regionname = ‘город Москва’ .. code-block:: select le.short_name, le.region_code, o.regionid, o.name, o.regionname from egrul.legalentity le left join oktmo.oktmo o on cast(o.regionid as varchar) = le.region_code where o.kod2 is null .. code-block:: select le.short_name, le.region_code, o.regionid, o.name, o.regionname from egrul.legalentity le full join oktmo.oktmo o on cast(o.regionid as varchar) = le.region_code where le.ogrn is null or o.kod2 is null .. code-block:: select le.short_name, le.region_code, o.regionid, o.name, o.regionname from egrul.legalentity le right join oktmo.oktmo o on cast(o.regionid as varchar) = le.region_code where le.ogrn is null .. code-block:: select le.short_name, rc.region_full_name from egrul.legalentity le cross join egrul.region_codes rc where rc.region_code = le.region_code .. _executing_regulated_queries: Выполнение регламентированных SQL-запросов -------------------------------------------- .. _executing_rules: Правила выполнения ~~~~~~~~~~~~~~~~~~~~~ Регламентированный SQL-запрос выполняется аналогично выполнению любого запроса к Витрине Поставщика данных. Описание синтаксиса выполнения запроса приведено в :numref:`sql_syntax` . Эта операция может быть выполнена: - с использованием REST-интерфейса в соответствии с :numref:`consumer_sql_rest_interface`. - с использованием JDBC-интерфейса в соответствии с :numref:`jdbc_interface` . Для выполнения необходимо составить SQL выражение, указав мнемонику Регламентированного SQL-запроса вместо таблицы. Формат Регламентированного SQL-запроса имеет вид: .. code-block:: select * from <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>(<параметры>) <дополнительные функции (опционально)> где: - <мнемоника Витрины> – для простых запросов (к одной Витрине) задается мнемоника соответствующей Витрины. Для распределенного запроса вместо мнемоники Витрины указывается префикс «podd»; - <версия Регламентированного SQL-запроса> – задается в формате «major.minor»; - <мнемоника Регламентированного SQL-запроса> – мнемоника вызываемого Регламентированного SQL-запроса; - <параметры> – указываются в скобках через запятую для Регламентированного SQL-запроса с параметрами, заданными в определении. Если выполняемый запрос не требует указания параметров, то скобки должны быть указаны пустыми. Если параметры не указаны в исходном запросе, но их значения по умолчанию присутствуют в загруженном определении, то они будут подставлены автоматически. - <дополнительные функции (опционально)> – дополнительные функции для обработки вызываемого Регламентированного SQL-запроса (например, группировка или лимит). .. attention:: если запрос не является аналитическим и необходимо получение результата выполнения в реальном времени (запросы граждан на портале ЕПГУ, предоставление услуг в МФЦ и т.п.), то обязательно указание лимита (limit) с минимально возможным значением (максимально допустимое значение зависит от конфигурации и настроек Витрины Поставщика, по умолчанию равно 1000): .. code-block:: POST «https://:/query?async=false» Accept-Version:1 Content-Type:application/x-www-form-urlencoded; encoding=utf-8 priority:NORMAL timeout:60 sql: select * from fias.1.0.addrobj_view('001') limit 10 Для упрощенного вызова Регламентированного SQL-запроса без использования дополнительных функций обработки (без надстроек) доступен формат вызова: - через REST-интерфейс в соответствии c :numref:`sync_broker_connect` с соответствующей пометкой; - через JDBC-интерфейс: .. code-block:: CALL <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>(<параметры>) **Правила указания параметров:** 1. Если параметры заданы в SQL-выражении Регламентированного SQL-запроса в виде «?», то при вызове они должны быть указаны в порядке, соответствующем определению Регламентированного SQL-запроса. Количество параметров при вызове должно соответствовать количеству параметров в определении Регламентированного SQL-запроса. 2. Для запроса, в SQL-выражении которого параметры заданы как именованные, доступен: 1. Вызов с использованием мнемоники именованного параметра. Для этого необходимо задать значения всех именованных параметров, для которых не задано значение по умолчанию, в виде "<мнемоника параметра>=><значение параметра>" (:numref:`original_query_transform`). Мнемоника именованного параметра при вызове запроса должна соответствовать мнемонике именованного параметра в определении Регламентированного SQL-запроса. Использование именованных параметров позволяет при вызове задавать значения параметров в любом порядке и только один раз, независимо от количества мест, где этот параметр используется в определении Регламентированного SQL-запроса. 2. Вызов без использования мнемоники именованного параметра. Для этого необходимо задать значения всех именованных параметров в порядке, соответствующем определению Регламентированного SQL-запроса. 3. Совместное использование именованных и неименованных параметров не допускается. .. _original_query_transform: Примеры вызова и преобразования исходного запроса ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Регламентированный SQL-запрос с параметрами без имени: .. code-block:: // Исходный запрос от Потребителя данных ПОДД СМЭВ: select * from oktmo.1.0.oktmo_view(‘Московская область’,7) // Определение Регламентированного SQL-запроса select id, whenadd, name, regionname, settlementtypename FROM oktmo.1.0.oktmo where regionname = ? AND settlementtypeid = ? // Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса: select id, whenadd, name, regionname, settlementtypename FROM oktmo.1.0.oktmo where regionname = ‘Московская область’ AND settlementtypeid = 7 2. Регламентированный SQL-запрос с именованными параметрами: .. code-block:: // Исходный запрос от Потребителя данных ПОДД СМЭВ (вызов через мнемонику параметра) select * from <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>(param=>'000', lim=>20) // Исходный запрос от Потребителя данных ПОДД СМЭВ select * from <мнемоника Витрины>.<версия Регламентированного SQL-запроса>.<мнемоника Регламентированного SQL-запроса>('000',20) // Определение Регламентированного SQL-запроса SELECT name, code FROM datamart.1.0.regions WHERE code=:param and id in (select id from :param) limit :lim // Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса: SELECT name, code FROM datamart.1.0.regions WHERE code='000' and id in (select id from '000') limit 20 3. Регламентированный SQL-запрос с параметром типа TIMESTAMP: .. code-block:: // Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к Pulsar select * from fias.1.0.addrobj_view('001', '000', TIMESTAMP '1970-01-01 00:00:00') // Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру CALL fias.1.0.addrobj_view('001', '000', TIMESTAMP '1970-01-01 00:00:00') // Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру с отдельным блоком параметров datamart: fias mnemonic: addrobj_view majorVersion: 1 minorVersion: 0 params:{ “type”: “STRING”, “value”:”001”},{ “type”: “STRING”, “value”:“002”},{ “type”: “TIMESTAMP”, “value”:“2007-12-03Т10:00:00.000Z”} // Определение РЗ SELECT oktmo, formalname, startdate, enddate FROM datamart.9.1.addrobj WHERE areacode=? and citycode=? and startdate<=? 4. Регламентированный SQL-запрос с параметром типа DATE: .. code-block:: // Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к Pulsar select * from fias.1.0.addrobj_view('001', '000', '1970-01-01') // Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру CALL fias.1.0.addrobj_view('001', '000', '1970-01-01') // Исходный запрос от Потребителя данных ПОДД СМЭВ при подключении к брокеру с отдельным блоком параметров datamart: fias mnemonic: addrobj_view majorVersion: 1 minorVersion: 0 params:{ “type”: “STRING”, “value”:”001”},{ “type”: “STRING”, “value”:“002”},{ “type”: “DATE”, “value”:“2007-12-03”} // Определение РЗ SELECT oktmo, formalname, startdate, enddate FROM datamart.9.1.addrobj WHERE areacode=? and citycode=? and startdate>=? 5. Регламентированный SQL-запрос без параметров: .. code-block:: // Исходный запрос от Потребителя данных ПОДД СМЭВ: select * from egrul.1.1.legalentity_view() // Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса: select ogrn, short_name, inn, kpp, region_code from egrul.2.legalentity 6. Распределенный Регламентированный SQL-запрос: .. code-block:: // Исходный запрос от Потребителя данных ПОДД СМЭВ: select * from podd.1.1.r_query(‘Москва’, 18) // Пример преобразования исходного запроса в соответствии с загруженным определением Регламентированного SQL-запроса: select ao.oktmo, o.name, o.kod from fias.1.0.addrobj ao LEFT JOIN oktmo.1.0.oktmo o on ao.oktmo = o.kod2 WHERE ao.offname= ‘Москва’ AND o.regionid = 18 .. _system_param_query: Выполнение запроса с системным параметром ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Системные параметры не описываются в определении Регламентированного SQL-запроса и могут быть заданы Потребителем для любого Регламентированного SQL-запроса при выполнении запроса. :numref:`tab_system_param_query` содержит поддерживаемые в ПОДД СМЭВ параметры. .. _tab_system_param_query: .. table:: Поддерживаемые в ПОДД СМЭВ параметры +---+------------------------------------------------+-------------------------------------------------------------------------------------+ | № | Мнемоника | Назначение | +===+================================================+=====================================================================================+ | 1 | settings_for_system_time | Системный параметр для получения актуальных на заданный момент данных. | | | | | | | | Позволяет указывать при вызове запроса момент времени, на который требуется | | | | получить актуальные данные из Витрины. | +---+------------------------------------------------+-------------------------------------------------------------------------------------+ | 2 | settings_for_system_time_started | Системный параметр для получения результата выполнения запроса с данными, | | | | добавленными за указанный диапазон времени. | | | | | | | | Позволяет указывать при вызове запроса диапазон номеров дельт, за который требуется | | | | получить измененные данные | +---+------------------------------------------------+-------------------------------------------------------------------------------------+ | 3 | settings_for_system_time_finished | Системный параметр для получения результата выполнения запроса с данными, | | | | удаленными за указанный диапазон времени. | | | | | | | | Позволяет указывать при вызове запроса диапазон номеров дельт, за который требуется | | | | получить удаленные данные | +---+------------------------------------------------+-------------------------------------------------------------------------------------+ Вызов Регламентированного SQL-запроса с системным параметром осуществляется аналогично вызову Регламентированного SQL-запроса с заданием значения для именованного параметра, в соответствии со следующими правилами: 1. Параметр задается в запросе только один раз в виде именованного параметра с соответствующей мнемоникой. 2. Значение параметра ``settings_for_system_time`` должно соответствовать формату ``YYYY-MM-DD hh:mm:ss``. 3. Значение параметров ``settings_for_system_time_started`` и ``settings_for_system_time_finished`` должно соответствовать формату (``int1``, ``int2``). Значение ``int1`` должно быть меньше, чем ``int2``. 4. Задание параметра недоступно при вызове Регламентированного SQL-запроса без SQL-выражения. 5. Для простого запроса: для Витрины, к которой обращается Регламентированный SQL-запрос с данным параметром, должна быть задана настройка поддержки обработки данного параметра в соответствии с «Руководством администратора ПОДД СМЭВ». [26]_ 6. Для распределенного запроса: для всех Витрин, к которым обращается Регламентированный SQL-запрос с данным параметром, должна быть задана настройка поддержки обработки данного параметра в соответствии с «Руководством администратора ПОДД СМЭВ». [26]_ 7. В подзапросе в блоке FROM должна отсутствовать конструкция «FOR SYSTEM_TIME». Пример вызова с параметром ``settings_for_system_time``: .. code-block:: // вызываемый SQL-запрос (вариант 1) select * from fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time=>'YYYY-MM-DD hh:mm:ss') // вызываемый SQL-запрос (вариант 2) select * from fias.1.0.addrobj_func(settings_for_system_time=>?, p1=>?, p2=>?) params: {"type": "TIMESTAMP", "value": "YYYY-MM-DD hh:mm:ss"},{"type": "STRING", "value": "001"},{"type": "STRING", "value": "002"} // SQL-выражение Регламентированного SQL-запроса SELECT <атрибуты> FROM <витрина>.<таблица> WHERE id=:p1 AND region=:p2 .. [26] Размещено на портале ЕСКС – https://info.gosuslugi.ru/ Пример вызова с параметрами ``settings_for_system_time_started`` и ``settings_for_system_time_finished``: .. code-block:: // вызываемый SQL-запрос (вариант 1) select * from fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time_started=>'122,124') select * from fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time_finished=>'122,124') // вызываемый SQL-запрос без настроек через JDBC-интерфейс call fias.1.0.addrobj_func(p1=>'000', p2=>'001', settings_for_system_time_started=>'122,124') // вызываемый SQL-запрос с параметрами, передаваемыми отдельным блоком select * from fias.1.0.addrobj_func(settings_for_system_time_finished=>?, p1=>?, p2=>?) params: {"type": "STRING", "value": "122,124"},{"type": "STRING", "value": "001"},{"type": "STRING", "value": "002"} // SQL-выражение РЗ SELECT <атрибуты> FROM <витрина>.<таблица> WHERE id=:p1 AND region=:p2 .. _consumer_tp_query: Выполнение запросов с использованием табличных параметров, передаваемых Потребителем данных для обогащения ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Выполнение запроса, включающего табличный параметр, осуществляется аналогично выполнению любого запроса к Витрине Поставщика данных. Описание синтаксиса выполнения запроса приведено в :numref:`sql_syntax`. Для выполнения запроса с табличным параметром необходимо: 1. Определить структуру таблицы, указанной в табличном параметре. 2. Указать запрос, содержащий табличный параметр. 3. Указать источник данных для табличного параметра. Эти операции могут быть выполнены с использованием REST или JDBC-интерфейса. .. _rest_interface_request: Запрос с использованием REST-интерфейса ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ При использовании REST-интерфейса данные собираются в CSV файл, который прикрепляется к запросу, содержащему информацию о структуре таблицы и SQL-выражение. Формат запроса приведен в :numref:`consumer_sql_async_request`. В теле запроса передаются следующие параметры: .. code-block:: sql:SELECT el.inn, er.region_name FROM @inns el LEFT JOIN egrul.2.region_codes er ON SUBSTRING(el.inn,1,2) = er.region_code priority:NORMAL tableParams:{“name”: “inns”, “columns”:[{“name”: “id”, “type”: “INTEGER”},{“name”: “inn”, “type”: “STRING”}]} inns: где: 1. sql – текст для вызова Регламентированного SQL-запроса, содержащего табличные параметры; 2. tableParams – описание передаваемого файла с данными для табличного параметра, где: - name – табличный параметр; - columns – перечень названий столбцов и их типов, содержащихся в файле с данными для табличного параметра. 3. inns – файл с данными для табличного параметра, где: - inns – табличный параметр (выступает в качестве названия параметра запроса); - <1.csv> – файл в формате CSV (поддерживаемый формат), передаваемый в параметре запроса. Пример CSV файла (разделитель – запятая): .. code-block:: 1, 4345310593 2, 4311003795 3, 4345336320 .. _jdbc_interface_query: Запрос с использованием JDBC-интерфейса ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ При использовании JDBC-интерфейса для описание передаваемой в качестве параметра таблицы и добавления данных расширяются функции драйвера JDBC. Для доступа к данным формируется итератор. После передачи данных выполняется запрос, включающий табличный параметр в формате ``@имя_параметра``. Пример использования представлен в :numref:`jdbc_driver`. .. _binary_objects_output: Получение двоичных объектов в результатах запроса ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ПОДД СМЭВ предоставляет возможность получения в качестве результата выполнения Регламентированных SQL-запросов: - скалярных параметров (значение которых представляет собой число, строку или дату); - двоичных объектов (соответствующих файлам, размещенным на Витринах Потребителей данных). Для получения в качестве ответа двоичных объектов необходимо выполнение следующих условий: - Витрина Поставщика данных поддерживает тип данных «двоичный объект»; - в метаданных Витрины Поставщика данных, зарегистрированной в ПОДД СМЭВ, для соответствующих атрибутов должен быть установлен тип данных «двоичный объект» (описание типов данных ПОДД СМЭВ приведено в :numref:`respondent_rest_services`). Процесс выполнения такого SQL-запроса приведён на рисунке 14, описание процесса приведено далее. 1. ИС Потребителя передаёт SQL-запрос в Агент СМЭВ4. 2. Далее приём, обработка и передача запроса: Агент Потребителя данных → Ядро ПОДД СМЭВ → Агент Поставщика данных → Витрина Поставщика данных осуществляется аналогично обычному информационному обмену с использованием Регламентированных SQL-запросов (:numref:`rz_exchange`). 3. Витрина данных осуществляет обработку запроса и возвращает ответ. В случае выполнения запроса, результат которого содержит атрибуты с типом данных «двоичный объект», в составе результата запроса атрибут может принимать одно из следующих возможных значений: - непосредственно сам двоичный объект; - уникальная ссылка на получение двоичного объекта с Витрины Поставщика данных (см. шаги :numref:`img_blob_output`). Решение о том какое значение будет передано (объект или ссылка на него принимается Витриной данных). 4. Далее ответ доставляется до ИС Потребителя аналогично обычному обмену (:numref:`rz_exchange`). Пример возврата двоичного объекта и ссылки на двоичный объект приведен в :numref:`sync_response`. 5. Если в результате выполнения запроса передана ссылка, то для получения двоичного объекта ИС Потребителя направляет запрос на получение вложения по ссылке, которую получил в ответе. Запрос двоичного объекта по ссылке считается отдельным обменом, идентификатор обмена (requestId) запроса по ссылке уникальный (в случае нескольких ссылок - уникальный для каждой из ссылок). Описание запроса на получение двоичного объекта по ссылке: - через REST-интерфейс приведено п :numref:`consumer_tp_request`; - через JDBC-интерфейс приведено далее. 6. Далее приём, обработка и передача запроса Агент Потребителя данных → Ядро ПОДД СМЭВ → Агент Поставщика данных → Витрина Поставщика данных осуществляется аналогично обычному обмену (:numref:`rz_exchange`). Для передачи запроса двоичного объекта на Витрину Поставщика используется специальный топик ``blob.rq``. 7. В случае, если в теле запроса содержится ссылка на двоичный объект: - Адаптер PODD Витрины данных отправляет запрос в BLOB-адаптер на получение этого файла. - BLOB-адаптер, считывает ссылку на двоичный объект и обращается в Хранилище BLOB-объектов на стороне Ведомства. - После получения двоичного объекта, возвращает его в ПОДД СМЭВ. Для передачи ответа на запрос двоичного объекта от Витрины Поставщика данных используется специальные топики ``blob.rs`` и ``blob.err``. 8. ПОДД СМЭВ передает ИС Потребителя данных двоичный объект (файл), организуя двоичный поток между Витриной Поставщика данных и ИС Потребителя данных. В процессе передачи Агент Поставщика данных разбивает поток данных на сегменты (чанки) и подписывает каждый сегмент подписью Поставщика данных. Перед передачей данных Потребителю данных подпись проверяется Ядром ПОДД СМЭВ. Пример программного кода для JDBC-драйвера, реализующего получение двоичного объекта: .. code-block:: package dev.nsud.jdbc import org.junit.jupiter.api.Test import java.sql.Connection import java.sql.DriverManager import org.junit.jupiter.api.Assertions import java.sql.SQLException class Features { private getConnectionURI() { val host = System.getProperty(“agent.host”, “localhost”) val port = System.getProperty(“agent.port”, “8182”) return “jdbc:podd://$host:$port” } @Test fun `ожидается успешное соединение с базой данных`() { Assertions.assertDoesNotThrow { DriverManager.getConnection(getConnectionURI()) } } @Test fun `ожидается успешное получение бинарных данных `() { Assertions.assertDoesNotThrow { val expect = getExpectedBytes() val con = DriverManager.getConnection(getConnectionURI()) val statement = con.createStatement() statement.executeQuery(“select binaryColumn from datamart.table where id=1”) val resultSet = statement.resultSet Assertions.assertEquals(expect, resultSet.getBlob(0)) } } } .. _img_blob_output: .. figure:: img/img_blob_output.png :align: center :alt: Информационный обмен при выполнении запроса с использованием ПОДД СМЭВ Информационный обмен при выполнении запроса с использованием ПОДД СМЭВ .. _printable_form_output: Получение печатной формы в результатах запроса ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Запросы для получения печатной формы в результатах запроса не содержат SQL-выражения в определении Регламентированного SQL-запроса и являются процедурами, выполняемыми на стороне Витрины. Вызов запроса от ИС Потребителя аналогичен вызову обычного Регламентированного SQL-запроса. Приём, обработка и передача запроса по пути Агент Потребителя данных → Ядро ПОДД СМЭВ → Агент Поставщика данных осуществляется аналогично обычному информационному обмену с использованием Регламентированных SQL-запросов (:numref:`rz_exchange`). Особенностью обработки запросов является добавление Агентом Поставщика данных алиаса сертификата в запрос, согласно настройкам, заданным в соответствии с Руководством администратора ПОДД СМЭВ [27]_, для последующей подписи печатной формы. .. _rest_service_output: Выполнение запросов к REST-сервису ИС Ответчика --------------------------------------------------- Для выполнения запроса к REST-сервису ИС Ответчика необходимо: 1. Определить доступные REST-сервисы. 2. Составить URI запроса в соответствии со спецификацией OpenAPI зарегистрированного REST-сервиса ИС Ответчика, загруженной в ПОДД СМЭВ. URI запроса формируется путём конкатенации мнемоники Агента ПОДД Ответчика, префикса в URL (basePath) соответствующего REST-сервиса ИС Ответчика и path операции. Сформированный запрос должен совпадать с запросом из спецификации OpenAPI. Формат запроса для обмена с использованиям REST-сервиса ИС Ответчика имеет вид: .. code-block:: <адрес>:<порт>/ где: - HTTP-метод – метод из поддерживаемых REST-сервисом; - <адрес> – IP-адрес Агента Инициатора; - <порт> – порт для обращения Агента Инициатора к Ядру ПОДД СМЭВ в соответствии с Руководством администратора ПОДД СМЭВ [27]_; - systemMnemonic – мнемоника Агента Ответчика, на стороне которого развернут REST-сервис; - basePath – префикс в URL соответствующего REST-сервиса ИС Ответчика; - path – путь операции, указанный в спецификации OpenAPI соответствующего REST-сервиса ИС Ответчика. Пример URI запроса соответствует примеру спецификации OpenAPI, приведенному в :numref:`respondent_rest_services` данного документа: .. code-block:: GET 10.81.4.30:29164/agent-oktmo/region-service/region/123 Выполнение запросов осуществляется через REST-интерфейс Агента СМЭВ4 (см. :numref:`consumer_tp_request` данного документа). .. [27] Размещен на портале ЕСКС – https://info.gosuslugi.ru/ .. _request_identification: Сквозная идентификация запросов ----------------------------------- Для диагностики проблем возникающих в ходе информационных обменов через ПОДД СМЭВ в части отслеживания всей цепочки сообщений, возникающих в ходе информационного обмена обеспечена сквозная идентификация запросов. Сквозная идентификация в ПОДД СМЭВ основывается на идентификаторах, приведённых в :numref:`tab_identifiers_types`. На :numref:`img_sql_request_identification`, :numref:`img_rest_request_identification` и :numref:`img_distribution_request_identification` приведён порядок возникновения этих идентификаторов. .. _tab_identifiers_types: .. table:: Виды идентификаторов ПОДД СМЭВ +---+------------------------------+--------------------------+-----------------------------------------------+ | № | Вид | Код | Источник идентификатора | +===+==============================+==========================+===============================================+ | 1 | Клиентский идентификатор | clientRequestId | Инициатор обмена | | | | | | | | (идентификатор клиента) | | | +---+------------------------------+--------------------------+-----------------------------------------------+ | 2 | Идентификатор обмена | requestId | ПОДД СМЭВ при получении запроса на: | | | | | | | | (идентификатор процесса) | | - информационный обмен (например, | | | | | выполнение регламентированного SQL-запроса) | | | | | | | | | | - процесс (например, регистрации подписки) | +---+------------------------------+--------------------------+-----------------------------------------------+ | 3 | Идентификатор подзапроса | subRequestId | ПОДД СМЭВ | | | ПОДД СМЭВ – Витрина | | | +---+------------------------------+--------------------------+-----------------------------------------------+ | 4 | Идентификатор подзапроса | dataRequestId | Адаптер Витрины | | | Адаптер – Prostore | | | +---+------------------------------+--------------------------+-----------------------------------------------+ .. _img_sql_request_identification: .. figure:: img/img_sql_request_identification.png :align: center :alt: Сквозная идентификация запросов для информационного обмена с использованием регламентированных SQL-запросов Сквозная идентификация запросов для информационного обмена с использованием регламентированных SQL-запросов .. _img_rest_request_identification: .. figure:: img/img_rest_request_identification.png :align: center :alt: Сквозная идентификация запросов для информационного обмена с использованием запросов к REST-сервису ИС Ответчика Сквозная идентификация запросов для информационного обмена с использованием запросов к REST-сервису ИС Ответчика .. _img_distribution_request_identification: .. figure:: img/img_distribution_request_identification.png :align: center :alt: Сквозная идентификация запросов для информационного обмена с использованием Рассылок Сквозная идентификация запросов для информационного обмена с использованием Рассылок **Правила использования клиентского идентификатора** 1. Клиентский идентификатор опционален. *Исключение из правила* – УВ явно добавил обязательное поле ClientRequestID в спецификацию OpenAPI для информационного обмена с использованием Регламентированных REST-запросов. В данном случае, валидация осуществляется в соответствии со спецификацией. 2. Клиентский идентификатор должен соответствовать стандарту UUID. 3. Ответственность за используемый формат несёт инициатор обмена. ПОДД не осуществляет проверку по формату и версиям UUID. Исключение из правила – УВ явно добавил поле ClientRequestID в спецификацию OpenAPI для информационного обмена с использованием Регламентированных REST-запросов. В данном случае, валидация осуществляется в соответствии со спецификацией. 4. Допустимо использовать один клиентский идентификатор для связывания нескольких запросов. ПОДД СМЭВ не осуществляет проверку на уникальность. 5. Способ передачи клиентского идентификатора приведён в :numref:`consumer_protocol`. .. _limiting_requests: Лимитирование регламентированных запросов Потребителя к информационным ресурсам Поставщика ------------------------------------------------------------------------------------------ .. _limiting: Лимиты ~~~~~~ Для защиты Поставщиков от избыточных запросов Потребителей обеспечена возможность лимитирования запросов к Поставщику данных от конкретного Потребителя данных для информационных обменов с использованием регламентированных запросов. Лимит может быть установлен на следующие информационные ресурсы Поставщика: - на конкретный Регламентированный SQL-запрос; - на все Регламентированные SQL-запросы к конкретной Витрине; - на конкретный Регламентированный REST-запрос (спецификацию OpenAPI ИС Поставщика); - общий на все Регламентированные SQL и REST-запросы от ИС Потребителя к ИС Поставщика. Лимит может быть следующих типов: - на Количество запросов; - на Размер запросов; - на Размер ответов. При создании лимита указывается его значение (количество или размер) и период (у которого два назначения – период контроля соблюдения значения и период блокировки). .. _limiting_conditions: Условия для добавления лимитов ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. В ПОДД должны быть зарегистрированы ИС Поставщика и ИС Потребителя; 2. Если лимит задаётся на Витрину в ПОДД СМЭВ должны быть: - зарегистрирована Витрина; - Витрина связана с ИС Поставщика; 3. Если лимит задаётся на конкретный Регламентированный SQL-запрос, в ПОДД СМЭВ должны быть: - зарегистрирована Витрина; - Витрина связана с ИС Поставщика; - выданы права ИС Потребителя на Регламентированный SQL-запрос. 4. Если лимит задаётся на конкретную спецификацию OpenAPI в ПОДД СМЭВ должны быть: - зарегистрирована спецификация OpenAPI; - выданы права ИС Инициатора на спецификацию OpenAPI. 5. При выставлении лимитов недопустимо совмещение: - общего на все Регламентированные SQL и REST-запросы ИС Потребителя к ИС Поставщика лимита и лимита на другие ресурсы; - лимита на Витрину и лимита на Регламентированный SQL-запрос к этой Витрине. 6. Лимит на конкретный Регламентированный SQL-запрос ограничивает запросы Потребителя по всем версиям этого запроса. 7. Лимит на все Регламентированные SQL-запросы к конкретной Витрине ограничивает запросы Потребителя по всем версиям модели этой Витрины. 8. При установке лимита на Витрину и ИС также могут учитываться произвольные SQL-запросы. Реализация исключения таких запросов из процесса лимитирования не предусмотрена, так как права доступа на выполнение произвольных SQL-запросов предоставляются автоматически и только владельцам Витрин на их собственные Витрины. .. _blocking: Блокировки ~~~~~~~~~~ В случае превышения лимитов, заданных Поставщиком, ПОДД СМЭВ блокирует Потребителю доступ к соответствующему информационному ресурсу. Например, если для ИС Потребителя указано два лимита к двум Регламентированным SQL-запросам и заблокирован доступ к одному из них, она может продолжить пользоваться другим доступным запросом. При получении запроса от заблокированного Потребителя, ПОДД СМЭВ возвращает ответ с соответствующей ошибкой. Блокировка снимается: - при истечении времени блокировки; - при удалении соответствующего лимита; - при редактировании соответствующего лимита (любых атрибутов кроме наименования); - при получении запроса на принудительное снятие блокировки. .. _blocking_limit_manage: Управление лимитами и блокировками ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Управление лимитами и блокировками доступно из ЛК УВ. .. _limiting_algorithm: Алгоритм лимитирования ~~~~~~~~~~~~~~~~~~~~~~ Лимитирование осуществляется в соответствии со следующим алгоритмом (:numref:`img_limiting_algorithm`): 1. ПОДД СМЭВ формирует окна наблюдения от 1 января 1970 годя 00:00:00.000 в соответствии с указанным значением периода лимита. 2. ПОДД СМЭВ хранит в памяти значение счётичка предыдущего и текущего окна наблюдения. После разблокировки значения счётчиков обнуляются. 3. ПОДД СМЭВ вычисляет счётчик инкрементируя значение при каждом полученном запросе. 4. ПОДД СМЭВ принимает решение о блокировке на основании имеющихся счётчиков: - Если значение предыдущего окна наблюдения нет, то берётся значение инкрементированного счётчика текущего окна. - Если полученное значение меньше значения лимита, то запрос будет обработан. - Если значение предыдущего окна наблюдения есть, то ПОДД СМЭВ вычисляет коэффициенты наложения окна наблюдения на интервалы по формуле: .. code-block:: K = N + M * R где: - N - количество запросов в текущем интервале (с учетом полученного), - M - количество запросов на предыдущем интервале, - R - коэффициент наложения на предыдущий интервал (0...1). - Если полученное значение меньше значения лимита, то запрос будет обработан. Пример: .. code-block:: Установлен лимит: 4 запроса в минуту С 0 до 0:59 - пришло 5 запросов, В 1:30 - пришёл ещё один запрос результат вычисления: - N = 1, - M = 5, - R = (90 - 60) / 60 = 0.5 K = 1 + 5 * 0.5 = 3.5 меньше предельного, запрос будет обработан. .. _img_limiting_algorithm: .. figure:: img/img_limiting_algorithm.png :align: center :alt: Алгоритм лимитрирования запросов Алгоритм лимитрирования запросов