2016-04-15 2 views
0

Для данной таблицы я пытаюсь получить все столбцы, чтобы включить их имя, тип, является ли столбец первичным ключом или внешним ключом, и если это FK, в какой таблице он указывает. Я написал ниже запрос, но это, кажется, дать мне то, что столбцы ссылаются, а не наоборот:Как получить таблицу, на которую ссылается FK в Postgres sql

select c.column_name, c.udt_name, constraint_type, kcu.table_name as references from information_schema.columns c 
left outer join information_schema.constraint_column_usage u on c.column_name=u.column_name 
left outer join information_schema.table_constraints t on u.constraint_name=t.constraint_name 
left outer join information_schema.key_column_usage AS kcu on t.constraint_name = kcu.constraint_name 
where [email protected] 

Я не слишком беспокоюсь о случаях края, я просто пытаюсь инвертировать столбец ссылок. Спасибо за ваше время.

ответ

1

Вот запрос, чтобы получить все внешние ключи из данной таблицы наряду с тем, что они указывают на:

SELECT c.conname, 
     t1.relname AS from_table, 
     a1.attname AS from_column, 
     t2.relname AS to_table, 
     a2.attname AS to_column 
FROM pg_catalog.pg_constraint c, 
     pg_catalog.pg_class t1, 
     pg_catalog.pg_class t2, 
     pg_catalog.pg_attribute a1, 
     pg_catalog.pg_attribute a2, 
     pg_catalog.pg_namespace n1, 
     pg_catalog.pg_namespace n2 
WHERE c.conrelid = t1.oid 
AND  c.confrelid = t2.oid 
AND  c.contype = 'f' 
AND  a1.attrelid = t1.oid 
AND  a1.attnum = ANY(c.conkey) 
AND  a2.attrelid = t2.oid 
AND  a2.attnum = ANY(c.confkey) 
AND  t1.relkind = 'r' 
AND  t2.relkind = 'r' 
AND  n1.oid = t1.relnamespace 
AND  n2.oid = t2.relnamespace 
AND  n1.nspname NOT IN ('pg_catalog', 'pg_toast') 
AND  n2.nspname NOT IN ('pg_catalog', 'pg_toast') 
AND  pg_catalog.pg_table_is_visible(t1.oid) 
AND  pg_catalog.pg_table_is_visible(t2.oid) 
AND  t1.relname = @name;      

Я вижу, что вы используете information_schema вместо pg_catalog, поэтому самый простой способ может быть, чтобы включить мой запрос в CTE или подзапрос, а затем присоединиться к нему на основе вашего имени таблицы и столбца.

EDIT: Похоже, вам просто нужна помощь в моем запросе к тому, что у вас уже есть. На самом деле ваш запрос имеет много ошибок в том, как это стыки, поэтому я переписать его, чтобы включить правильные внешние ключевые результаты:

SELECT c.column_name, 
     c.udt_name, 
     t.constraint_type, 
     t.constraint_name, 
     x.to_table 
FROM information_schema.columns c 
LEFT OUTER JOIN (
     SELECT t.constraint_type, 
       t.constraint_catalog, 
       t.constraint_schema, 
       t.constraint_name, 
       t.table_catalog, 
       t.table_schema, 
       t.table_name, 
       u.column_name 
     FROM information_schema.constraint_column_usage u 
     LEFT OUTER JOIN information_schema.table_constraints t 
     ON  t.table_catalog = u.table_catalog 
     AND  t.table_schema = u.table_schema 
     AND  t.table_name = u.table_name 
     AND  t.constraint_catalog = u.constraint_catalog 
     AND  t.constraint_schema = u.constraint_schema 
     AND  t.constraint_name = u.constraint_name 
     WHERE t.constraint_type IS DISTINCT FROM 'FOREIGN KEY' 
) t 
ON  c.table_catalog = t.table_catalog 
AND  c.table_schema = t.table_schema 
AND  c.table_name = t.table_name 
AND  c.column_name = t.column_name 
LEFT OUTER JOIN (
    SELECT c.conname, 
      t1.relname AS from_table, 
      a1.attname AS from_column, 
      t2.relname AS to_table, 
      a2.attname AS to_column 
    FROM pg_catalog.pg_constraint c, 
      pg_catalog.pg_class t1, 
      pg_catalog.pg_class t2, 
      pg_catalog.pg_attribute a1, 
      pg_catalog.pg_attribute a2, 
      pg_catalog.pg_namespace n1, 
      pg_catalog.pg_namespace n2 
    WHERE c.conrelid = t1.oid 
    AND  c.confrelid = t2.oid 
    AND  c.contype = 'f' 
    AND  a1.attrelid = t1.oid 
    AND  a1.attnum = ANY(c.conkey) 
    AND  a2.attrelid = t2.oid 
    AND  a2.attnum = ANY(c.confkey) 
    AND  t1.relkind = 'r' 
    AND  t2.relkind = 'r' 
    AND  n1.oid = t1.relnamespace 
    AND  n2.oid = t2.relnamespace 
    AND  n1.nspname NOT IN ('pg_catalog', 'pg_toast') 
    AND  n2.nspname NOT IN ('pg_catalog', 'pg_toast') 
    AND  pg_catalog.pg_table_is_visible(t1.oid) 
    AND  pg_catalog.pg_table_is_visible(t2.oid) 
) x 
ON  x.from_table = c.table_name 
AND  x.from_column = c.column_name 
WHERE c.table_name = @cards 
; 

Эта версия также предотвращает много повторяющихся строк, если у вас есть NOT NULL или CHECK ограничения.

+0

это очень информативный ответ, но на самом деле не делать то, что мне нужно, чтобы – TheCatWhisperer

+1

Добавлено правку, показывающий, как присоединиться мой запрос к вашему. –

+1

Мастерские навыки sql Пол – TheCatWhisperer

1

Я не уверен, если вы знаете, как программировать с другими языками (например, Java, C#), кроме написания Sql запросов

Если вы знаете, любой из них, вы можете использовать функцию, которые являются ИНТ в JDBC/ODBC драйвер, чтобы получить то, что вы хотите

Вот пример использования JDBC

  1. открытие подключения к базе данных
  2. от соединения вы получаете, и вы можете получить метаданные, вот код

    conn=dataSource.getConnection(); 
        DatabaseMetaData dbmeta = conn.getMetaData(); 
    
  3. После получения метаданных вы можете получить все столбцы, первичные ключи, внешние ключи и даже проиндексировать. Смотрите коды образца ниже

ResultSet rsKey = dbmeta.getPrimaryKeys(null, schemaName, tableName); ResultSet rs = dbmeta.getColumns(null, schemaName, tableName, "%"); ResultSet rsForeign=meta.getExportedKeys(null, schemaName, tableName);

+0

Отличный ответ! Я знал, что могу получить имена столбцов из драйвера jbdc, но не знаю, что было легко получить FK и PK. – TheCatWhisperer

+0

Отметил другое как ответ просто потому, что он ответил на заданный вопрос – TheCatWhisperer

Смежные вопросы