В чем разница между SPECIFIC_SCHEMA и ROUTINE_SCHEMA в INFORMATION_SCHEMA.ROUTINES?

INFORMATION_SCHEMA.ROUTINES содержит эти два столбца:

SPECIFIC_SCHEMA: Specific name of the schema.
ROUTINE_SCHEMA: Name of the schema that contains this function.

technet doc

Для SPECIFIC_ и ROUTINE_ версии CATALOG и NAME определены как эквивалентные (-специальное имя каталога. Это имя совпадает с ROUTINE_CATALOG.-), но эта формулировка для SCHEMA-

В чем разница между SPECIFIC_SCHEMA и ROUTINE_SCHEMA?

[Edit: Видимо, спустя 3 года это обозначается как дубликат, поэтому я должен уточнить. Предлагаемый дубликат - это разные поля, поэтому я не верю, что это дубликат.]

Ответ 1

Ну, это немного напоминает обратную совместимость.

Сам INFORMATION_SCHEMA используется для упрощения миграции версий сервера и упрощения. Я приведу примеры на основе SQL Server.

Вы можете захотеть (или, может быть, понадобиться) использовать таблицу sys.objects, которая в основном предоставляет почти все ту же информацию, которая была доставлена ​​INFORMATION_SCHEMA.ROUTINES. Фактически вам нужно использовать его, если вы действительно хотите узнать имя реальной схемы для процедуры - поскольку Microsoft уже заявляет о себе в docs. Но если вам нужно создать продукт, который просто хочет получить некоторую базовую информацию, например, если существует обычная программа или что-то в этом роде, вы не пойдете и не возьмете sys.objects, это может измениться с версии сервера на сервер. Это затрудняет поддержание. INFORMATION_SCHEMA в основном остается таким же во многих версиях. Только небольшие изменения будут применены, а работа под представлением будет изменена Microsoft. Это означает, что у вас есть стабильный код в течение многих лет и много разных версий сервера.

Это может быть тот факт, что есть два столбца с одним и тем же определением и, следовательно, с тем же содержимым. Это то же самое, что и SPECIFIC_NAME и ROUTINE_NAME или SPECIFIC_CATALOG и ROUTINE_CATALOG. Они в основном те же, что и Microsoft в своих документах.

Это может быть реликт, который может остаться там навсегда, только для совместимости с другим кодом СУБД или более старыми версиями самого SQL Server.

Кстати, Postgres имеют те же две строки, которые содержат один и тот же контент.

Ответ 2

Это для перегрузки. И этот вопрос является дубликатом этого вопроса здесь.

По существу, вы можете перегрузить функцию только в одной схеме в спецификации SQL.

Перегрузка и поиск.

Возьмем, например, ST_Union, который вы можете увидеть с документами с подписями здесь и здесь

SELECT specific_catalog, specific_schema, specific_name, routine_catalog, routine_schema, routine_name
FROM information_schema.routines
WHERE routine_name = 'st_union';
 specific_catalog | specific_schema |  specific_name  | routine_catalog | routine_schema | routine_name 
------------------+-----------------+-----------------+-----------------+----------------+--------------
 test             | public          | st_union_259584 | test            | public         | st_union
 test             | public          | st_union_259621 | test            | public         | st_union
 test             | public          | st_union_259622 | test            | public         | st_union
 test             | public          | st_union_260448 | test            | public         | st_union
 test             | public          | st_union_260450 | test            | public         | st_union
 test             | public          | st_union_260452 | test            | public         | st_union
 test             | public          | st_union_260454 | test            | public         | st_union
 test             | public          | st_union_260456 | test            | public         | st_union
(8 rows)

Здесь вы можете видеть, что ST_Union перегружается 8 раз. То, что вы не видите, - это почему: некоторые из них являются агрегатами, некоторые из них принимают rasters и другие geometry. Точка, вы вызываете ST_Union в зависимости от того, что вы называете ее, вы можете получить st_union_260454 или st_union_259621 или любой другой.

Catch is, SQL позволяет вам получить другую в зависимости от схемы, в которую вы ее вызываете.

SELECT current_schema;

Возвращает public. Это первая схема в моем search_path. Я могу создать sub, который предоставляет 9-й ST_Union, но тот, который работает только внутри схемы foobar. Это обеспечит 9-ю перегрузку рутин_имя ST_Union. Это сделало бы вышеприведенное возвращение что-то вроде этого...

SELECT specific_catalog, specific_schema, specific_name, routine_catalog, routine_schema, routine_name
FROM information_schema.routines
WHERE routine_name = 'st_union';
 specific_catalog | specific_schema |  specific_name  | routine_catalog | routine_schema | routine_name 
------------------+-----------------+-----------------+-----------------+----------------+--------------
 test             | public          | st_union_259584 | test            | public         | st_union
 test             | public          | st_union_259621 | test            | public         | st_union
 test             | public          | st_union_259622 | test            | public         | st_union
 test             | public          | st_union_260448 | test            | public         | st_union
 test             | public          | st_union_260450 | test            | public         | st_union
 test             | public          | st_union_260452 | test            | public         | st_union
 test             | public          | st_union_260454 | test            | public         | st_union
 test             | public          | st_union_270456 | test            | foobar         | st_union
(9 rows)
  • Если мой search_path просто foobar, тогда подпись лучше соответствует типам st_union_270456
  • Если мой search_path равен foobar,public, то либо foobar переопределяет подпрограмму в public, либо не предоставляет подпрограмму public.

CURRENT_SCHEMA - это только первая схема в search_path для PostgreSQL. PostgreSQL распространяется на спецификацию, разрешая вам разрешать вещи в нескольких схемах.