Обсуждение: Need help to dynamically access to colomns in function!

Поиск
Список
Период
Сортировка

Need help to dynamically access to colomns in function!

От
"Иван Марков"
Дата:
Hello. I have table classif with columns:
... , group1, group2, group3, ... , group48, ...

In function i do query and want run on every row and dynamically operate on columns from group1 to group20. I do something like this:

OPEN curs FOR select * from classif;
 loop
    fetch curs into tmprec;
    exit when not found;
   
    for I in 1..20 loop
        ...
    -- problem code is:
        value := tmprec.group{I}; 
    -- i cannot dynamically access to group1, group2, ... colomns according to "I" variable.
    ...   

    end loop;
end loop;

I have to manually identify and handle each entry without a cycle do something like this:
value := tmprec.group1;
...
value := tmprec.group2;
...
value := tmprec.group2;
...
value := tmprec.group20;
   
Please help me to do it dynamically with a loop, depending on the I?
something like this in a loop:
value := tmprec.group{I}; 

Thanks.

Re: Need help to dynamically access to colomns in function!

От
Ivan Pavlov
Дата:
Please disregard my other message. I didn't get what you are trying to
do at first.
You can do this with dynamic SQL: Look at 38.5.4. Executing Dynamic
Commands (http://www.postgresql.org/docs/current/static/plpgsql-
statements.html).
I guess something like

EXECUTE 'SELECT tmprec.group' || i  INTO value

will work in a loop. Didn't try it though.

regards,
Ivan Pavlov


Re: Need help to dynamically access to colomns in function!

От
Ivan Pavlov
Дата:
If you need them one by one why fetch them into tmprec? Take a look at
the docs for FETCH:
http://www.postgresql.org/docs/8.3/static/sql-fetch.html

especially the FETCH ABSOLUTE...

regards,
Ivan Pavlov


On Dec 16, 3:37 pm, aesthete2...@gmail.com ("Иван Марков") wrote:
> Hello. I have table classif with columns:
> ... , group1, group2, group3, ... , group48, ...
>
> In function i do query and want run on every row and dynamically operate on
> columns from group1 to group20. I do something like this:
>
> OPEN curs FOR select * from classif;
>  loop
>     fetch curs into tmprec;
>     exit when not found;
>
>     for I in 1..20 loop
>         ...
>     -- problem code is:
>         value := tmprec.group{I};
>     -- i cannot dynamically access to group1, group2, ... colomns according
> to "I" variable.
>     ...
>
>     end loop;
> end loop;
>
> I have to manually identify and handle each entry without a cycle do
> something like this:
> value := tmprec.group1;
> ...
> value := tmprec.group2;
> ...
> value := tmprec.group2;
> ...
> value := tmprec.group20;
>
> Please help me to do it dynamically with a loop, depending on the I?
> something like this in a loop:
> value := tmprec.group{I};
>
> Thanks.


Re: Need help to dynamically access to colomns in function!

От
"Hoover, Jeffrey"
Дата:
Create a plpgsql function that reformats your row as an array.

Example:
 I have a table named task_parameter with three columns:

            Table "camera.task_parameter"
          Column      |                 Type          | Modifiers
--------------------------+---------------------------------+-----------
 parameter_name  | character varying(255) | not null
 parameter_value   | text                           |
 task_id                | bigint                         | not null

I create a plpgsql function that takes a task_parameter row and returns an array, one column per array entry:

create or replace function task_parameter_array(tp task_parameter) returns text[] as $$
declare
  result text[];
begin
  result[1] := tp.parameter_name;
  result[2] := tp.parameter_value;
  result[3] := tp.task_id;
  return result;
end $$ language plpgsql;

select task_parameter_array(task_parameter) from task_parameter limit 1;
                task_parameter_array
----------------------------------------------------
 {"db alignments per query",25,1286428019358957945}
(1 row)

You can write a similar function for your table and then your code would look like:

