Проверьте, существует ли столбец, если в разных схемах есть несколько таблиц с одинаковыми именами (PSQL 8.2) - PullRequest
2 голосов
/ 16 мая 2011

Чтобы проверить, существует ли столбец, я могу легко использовать что-то похожее на это:

SELECT attname FROM pg_attribute 
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'YOURTABLENAME') 
AND attname = 'YOURCOLUMNNAME';

Однако у меня возникают проблемы с

SELECT oid FROM pg_class WHERE relname = 'YOURTABLENAME'

Когда существует несколько таблицс одинаковым именем, распределенным по разным схемам, поскольку он возвращает OID всех таблиц с этим именем.Как проверить, содержит ли таблица в определенной схеме столбец, который мне нужен?Я использую Postgres 8.2.

Ответы [ 2 ]

4 голосов
/ 16 мая 2011

8,2 поддерживает представления информации_схемы .Что-то в этом роде должно работать.Конечно, вам нужно будет указать собственную базу данных, схему, таблицу и имена столбцов.

select * 
from information_schema.columns
where table_catalog = 'sandbox'
and table_schema = 'public'
and table_name = 'calendar'
and column_name = 'iso_year';
2 голосов
/ 17 мая 2012

Общее решение , для проверки существования таблицы или столбца, использует функции (см. Ниже).Здесь я также использую функцию для анализа имени таблицы.

PS: простой способ проверить таблицу - использовать в вашей функции ::regclass, см. Дополнительную функцию table_exists_v2 ().

CREATE FUNCTION tname_split(
  -- Verify the table name, sort, use defaults if necessary, and returns
  -- array with indexes: 1=complete name, 2=schema name, 3=table name.
  p_tabname varchar,                 -- table name or full name (schema.table)
  p_schema varchar DEFAULT 'public'  -- default schema name
) RETURNS varchar[] AS $func$
DECLARE 
  p integer;
BEGIN
  IF (p_schema IS NULL) THEN p_schema:='public'; END IF;
  p := strpos(p_tabname,'.'); -- check schema
  IF p=0 AND p_schema='' THEN
    RAISE EXCEPTION 'ERROR, schema name default can not be empty';
  ELSEIF p=0 THEN 
    RETURN ARRAY[p_schema||'.'||p_tabname,p_schema,p_tabname];
  ELSEIF p=1 THEN 
    RAISE EXCEPTION 'ERROR, table name initiating by dot';
  ELSE
    RETURN ARRAY[p_tabname] || string_to_array(p_tabname, '.')::varchar[]; 
  END IF;
END;
$func$ LANGUAGE plpgsql;

CREATE FUNCTION column_exists(
  -- 
  -- Check if a column exists in a table. Returns true if yes.
  -- 
  p_colname varchar,
  p_tname varchar,             -- table name or full name (schema.table)
  p_schema varchar DEFAULT NULL  -- default schema name
) RETURNS BOOLEAN AS $func$
DECLARE
  t varchar[]; 
BEGIN
  t = lib.tadm_tname_split(p_tname,p_schema);
  PERFORM 1 FROM information_schema.COLUMNS 
  WHERE column_name=$1 AND table_schema=t[2] AND table_name=t[3];
  RETURN FOUND;
END;
$func$ LANGUAGE plpgsql;


CREATE FUNCTION table_exists(
  -- 
  -- Check if a table exists, returns true if yes, false if not.
  -- 
  p_tname varchar,                -- table name or full name (schema.table)
  p_schema varchar DEFAULT 'public',  -- default schema name
) RETURNS BOOLEAN AS $func$
DECLARE
  t varchar[]; 
BEGIN
  t = lib.tadm_tname_split(p_tname,p_schema);
  RETURN EXISTS (SELECT tablename FROM pg_tables WHERE schemaname=t[2] AND tablename=t[3]);
END;
$func$ LANGUAGE plpgsql;

CREATE FUNCTION table_exists_v2(p_tname varchar) RETURNS boolean AS $f$
DECLARE
  tmp regclass;
BEGIN
    tmp := p_tname::regclass; -- do nothing, only parsing regclass
    RETURN true;
    EXCEPTION WHEN SQLSTATE '3F000' THEN
       RETURN false;
END;
$f$ LANGUAGE plpgsql;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...