64

PostgreSQL 中是否有一个简单的替代方法来替代 Oracle 中生成的此语句?

select table_name from user_tab_columns
where table_name = myTable and column_name = myColumn;

然后我正在测试查询是否返回任何内容以证明该列存在。

我知道使用 psql 我可以单独找到这些,但这是在我正在编写的程序中生成结果以验证我的数据库表中是否存在请求的属性字段所必需的。

4

6 回答 6

130

尝试这个 :

SELECT column_name 
FROM information_schema.columns 
WHERE table_name='your_table' and column_name='your_column';
于 2012-04-03T10:05:08.180 回答
46

Accepted answer is correct, but is missing the schema and nicer output (True/False):

SELECT EXISTS (SELECT 1 
FROM information_schema.columns 
WHERE table_schema='my_schema' AND table_name='my_table' AND column_name='my_column');
于 2015-12-29T20:33:29.290 回答
21

使用 PostgreSQL 的对象标识符类型,这更简单(并且 SQLi 安全):

SELECT TRUE
FROM   pg_attribute 
WHERE  attrelid = 'myTable'::regclass  -- cast to a registered class (table)
AND    attname = 'myColumn'
AND    NOT attisdropped  -- exclude dropped (dead) columns
-- AND attnum > 0        -- exclude system columns (you may or may not want this)

阅读手册中各列的意义

如果您正在构建动态 SQL 并且您的列名作为参数提供,您可能希望使用它quote_ident()来避免 SQL 注入:

...
AND    attname = quote_ident('myColumn');

也适用于 之外的表search_path

...
WHERE  attrelid = 'mySchema.myTable'::regclass
...
于 2012-04-03T22:29:05.430 回答
5

与 Oracle 不同,PostgreSQL 支持 ANSI 标准INFORMATION_SCHEMA视图。

Oracle 的 user_tab_columns 对应的标准视图是information_schema.columns

http://www.postgresql.org/docs/current/static/infoschema-columns.html

于 2012-04-03T10:04:23.087 回答
3
SELECT attname 
FROM pg_attribute 
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'YOURTABLENAME') 
AND attname = 'YOURCOLUMNNAME';

当然,请将YOURTABLENAMEYOURCOLUMNNAME替换为适当的值。如果返回一行,则具有该名称的列存在,否则不存在。

于 2012-04-03T10:04:06.320 回答
2

这是 Erwin Brandstetter 答案的类似变体。在这里我们也检查模式,以防我们在不同模式中有类似的表。

SELECT TRUE FROM pg_attribute 
WHERE attrelid = (
    SELECT c.oid
    FROM pg_class c
    JOIN pg_namespace n ON n.oid = c.relnamespace
    WHERE 
        n.nspname = CURRENT_SCHEMA() 
        AND c.relname = 'YOURTABLENAME'
    )
AND attname = 'YOURCOLUMNNAME'
AND NOT attisdropped
AND attnum > 0
于 2016-10-10T04:41:27.083 回答