Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / record в text[] - можно? / 11 сообщений из 11, страница 1 из 1
03.05.2007, 12:40
    #34501799
record в text[] - можно?
Возможно ли преобразовать значение типа record в массив text[]? Если можно, то как? Если нельзя, почему? :)
...
Рейтинг: 0 / 0
03.05.2007, 17:16
    #34503026
record в text[] - можно?
Алексей КолосовВозможно ли преобразовать значение типа record в массив text[]? Если можно, то как? Если нельзя, почему? :)
Упростим задачу: функция возвращает значение типа record. Условия: известно количество возвращаемых полей, имена полей присутствуют в качестве массива text[]. Цель: перебрать последовательно все поля возвращённой записи по порядку и получить значения полей. Как?
...
Рейтинг: 0 / 0
04.05.2007, 05:54
    #34503738
Kruchinin Pahan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record в text[] - можно?
Алексей Колосов Алексей КолосовВозможно ли преобразовать значение типа record в массив text[]? Если можно, то как? Если нельзя, почему? :)
Упростим задачу: функция возвращает значение типа record. Условия: известно количество возвращаемых полей, имена полей присутствуют в качестве массива text[]. Цель: перебрать последовательно все поля возвращённой записи по порядку и получить значения полей. Как?
Смотря на чем писать собираешься. PlPerl и C - пожалста, а PlPgSql - низзя. (вроде).
...
Рейтинг: 0 / 0
04.05.2007, 06:33
    #34503751
record в text[] - можно?
Kruchinin PahanСмотря на чем писать собираешься. PlPerl и C - пожалста, а PlPgSql - низзя. (вроде).
а нет ли примера на plperl?
...
Рейтинг: 0 / 0
04.05.2007, 07:29
    #34503782
Serik Akhmetov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record в text[] - можно?
Алексей Колосов Алексей КолосовВозможно ли преобразовать значение типа record в массив text[]? Если можно, то как? Если нельзя, почему? :)
Упростим задачу: функция возвращает значение типа record. Условия: известно количество возвращаемых полей, имена полей присутствуют в качестве массива text[]. Цель: перебрать последовательно все поля возвращённой записи по порядку и получить значения полей. Как?record откуда берется ?
Если вы его получаете сами, то можно примерно так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
declare
    rec       record;
    sql       text;
begin

-- извлечение значения поля
    sql = 'select field1 as f1, field2 as f2 from my_func()';
    for rec in execute sql
    loop
      ... rec.f1 ....  -- использование record
      ... rec.f2 ....
    end loop;

end;

Проблема с pl/pgsql в том, что в теле процедуры невозможно обратиться к элементу record не зная его названия во время разработки процедуры. Обход заключается в том, что вы подставляете в динамический sql нужное название, и потом к нему обращаетесь. Т.е. если вы сами выполняете запрос, и знаете кол-во полей, просто подставьте нужные названия. Если кол-во не известно, можно выполнить несколько раз, вытаскивая по одному полю.
...
Рейтинг: 0 / 0
04.05.2007, 08:13
    #34503830
record в text[] - можно?
Serik AkhmetovПроблема с pl/pgsql в том, что в теле процедуры невозможно обратиться к элементу record не зная его названия во время разработки процедуры. Обход заключается в том, что вы подставляете в динамический sql нужное название, и потом к нему обращаетесь. Т.е. если вы сами выполняете запрос, и знаете кол-во полей, просто подставьте нужные названия. Если кол-во не известно, можно выполнить несколько раз, вытаскивая по одному полю.
это немного не то... т.е. функции, которая возвращает record передаются имя таблицы, список необходимых полей и условие выборки. она строит запрос, говорит EXECUTE v_query INTO v_rec и этот v_rec возвращает. НО! таблица может иметь произвольное количество полей и код приведённый Вами между loop...end loop должен быть динамическим, а это невозможно на plsql... Либо написать кучу IF...ELSIF...ELSIF с условием типа rec_count = n+1 ну скажем до n = 50... мне бы пример на plperl или plpython, я бы разобрался дальше... просто сам никогда не писал на них ХП :)
...
Рейтинг: 0 / 0
04.05.2007, 10:03
    #34504055
Serik Akhmetov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record в text[] - можно?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
CREATE OR REPLACE FUNCTION test2()
  RETURNS SETOF text AS