OPEN curs FOR select classif_to_array(classif) as group_array from classif;
loop
  fetch curs into tmprec;
  exit when not found;

  for I in 1..20 loop
      ...
      value := tmprec.group_array{I};

of course, this begs the question, whjy not define you table to store an array...?

-----Original Message-----
From: pgsql-general-owner@postgresql.org [mailto:pgsql-general-owner@postgresql.org] On Behalf Of Ivan Pavlov
Sent: Tuesday, December 16, 2008 3:55 PM
To: pgsql-general@postgresql.org
Subject: Re: [GENERAL] Need help to dynamically access to colomns in function!

If you need them one by one why fetch them into tmprec? Take a look at
the docs for FETCH:
http://www.postgresql.org/docs/8.3/static/sql-fetch.html

especially the FETCH ABSOLUTE...

regards,
Ivan Pavlov


On Dec 16, 3:37 pm, aesthete2...@gmail.com ("Иван Марков") wrote:
> Hello. I have table classif with columns:
> ... , group1, group2, group3, ... , group48, ...
>
> In function i do query and want run on every row and dynamically operate on
> columns from group1 to group20. I do something like this:
>
> OPEN curs FOR select * from classif;
>  loop
>     fetch curs into tmprec;
>     exit when not found;
>
>     for I in 1..20 loop
>         ...
>     -- problem code is:
>         value := tmprec.group{I};
>     -- i cannot dynamically access to group1, group2, ... colomns according
> to "I" variable.
>     ...
>
>     end loop;
> end loop;
>
> I have to manually identify and handle each entry without a cycle do
> something like this:
> value := tmprec.group1;
> ...
> value := tmprec.group2;
> ...
> value := tmprec.group2;
> ...
> value := tmprec.group20;
>
> Please help me to do it dynamically with a loop, depending on the I?
> something like this in a loop:
> value := tmprec.group{I};
>
> Thanks.


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

Re: Need help to dynamically access to colomns in function!

От
Sam Mason
Дата:
On Tue, Dec 16, 2008 at 11:37:17PM +0300, IIIIIIII wrote:
> Hello. I have table classif with columns:
> ... , group1, group2, group3, ... , group48, ...
>
> In function i do query and want run on every row and dynamically operate on
> columns from group1 to group20. I do something like this:

It sounds as though you should be using an ARRAY instead of having lots
of columns.

The best I could come up with would be doing something like:

> OPEN curs FOR select * from classif;

  OPEN curs FOR SELECT ARRAY[group1,group2,group3,group4] AS group FROM classif;

You'd obviously need to all the way up to "group20" here.  If the syntax
gets a bit baroque you could create a view to do the same.

>  loop
>     fetch curs into tmprec;
>     exit when not found;
>
>     for I in 1..20 loop
>         ...
>     -- problem code is:
>         value := tmprec.group{I};

  value := tmprec.group[I];

>     -- i cannot dynamically access to group1, group2, ... colomns according
> to "I" variable.
>     ...
>
>     end loop;
> end loop;
>
> I have to manually identify and handle each entry without a cycle do
> something like this:

You're using the wrong data type; RECORDs are for where you statically
know and care about the structure of the data, ARRAYs are when you care
at runtime.


  Sam

Re: Need help to dynamically access to colomns in function!

От
David Fetter
Дата:
On Tue, Dec 16, 2008 at 11:37:17PM +0300, Иван Марков wrote:
> Hello. I have table classif with columns:
> ... , group1, group2, group3, ... , group48, ...

That's a very poor design because it's both denormalized and has very
poor naming.  There are likely plenty of other things wrong with it,
too.  Check http://thedailywtf.com/ for systems similar to yours.  I
suspect it won't take long to find some.

> In function i do query and want run on every row and dynamically
> operate on columns from group1 to group20. I do something like this:

Nothing will really help until you fix your design, and dynamic
querying will only lead you further down this rat-hole.

The answer to, "how do I shoot myself in the foot?" is "Don't."

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter      XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate