Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выбрать список таблиц не через psql-шел / 11 сообщений из 11, страница 1 из 1
30.04.2007, 11:41
    #34497451
Skif Swarogich
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
Сабж.
Мне надо постоянно в моих функциях получать список таблиц в базе. \dt не подходит. Как через SQL получить?
Сейчас пользую:

Код: plaintext
SELECT tablename FROM pg_tables WHERE tableowner='owner'
но это не удобно.
При инсталяции функций и процедур приходиться каждый раз править их содержимое на предмет владельца.
В MySQL есть хорошая функция
Код: plaintext
SHOW TABLES
Которая с минимальными потерями позволяет решить мою задачу.
В принципе, мне, как вариант, подошла бы и проверка на существование необходимой таблицы. Есть хотя бы такое?
...
Рейтинг: 0 / 0
30.04.2007, 12:26
    #34497468
моррут
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
ключ -E у psql покажет что он шлёт на стервер при \dt
...
Рейтинг: 0 / 0
30.04.2007, 12:26
    #34497469
BlackDan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
Очень мало в посте полезной информации, больше эмоций :)
Skif SwarogichСабж.
Мне надо постоянно в моих функциях получать список таблиц в базе. \dt не подходит. Как через SQL получить?
Сейчас пользую:
Код: plaintext
SELECT tablename FROM pg_tables WHERE tableowner='owner'
но это не удобно.в чем, собственно, неудобство?

авторВ MySQL есть хорошая функция
Код: plaintext
SHOW TABLES
Которая с минимальными потерями позволяет решить мою задачу.

Чем show tables принципиально отличается от select * from pg_tables ?

авторВ принципе, мне, как вариант, подошла бы и проверка на существование необходимой таблицы. Есть хотя бы такое?
Код: plaintext
SELECT tablename FROM pg_tables WHERE tablename = 'tablename'
...
Рейтинг: 0 / 0
30.04.2007, 13:36
    #34497508
MBG
MBG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  foreach x [list table_1 view_1] {
    spi_exec -array V "SELECT relname, pg_class.relkind as relkind FROM pg_class, pg_namespace \
      WHERE pg_class.relnamespace=pg_namespace.oid \
        AND pg_class.relkind IN ('v', 'r') \
        AND pg_namespace.nspname='user_$1' \
        AND relname = '$unit\_$x'" {
      if [info exists V(relname)] {
        if {$V(relkind) eq "v"} {
          spi_exec "DROP VIEW  user_$1.$V(relname) CASCADE"
        }
        if {$V(relkind) eq "r"} {
          spi_exec "DROP TABLE  user_$1.$V(relname) CASCADE"
        }
      }
    }
  }


Доступно объяснил?
...
Рейтинг: 0 / 0
30.04.2007, 13:57
    #34497523
Skif Swarogich
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
BlackDanОчень мало в посте полезной информации, больше эмоций :)
в чем, собственно, неудобство?

авторВ MySQL есть хорошая функция
Код: plaintext
SHOW TABLES
Которая с минимальными потерями позволяет решить мою задачу.

Чем show tables принципиально отличается от select * from pg_tables ?

авторВ принципе, мне, как вариант, подошла бы и проверка на существование необходимой таблицы. Есть хотя бы такое?
Код: plaintext
SELECT tablename FROM pg_tables WHERE tablename = 'tablename'


