代码之家  ›  专栏  ›  技术社区  ›  jsight TaherT

如何通过plpgsql从postgres获取表的主键?

  •  33
  • jsight TaherT  · 技术社区  · 15 年前

    给定一个表名,如何从plpgsql函数中提取主键列及其数据类型的列表?

    7 回复  |  直到 6 年前
        1
  •  26
  •   user3094383    11 年前

    上面的查询非常糟糕,因为它非常慢。

    我建议这个官方版本:

    http://wiki.postgresql.org/wiki/Retrieve_primary_key_columns

    如果需要模式,查询如下

    SELECT               
      pg_attribute.attname, 
      format_type(pg_attribute.atttypid, pg_attribute.atttypmod) 
    FROM pg_index, pg_class, pg_attribute, pg_namespace 
    WHERE 
      pg_class.oid = 'foo'::regclass AND 
      indrelid = pg_class.oid AND 
      nspname = 'public' AND 
      pg_class.relnamespace = pg_namespace.oid AND 
      pg_attribute.attrelid = pg_class.oid AND 
      pg_attribute.attnum = any(pg_index.indkey)
     AND indisprimary
    
        2
  •  16
  •   Dale K    6 年前

    要直接提供一点SQL,可以使用以下命令列出主键列及其类型:

    SELECT c.column_name, c.data_type
    FROM information_schema.table_constraints tc 
    JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name) 
    JOIN information_schema.columns AS c ON c.table_schema = tc.constraint_schema
      AND tc.table_name = c.table_name AND ccu.column_name = c.column_name
    WHERE constraint_type = 'PRIMARY KEY' and tc.table_name = 'mytable';
    
        3
  •  5
  •   Milen A. Radev    13 年前

    看一看 pg_constraint 系统表。或 information_schema.table_constraints 查看您是否喜欢接近SQL标准。

    对于完整的示例,请使用 psql 带有“-e”选项和类型 \d <some_table> -您将看到描述表时使用的实际查询。

        4
  •  5
  •   cmaher MSeifert    6 年前

    以下 SQL 声明对我有效:

    SELECT a.attname
    FROM   pg_index i
    JOIN   pg_attribute a ON a.attrelid = i.indrelid
                         AND a.attnum = ANY(i.indkey)
    WHERE  i.indrelid = 'tablename'::regclass
    AND    i.indisprimary;
    

    它是直接从 here .

        5
  •  1
  •   jamesvl    10 年前

    注意索引中的列顺序与表的列顺序不同。(例如,如果主键使用了列3、2和1)

    下面的查询要复杂得多,但以正确的顺序返回列。(删除“unimprimary”子句以获取表上所有索引的相同信息)

    WITH ndx_list AS
    (
        SELECT pg_index.indexrelid
          FROM pg_index, pg_class
         WHERE pg_class.relname = 'test_indices_table'
           AND pg_class.oid = pg_index.indrelid
           AND pg_index.indisprimary
    ), ndx_cols AS
    (
       SELECT pg_class.relname AS index_name, UNNEST(i.indkey) AS col_ndx, i.indisunique, i.indisprimary
         FROM pg_class, pg_index i
        WHERE pg_class.oid = i.indexrelid
          AND pg_class.oid IN (SELECT indexrelid FROM ndx_list)
    )
      SELECT ndx_cols.index_name, ndx_cols.indisunique, ndx_cols.indisprimary,
             a.attname, format_type(a.atttypid, a.atttypmod), a.attnum
        FROM pg_class c, pg_attribute a
        JOIN ndx_cols ON (a.attnum = ndx_cols.col_ndx)
       WHERE c.oid = 'test_indices_table'::regclass
         AND a.attrelid = c.oid
    
        6
  •  0
  •   snipsnipsnip    8 年前

    使用保留列顺序 generate_subscripts :

    SELECT
      a.attname,
      format_type(a.atttypid, a.atttypmod) 
    FROM
      pg_attribute a
      JOIN (SELECT *, GENERATE_SUBSCRIPTS(indkey, 1) AS indkey_subscript FROM pg_index) AS i
        ON
          i.indisprimary
          AND i.indrelid = a.attrelid
          AND a.attnum = i.indkey[i.indkey_subscript]
    WHERE
      a.attrelid = 'your_table'::regclass
    ORDER BY
      i.indkey_subscript
    
        7
  •  0
  •   user2553316 Ns    6 年前
    SELECT
       conrelid::regclass AS table_from,
       conname,
       pg_get_constraintdef ( c.oid )
    FROM
       pg_constraint c
       JOIN pg_namespace n ON n.oid = c.connamespace
    WHERE
       contype IN ( 'f', 'p ' )
       AND conrelid::regclass::TEXT IN ( 'foo' )
    
    ORDER BY
       conrelid::regclass::TEXT,
       contype DESC