如何检查给定模式中是否存在表格
Postgres 8.4和更高版本的数据库包含public
模式中的公用表和公司模式中的公司特定表中的公用表。
company
模式名称始终以'company'
开头,并以公司编号结尾。
所以可能有图式:
public company1 company2 company3 ... companynn
一个应用程序总是与一家公司合作。
search_path
在odbc或npgsql连接string中相应地指定,如:
search_path='company3,public'
如何检查给定的表是否存在于指定的companyn
模式中?
select isSpecific('company3','tablenotincompany3schema')
应该返回false
,并且
select isSpecific('company3','tableincompany3schema')
应该返回true
。
在任何情况下,函数应该只检查通过的companyn
模式,而不是其他模式。
如果给定的表存在public
模式和传递模式,则该函数应该返回true
。
它应该适用于Postgres 8.4或更高版本。
这取决于你想要testing的东西。
信息架构?
为了find“表是否存在”( 无论谁在问 ),查询信息模式( information_schema.tables
)是不正确的 ,严格地说,因为( 每个文档 ):
只有那些表格和视图显示当前用户有权访问(作为拥有者或拥有某种特权)。
@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
,这也相当快。 但是, 每个关于pg_class
文档 :
目录
pg_class
目录表和大多数其他所有有列或类似于一个表。 这包括索引 (但也参见pg_index
), 序列 , 视图 , 物化视图 , 复合types和TOAST表 ;
对于这个特定的问题,你也可以使用系统视图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' );
- 关于dba.SE讨论“信息模式与系统目录”相关的问题
另类:投给regclass
SELECT 'schema_name.table_name'::regclass
如果(可选的模式限定的)表(或其他占据该名称的对象)不存在,则会引发exception 。
如果您没有对表名称进行模式限定,那么对regclass
进行regclass
默认为search_path
并返回find的第一个表的OID;如果表不在列出的模式中,则返回exception。 请注意,系统模式pg_catalog
和pg_temp
(当前会话的临时对象的模式)自动成为search_path
一部分。
你可以使用它并捕获函数中可能的exception。 例:
- 检查Postgres(plpgsql)中是否存在序列
像上面这样的查询避免了可能的exception,因此速度稍快。
Postgres 9.4+中的to_regclass(rel_name)
现在更简单了:
SELECT to_regclass('schema_name.table_name');
与演员阵容相同, 但会返回…
如果找不到该名称,则返回null而不是抛出错误
也许使用information_schema :
SELECT EXISTS( SELECT * FROM information_schema.tables WHERE table_schema = 'company3' AND table_name = 'tableincompany3schema' );