не удобно тем, что владелец меняется. схема по дефолту public. На сервере может находиться несколько похожих баз (например одна основная, а вторая развернутая из бекапа), в результате таблиц с одинаковым названием может быть или несколько или не в той базе что не обходимо. Плюс могут находиться другие базы, которые могут содержать схожие названия таблиц. Так что у меня пока из всего что есть только и остается выбор из pg_tables по схеме и владельцу :( Увы, другого пока не знаю способа.
А SHOW TABLES принципиально отличается от SELECT tablename FROM pg_tables тем, что ей нет нужды во вспомогательных данных, как-то имя таблицы откуда выбирать, схемы, владельца таблиц/схем. Все делается достаточно просто без излишнего головомойства.
...
Рейтинг: 0 / 0
30.04.2007, 14:03
    #34497525
Skif Swarogich
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
MBG
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
  foreach x [list table_1 view_1] {
    spi_exec -array V "SELECT relname, pg_class.relkind as relkind FROM pg_class, pg_namespace \
      WHERE pg_class.relnamespace=pg_namespace.oid \
        AND pg_class.relkind IN ('v', 'r') \
        AND pg_namespace.nspname='user_$1' \
        AND relname = '$unit\_$x'" {
      if [info exists V(relname)] {
        if {$V(relkind) eq "v"} {
          spi_exec "DROP VIEW  user_$1.$V(relname) CASCADE"
        }
        if {$V(relkind) eq "r"} {
          spi_exec "DROP TABLE  user_$1.$V(relname) CASCADE"
        }
      }
    }
  }


Доступно объяснил?
немного не понял. Откуда берутся 'user_$1' '$unit\_$x'
...
Рейтинг: 0 / 0
30.04.2007, 14:09
    #34497529
Skif Swarogich
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
моррутключ -E у psql покажет что он шлёт на стервер при \dt
Вот это кажется именно оно. Спасибо, буду пробовать.
...
Рейтинг: 0 / 0
30.04.2007, 18:18
    #34497724
MBG
MBG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
'user_$1' и '$unit\_$x' - это просто переменные, а сам sql-запрос ищет в указанной схеме указанные таблицы и виды и удаляет их, если находит.

А пример я взял вот из такой функции:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
CREATE OR REPLACE FUNCTION reports.build_sales_checks(int4)
  RETURNS bool AS
$BODY$
 
  set unit report_sales_checks
  set session_table "user_$1.session"
  set db_prefix "user_$1.$unit\_"
 
  spi_exec "DELETE from $session_table where unit='$unit' and var IN ('db_log', 'db_sale_filter', 'db_user_filter', 'db_date_filter')"
  # drop views
  foreach x [list checks expand_checks] {
    spi_exec -array V "SELECT relname, pg_class.relkind as relkind FROM pg_class, pg_namespace \
      WHERE pg_class.relnamespace=pg_namespace.oid \
        AND pg_class.relkind IN ('v', 'r') \
        AND pg_namespace.nspname='user_$1' \
        AND relname = '$unit\_$x'" {
      if [info exists V(relname)] {
        if {$V(relkind) eq "v"} {
          spi_exec "DROP VIEW  user_$1.$V(relname) CASCADE"
        }
        if {$V(relkind) eq "r"} {
          spi_exec "DROP TABLE  user_$1.$V(relname) CASCADE"
        }
      }
    }
  }
 
  set sql_get {SELECT value from $session_table where unit='$unit' and var='$var'}
 
  set vars [list macroregion region dealer subdealer category cluster trademark]
  set sale_filter true
  foreach var $vars {
    if {![ spi_exec [subst $sql_get]]} {
      set log [quote "Ошибка: Не найден элемент $var в переменных сессии модуля $unit"]
      spi_exec "INSERT INTO $session_table (unit, var, value) values ('$unit', 'db_log', '$log')"
      return false
    } 
    if {$value ne ""} {
      append sale_filter " and $var IN ([joinquote $value])"
    }
  }
  spi_exec "INSERT INTO $session_table (unit, var, value) values ('$unit', 'db_sale_filter', '[quote $sale_filter]')"
 
  set var user
  set user_filter true
  if {![ spi_exec [subst $sql_get]]} {
      set log [quote "Ошибка: Не найден элемент $var в переменных сессии модуля $unit"]
      spi_exec "INSERT INTO $session_table (unit, var, value) values ('$unit', 'db_log', '$log')"
      return false
  }
  if {$value ne ""} {
    set user_filter "name IN ([joinquote $value])"
  }
  spi_exec "INSERT INTO $session_table (unit, var, value) values ('$unit', 'db_user_filter', '[quote $user_filter]')"
 
  set vars [list date_from date_to]
  set sql_get {SELECT value from $session_table where unit='$unit' and var='$var'}
  foreach var $vars {
    if {![ spi_exec [subst $sql_get]]} {
      set log [quote "Ошибка: Не найден элемент $var в переменных сессии модуля $unit"]
      spi_exec "INSERT INTO $session_table (unit, var, value) values ('$unit', 'db_log', '$log')"
      return false
    } 
    if {$value ne ""} {
      set $var [quote $value]
    } else {
      set log [quote "Ошибка: Пустое значение элемента $var в переменных сессии модуля $unit"]
      spi_exec "INSERT INTO $session_table (unit, var, value) values ('$unit', 'db_log', '$log')"
      return false
    }
  }
 
  # если дошли до этого места, фильтры по т/т и пользователю успешно созданы, можно начинать генерацию таблиц отчета
 
  spi_exec "create view ${db_prefix}checks as 
    select distinct check_date, object_id, user_id
    from cache.checks d 
    where d.check_date between '$date_from'::date and '$date_to'::date 
    and d.object_id IN (select id from merch.objects_sales where $sale_filter) 
    and d.user_id   IN (select id from auth.users       where $user_filter)"
 
  spi_exec "CREATE view ${db_prefix}expand_checks AS
SELECT s.id as object_id, macroregion, region, case when s.code='' then 'Удалена' else s.code end as code,
    town, address, dealer, subdealer, category, cluster,
    trademark, person, phone, u.id as user_id, u.name as user,
    check_date
FROM ${db_prefix}checks c
left join merch.objects_sales s on c.object_id=s.id
left join auth.users u on c.user_id  =u.id"
 
  # таблицы отчета построены, возвращаем управление
  spi_exec "INSERT INTO $session_table (unit, var, value) values ('$unit', 'db_log', '')"
  return true
 
$BODY$
  LANGUAGE 'pltcl' VOLATILE SECURITY DEFINER;
...
Рейтинг: 0 / 0
01.05.2007, 01:17
    #34498025
BlackDan
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
MBG
LANGUAGE 'pltcl' VOLATILE SECURITY DEFINER;
[/src]
спасибо, всё всем понятно... все используют в разработке pltcl, знают конструкции языка и т.д. и т.п.
возможно, для ответа на любой вопрос, достаточно привести код на каком-нибудь экзотическом языке, чтобы всем стало всё понятно и вопросов больше не возникало... отличная практика.
дааа!!! ещё у меня есть фукции на 1000 строк, возможно, я их должен тоже на форум запостить, чтобы решить половину проблем спрашивающих?!
...
Рейтинг: 0 / 0
01.05.2007, 23:37
    #34498511
MBG
MBG
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
Я привел пример SQL кода. В ответ на вопрос подробно показал, где этот код используется. Если ты не можешь найти SQL код в приведенном фрагменте, вряд ли кто тебе сможет помочь.
...
Рейтинг: 0 / 0
03.05.2007, 01:21
    #34500814
Skif Swarogich
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать список таблиц не через psql-шел
Люди, спасибо, все решилось при помощи ключика -E и просмотра запроса. В итоге написал свою функцию на plperl.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
CREATE or REPLACE FUNCTION show_tables(varchar) returns setof varchar AS '

my $tbl_scheme = shift @_;
my $query="SELECT n.nspname as  Scheme ,
  c.relname as Name,
  CASE c.relkind WHEN ''r'' THEN ''Table'' WHEN ''v'' THEN ''View'' WHEN ''i'' THEN ''Index'' WHEN ''S'' THEN ''Posled'' WHEN ''s'' THEN ''Spesial'' END as Type,
  r.rolname as Owner
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_roles r ON r.oid = c.relowner
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN (''r'','''')
      AND n.nspname NOT IN (''pg_catalog'', ''pg_toast'')
      AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2";
my $dbh  = spi_exec_query($query);
my $rows = $dbh->{processed};
my $res  = $dbh->{status};

my @res_data;
foreach my $rw (0 .. ($rows - 1)) {
	my $rs = $dbh->{rows}[$rw];
	my $scheme = $rs->{scheme};
	my $name = $rs->{name};
	my $type = $rs->{type};
	my $owner = $rs->{owner};
	if (($type eq "Table") and ($scheme eq $tbl_scheme)) {
		push @res_data, $name;
	}
}
foreach my $table (@res_data) {
	return_next($table);
}

return undef;
'
LANGUAGE 'plperl';
Ключевое во всем этом сам запрос, подсмотренный у шела psql:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT n.nspname as  Scheme ,
  c.relname as Name,
  CASE c.relkind WHEN ''r'' THEN ''Table'' WHEN ''v'' THEN ''View'' WHEN ''i'' THEN ''Index'' WHEN ''S'' THEN ''Posled'' WHEN ''s'' THEN ''Spesial'' END as Type,
  r.rolname as Owner
FROM pg_catalog.pg_class c
     LEFT JOIN pg_catalog.pg_roles r ON r.oid = c.relowner
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN (''r'','''')
      AND n.nspname NOT IN (''pg_catalog'', ''pg_toast'')
      AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY  1 , 2 
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Выбрать список таблиц не через psql-шел / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]