Обсуждение: Why won't nested select-into expression work?

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

Why won't nested select-into expression work?

От
Leon Starr
Дата:
I've got an expression that works fine if I assign its return value (bigint) to a temporary variable (t).  But if
I eliminate the variable and just nest the expression, its outer expression (select into) fails for some reason.

Relevant variables:
    my_paragraph    paragraph%rowtype;
    t bigint;

I tried this and it failed (see embedded comments):

        select * into my_paragraph from paragraph where
            form = p_form and
            number = ( select method_paragraph_new( p_form, 0, p_append ) );
            -- Inner expression above inserts a new row in the 'paragraph' table which
            -- just happens to be the one I want selected by the outer select-into expression
        if not found then
            raise exception 'DEBUG: Paragraph create failed';  -- This is what happens!
        else
            raise exception'DEBUG:  Success!';
        end if;

But it works just fine if I use the variable 't' instead:

        t := ( select method_paragraph_new( p_form, 0, p_append ) );
        select * into my_paragraph from paragraph where
            form = p_form and
            number = t;  -- instead of a nested expression that inserts the thing I am looking for
        if not found then
            raise exception 'DEBUG: Paragraph create failed';
        else
            raise exception'DEBUG:  Success!';  -- This is what happens!
        end if;

There's probably something fundamental I am not understanding here.  Does anyone see the problem?



Re: Why won't nested select-into expression work?

От
Tom Lane
Дата:
Leon Starr <leon_starr@modelint.com> writes:
> I tried this and it failed (see embedded comments):

>         select * into my_paragraph from paragraph where
>             form = p_form and
>             number = ( select method_paragraph_new( p_form, 0, p_append ) );
>             -- Inner expression above inserts a new row in the 'paragraph' table which
>             -- just happens to be the one I want selected by the outer select-into expression

You're apparently expecting that the row inserted by
method_paragraph_new() will be seen by the already-in-progress outer
query?  That won't happen.  A SELECT will only see rows that exist
when it starts execution.  This is a feature, not a bug.

            regards, tom lane

Re: Why won't nested select-into expression work?

От
Leon Starr
Дата:
Good to know the rule.  Not entirely clear on why it's a feature and not a bug, but
that's why I posted as a novice!

On Nov 23, 2010, at 11:38 AM, Tom Lane wrote:

> Leon Starr <leon_starr@modelint.com> writes:
>> I tried this and it failed (see embedded comments):
>
>>         select * into my_paragraph from paragraph where
>>             form = p_form and
>>             number = ( select method_paragraph_new( p_form, 0, p_append ) );
>>             -- Inner expression above inserts a new row in the 'paragraph' table which
>>             -- just happens to be the one I want selected by the outer select-into expression
>
> You're apparently expecting that the row inserted by
> method_paragraph_new() will be seen by the already-in-progress outer
> query?  That won't happen.  A SELECT will only see rows that exist
> when it starts execution.  This is a feature, not a bug.
>
>             regards, tom lane
>
> --
> Sent via pgsql-novice mailing list (pgsql-novice@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-novice



Why won't this function loop?

От
"Rob Richardson"
Дата:
Greetings!

I am trying to write a function that will generate test requests as
input for another program.  The function will be called every ten
minutes.  It will read data from a table and generate requests for each
record in the source table in turn.  When it runs out of records in the
source table, it will go back to the beginning of the source table.

The function will get the lowest value larger than a given number from a
column.  If the given number is larger than any value in that column,
then the function should get the lowest number in that column.  The
number that is retrieved is stored in a one-row table for use the next
time the function is called.

Here is my function:

CREATE OR REPLACE FUNCTION add_test_request()
  RETURNS integer AS
$BODY$
declare
    LastIPChargeNum integer;
    LastHSCSChargeNum integer;
    NextIPChargeNum integer;
    NextHSCSChargeNum integer;

begin
    raise notice 'Running add_test_request()';

    select into LastIPChargeNum, LastHSCSChargeNum last_ip_charge,
last_hscs_charge from model_scheduler_test;
    select into NextIPChargeNum min(charge) from charge where status =
'Done' and charge > LastIPChargeNum;
    if not found then
    select into NextIPChargeNum min(charge) from charge where status
= 'Done';
    end if;

    select into NextHSCSChargeNum min(charge) from feedback
    where charge > LastHSCSChargeNum;
    if not found then
    select into NextHSCSChargeNum min(charge) from feedback;
    end if;

    insert into model_request (charge, run_date, heating, cooling)
    values (NextIPChargeNum, current_timestamp, 0, 0);
    insert into model_request (charge, run_date, heating, cooling)
    values (NextHSCSChargeNum, current_timestamp, 1, 1);

    update model_scheduler_test set last_ip_charge = NextIPChargeNum,
last_hscs_charge = NextHSCSChargeNum;

    return 1;
end;


When the values stored in model_scheduler_test are higher than anything
in the charge columns of charge or feedback, the NextIPChargeNum and
NextHSCSChargeNum end up being null.  If the values stored in
model_scheduler_test are low, the function works well.

What piece of sheer idiocy am I missing?

Thanks for your help!

RobR

Re: Why won't this function loop?

От
"Rob Richardson"
Дата:
Answering my own question:  It appears that FOUND will always be true
after calling the min() function, and probably after any other aggregate
function as well, even if the set of data the min() function is looking
at is empty.

RobR