Postgres 8.4及更高版本的数据库包含public
模式中的公共表和company
模式中的公司特定表。
company
模式名称始终以'company'
开头,以公司编号结束。
所以可能有以下模式:
public
company1
company2
company3
...
companynn
应用程序始终适用于单个公司。
search_path
在odbc或npgsql连接字符串中相应指定,如:
search_path='company3,public'
您如何检查指定的companyn
架构中是否存在给定的表?
例如:
select isSpecific('company3','tablenotincompany3schema')
应该返回false
,和
select isSpecific('company3','tableincompany3schema')
应该返回true
。
在任何情况下,该函数应仅检查传递的companyn
模式,而不是其他模式。
如果public
和传递的模式中都存在给定的表,则该函数应返回true
。
它适用于Postgres 8.4或更高版本。
这取决于你想要准确测试的内容。
要查找“表是否存在”(无论是谁在询问),严格来说,查询信息模式(information_schema.tables
)是不正确的,因为(per documentation):
仅显示当前用户可以访问的那些表和视图(通过作为所有者或具有某些特权)。
查询demonstrated by @kong可以返回FALSE
,但表仍然可以存在。它回答了这个问题:
如何检查表(或视图)是否存在,以及当前用户是否可以访问它?
SELECT EXISTS (
SELECT 1
FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
信息模式主要用于在主要版本和不同RDBMS之间保持可移植性。但实施速度很慢,因为Postgres必须使用复杂的视图来遵守标准(information_schema.tables
是一个相当简单的例子)。并且一些信息(如OID)在系统目录的翻译中丢失 - 实际上包含所有信息。
你的问题是:
如何检查表是否存在?
SELECT EXISTS (
SELECT 1
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
AND c.relkind = 'r' -- only tables
);
直接使用系统目录pg_class
和pg_namespace
,这也快得多。但是,per documentation on pg_class
:
目录
pg_class
编目表和大多数具有列或其他类似于表的其他所有内容。这包括索引(但也参见pg_index
),序列,视图,物化视图,复合类型和TOAST表;
对于这个特殊问题,您也可以使用system view pg_tables
。主要的Postgres版本更简单,更便携(这个基本查询几乎不关心):
SELECT EXISTS (
SELECT 1
FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
标识符必须在上面提到的所有对象中是唯一的。如果你想问:
如何检查给定模式中的表或类似对象的名称是否被采用?
SELECT EXISTS (
SELECT 1
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
);
regclass
SELECT 'schema_name.table_name'::regclass
如果(可选的模式限定的)表(或占用该名称的其他对象)不存在,则会引发异常。
如果您没有对表名进行模式限定,则对regclass
的强制转换默认为search_path
并返回找到的第一个表的OID - 如果表中没有列出的模式,则返回异常。请注意,系统模式pg_catalog
和pg_temp
(当前会话的临时对象的模式)自动成为search_path
的一部分。
您可以使用它并在函数中捕获可能的异常。例:
像上面这样的查询可以避免可能的异常,因此会稍快一些。
to_regclass(rel_name)
9.4+现在简单得多:
SELECT to_regclass('schema_name.table_name');
与演员一样,but it returns ...
...如果找不到名称,则为null而不是抛出错误
也许使用information_schema:
SELECT EXISTS(
SELECT *
FROM information_schema.tables
WHERE
table_schema = 'company3' AND
table_name = 'tableincompany3schema'
);
我的旧瑞士刀库的三种口味:qazxsw poi,qazxsw poi和qazxsw poi。所有来自pg_catalog.pg_class表的检查,并返回标准通用数据类型(boolean,text或text [])。
relname_exists(anyThing)