В чем разница между 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 распространяется на спецификацию, разрешая вам разрешать вещи в нескольких схемах.