$BODY$
    my $row; 
    my $sth = spi_query("select * from audio limit 1;");
    while (defined ($row = spi_fetchrow($sth)))
    {
      my @k = (%$row);      
      for ($i= 0 ; $i < ($#k +  1 )/ 2 ; $i++)
      {
      # строка название_поля = значение
       return_next($k[$i* 2 ].' = '.$k[$i* 2 + 1 ]);
      }  
    }

return undef;                
$BODY$
  LANGUAGE 'plperlu' VOLATILE;

select * from test2();
Запрос передавай в параметре, вывод заворачивай в массив.
...
Рейтинг: 0 / 0
04.05.2007, 11:03
    #34504277
record в text[] - можно?
Код: 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.
CREATE OR REPLACE FUNCTION "mammoth"."get_field_values" (p_table text, p_fields text, p_muid bigint, p_mcid integer) RETURNS SETOF text AS

$body$

my $v_query = spi_query("select $_[1] from $_[0] where muid = $_[2] and mcid = $_[3];");

my $v_row = spi_fetchrow($v_query);



if (defined($v_row)) {

    foreach my $v_field (keys(%{$v_row})) {

                 return_next($v_row->{$v_field});

    }

}



return undef;

$body$

LANGUAGE 'plperl' VOLATILE;
у меня получилось проще... НО! он возвращает записи не в том порядке которые я ему задал... :( т.е. делаю
select * from mammoth.get_field_values('test_one', 'name, descr, created'); и получаю сначала (!) created, а потом name и descr... почему так?
...
Рейтинг: 0 / 0
04.05.2007, 11:17
    #34504330
Serik Akhmetov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record в text[] - можно?
Это особенность хэша, он не хранит порядок записей.

зная название поля можно явно к нему обратиться
Код: plaintext
$row->{$field_name}
можно распарсить p_fields и брать самому в нужной последовательности
...
Рейтинг: 0 / 0
04.05.2007, 13:48
    #34504958
record в text[] - можно?
Serik AkhmetovЭто особенность хэша, он не хранит порядок записей. зная название поля можно явно к нему обратиться
Код: plaintext
$row->{$field_name}
можно распарсить p_fields и брать самому в нужной последовательности
примерно вот так получилось:
Код: plaintext
1.
2.
foreach my $v_field (split(/\, /, $_[ 1 ])) {
                 return_next($v_row->{$v_field});
    }
одно огорчает - plperl работает медленнее plsql
...
Рейтинг: 0 / 0
04.05.2007, 14:30
    #34505128
.gc
.gc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record в text[] - можно?
Алексей Колосов Алексей КолосовВозможно ли преобразовать значение типа record в массив text[]? Если можно, то как? Если нельзя, почему? :)
Упростим задачу: функция возвращает значение типа record. Условия: известно количество возвращаемых полей, имена полей присутствуют в качестве массива text[]. Цель: перебрать последовательно все поля возвращённой записи по порядку и получить значения полей. Как?
Код: 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.
create table a_set ( f1 text, f2 text, f3 text , d1 int, d2 int);
create or replace function get_some_data(_d1 int, _d2 int, _fields text) returns setof text as $$
DECLARE _tmp text[];
        _i int;
BEGIN
  EXECUTE  
        'select ARRAY['||_fields||']::text[] '||
        ' FROM a_set WHERE d1='||text(_d1)||' AND d2='||text(_d2)||' LIMIT 1' 
  INTO _tmp;
  FOR _i IN array_lower(_tmp,  1 ) .. array_upper(_tmp,  1 ) LOOP
    RETURN NEXT _tmp[_i];
  END LOOP;
  RETURN;
END$$ language 'plpgsql';
INSERT INTO a_set VALUES('f1', 'f2', 'f3',  1 , 2 );
SELECT * FROM get_some_data(  1 ,  2 , 'f3, f1, f2');
SELECT * FROM get_some_data(  1 ,  2 , 'text(d1), text(d2), f3, f2');
SELECT * FROM get_some_data(  1 ,  2 , 'f2, f1, f1, f3, f2');

 get_some_data 
---------------
 f3
 f1
 f2
( 3  rows)

 get_some_data 
---------------
  1 
  2 
 f3
 f2
( 4  rows)

 get_some_data 
---------------
 f2
 f1
 f1
 f3
 f2
( 5  rows)
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / record в text[] - можно? / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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