Обсуждение: SQL works but same function is confused

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

SQL works but same function is confused

От
"Bui, Michelle P"
Дата:

Hi all,

 

I have this query that when executed as a SQL statement, it works perfect! The table tools contains many records in a time series, with attributes like category but without the field status. I assign the value of status ’active’ or ‘inactive’ depending on whether the tool record exists after a certain time (number of seconds).

 

SELECT category, v_status as status, count (tool_id) AS tool_count

FROM

    (SELECT distinct category, tool_id, ‘active’ as v_status

                                  FROM tools

                                 WHERE time >= 123456

      UNION

                SELECT distinct e1.category, e1.tool_id, ‘inactive’ as v_status

                FROM tools e1

                WHERE not exists

                                (SELECT e2.category, e2.tool_id

                                FROM tools e2

                                WHERE e2.sim_time >= 123456

                                AND e2.category = e1.category

                                AND e2.tool_id = e1.tool_id)

   ) AS derived_table

GROUP BY category, Status

 

However, when I write a function to return the same result, using this SQL statement, and I declare a local variable v_status TEXT; it errors out when executed.  The key complaint is:

ERROR:  column reference "v_status" is ambiguous...

DETAIL:  It could refer to either a PL/pgSQL variable or a table column.

 

The function returns table (category, status, and tool_count) using RETURN QUERY in front of the query.

I used <<block>> before Declare section and try using block.v_status but this is not allowed (has syntax error). When I use #variable_conflict use_variable, there is no error anymore, but the resulted Status field is null. Seemed like Postgresql does not assign the v_status as we wish.

 

CREATE OR REPLACE FUNCTION get_status

RETURNS TABLE (category SMALLINT, status TEXT, tool_count BIGINT) AS

$BODY$

 

#variable_conflict use_variable

DECLARE

v_status TEXT;

BEGIN

    RETURN QUERY SELECT category, v_status as status, count (tool_id) AS tool_count

    FROM

    (SELECT distinct category, tool_id, ‘active’ as v_status

FROM tools

                                 WHERE time >= 123456

                                UNION

                SELECT distinct e1.category, e1.tool_id, ‘inactive’ as v_status

                FROM tools e1

                WHERE not exists

                                (SELECT e2.category, e2.tool_id

                                FROM tools e2

                                WHERE e2.sim_time >= 123456

                                AND e2.category = e1.category

                                AND e2.tool_id = e1.tool_id)

   ) AS derivedTable

GROUP BY category, Status;

 

END; $BODY$

LANGUAGE plpgsql;

 

 

Thanks in advance for your insight or suggestion!

 

Michelle

 

Re: SQL works but same function is confused

От
Rob Sargent
Дата:
CREATE OR REPLACE FUNCTION get_status

RETURNS TABLE (category SMALLINT, status TEXT, tool_count BIGINT) AS

$BODY$

 

#variable_conflict use_variable

DECLARE

change this to "s_status TEXT;" I think it's conflicting with the column alias of same

v_status TEXT;

BEGIN

    RETURN QUERY SELECT category, v_status as status, count (tool_id) AS tool_count

    FROM

    (SELECT distinct category, tool_id, ‘active’ as v_status

FROM tools

                                 WHERE time >= 123456

                                UNION

                SELECT distinct e1.category, e1.tool_id, ‘inactive’ as v_status

                FROM tools e1

                WHERE not exists

                                (SELECT e2.category, e2.tool_id

                                FROM tools e2

                                WHERE e2.sim_time >= 123456

                                AND e2.category = e1.category

                                AND e2.tool_id = e1.tool_id)

   ) AS derivedTable

GROUP BY category, Status;

 

END; $BODY$

LANGUAGE plpgsql;

 

 

Thanks in advance for your insight or suggestion!

 

Michelle

 


Re: SQL works but same function is confused

От
Rob Sargent
Дата:
On 04/01/2014 06:10 PM, Bui, Michelle P wrote:

Hi all,

 

I have this query that when executed as a SQL statement, it works perfect! The table tools contains many records in a time series, with attributes like category but without the field status. I assign the value of status ’active’ or ‘inactive’ depending on whether the tool record exists after a certain time (number of seconds).

 

SELECT category, v_status as status, count (tool_id) AS tool_count

FROM

    (SELECT distinct category, tool_id, ‘active’ as v_status

                                  FROM tools

                                 WHERE time >= 123456

      UNION

                SELECT distinct e1.category, e1.tool_id, ‘inactive’ as v_status

                FROM tools e1

                WHERE not exists

                                (SELECT e2.category, e2.tool_id

                                FROM tools e2

                                WHERE e2.sim_time >= 123456

                                AND e2.category = e1.category

                                AND e2.tool_id = e1.tool_id)

   ) AS derived_table

GROUP BY category, Status

 

However, when I write a function to return the same result, using this SQL statement, and I declare a local variable v_status TEXT; it errors out when executed.  The key complaint is:

ERROR:  column reference "v_status" is ambiguous...

DETAIL:  It could refer to either a PL/pgSQL variable or a table column.

 

The function returns table (category, status, and tool_count) using RETURN QUERY in front of the query.

I used <<block>> before Declare section and try using block.v_status but this is not allowed (has syntax error). When I use #variable_conflict use_variable, there is no error anymore, but the resulted Status field is null. Seemed like Postgresql does not assign the v_status as we wish.

 

CREATE OR REPLACE FUNCTION get_status

RETURNS TABLE (category SMALLINT, status TEXT, tool_count BIGINT) AS

$BODY$

 

#variable_conflict use_variable

DECLARE

v_status TEXT;

BEGIN

    RETURN QUERY SELECT category, v_status as status, count (tool_id) AS tool_count

    FROM

    (SELECT distinct category, tool_id, ‘active’ as v_status

FROM tools

                                 WHERE time >= 123456

                                UNION

                SELECT distinct e1.category, e1.tool_id, ‘inactive’ as v_status

                FROM tools e1

                WHERE not exists

                                (SELECT e2.category, e2.tool_id

                                FROM tools e2

                                WHERE e2.sim_time >= 123456

                                AND e2.category = e1.category

                                AND e2.tool_id = e1.tool_id)

   ) AS derivedTable

GROUP BY category, Status;

 

END; $BODY$

LANGUAGE plpgsql;

 

 

Thanks in advance for your insight or suggestion!

 

Michelle

 


Then again, do you use "v_status" as a variable?  select into v_status....


Re: SQL works but same function is confused

От
Adrian Klaver
Дата:
On 04/01/2014 05:10 PM, Bui, Michelle P wrote:
> Hi all,
>
> I have this query that when executed as a SQL statement, it works
> perfect! The table tools contains many records in a time series, with
> attributes like category but without the field status. I assign the
> value of status ’active’ or ‘inactive’ depending on whether the tool
> record exists after a certain time (number of seconds).
>

>
> However, when I write a function to return the same result, using this
> SQL statement, and I declare a local variable v_status TEXT; it errors
> out when executed.  The key complaint is:
>
> ERROR:  column reference "v_status" is ambiguous...
>
> DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
>
> The function returns table (category, status, and tool_count) using
> RETURN QUERY in front of the query.
>
> I used <<block>> before Declare section and try using block.v_status but
> this is not allowed (has syntax error). When I use #variable_conflict
> use_variable, there is no error anymore, but the resulted Status field
> is null. Seemed like Postgresql does not assign the v_status as we wish.
>
> /CREATE OR REPLACE FUNCTION get_status/
>
> /RETURNS TABLE (category SMALLINT, status TEXT, tool_count BIGINT) AS/
>
> /$BODY$/
>
> //
>
> #variable_conflict use_variable
>
> /DECLARE/
>
> /v_status TEXT;/

I am not seeing where v_status is being used. Below it is an alias name
in the query, which is where the conflict is coming in.


>
> /BEGIN/
>
> /    RETURN QUERY SELECT category, v_status as status, count (tool_id)
> AS tool_count/
>
> /    FROM /
>
> /    (SELECT distinct category, tool_id, ‘active’ as v_status/
>
> /FROM tools/
>
> /                                 WHERE time >= 123456/
>
> /                                UNION/
>
> /                SELECT distinct e1.category, e1.tool_id, ‘inactive’ as
> v_status/
>
> /                FROM tools e1/
>
> /                WHERE not exists/
>
> /                                (SELECT e2.category, e2.tool_id/
>
> /                                FROM tools e2/
>
> /                                WHERE e2.sim_time >= 123456/
>
> /                                AND e2.category = e1.category/
>
> /                                AND e2.tool_id = e1.tool_id)/
>
> /   ) AS derivedTable/
>
> /GROUP BY category, Status;/
>
> //
>
> /END; $BODY$/
>
> /LANGUAGE plpgsql;/
>
> Thanks in advance for your insight or suggestion!
>
> Michelle
>


--
Adrian Klaver
adrian.klaver@aklaver.com


Re: SQL works but same function is confused

От
"Bui, Michelle P"
Дата:
v_status is not used inthe SQL statement but is used in the function because we need to return a table (catgory,
tool_count,status). 
 

Even when I did not use v_status, and assign value 'valid' or 'invalid' to the output parameter directly, the same
erroroccurred.
 

 Thanks,
Michelle
Can we assign value for an alias in a function?

----- Original Message -----
From: Adrian Klaver [mailto:adrian.klaver@aklaver.com]
Sent: Tuesday, April 01, 2014 07:29 PM
To: Bui, Michelle P; pgsql-general@postgresql.org <pgsql-general@postgresql.org>
Subject: Re: [GENERAL] SQL works but same function is confused

On 04/01/2014 05:10 PM, Bui, Michelle P wrote:
> Hi all,
>
> I have this query that when executed as a SQL statement, it works
> perfect! The table tools contains many records in a time series, with
> attributes like category but without the field status. I assign the
> value of status ’active’ or ‘inactive’ depending on whether the tool
> record exists after a certain time (number of seconds).
>

>
> However, when I write a function to return the same result, using this
> SQL statement, and I declare a local variable v_status TEXT; it errors
> out when executed.  The key complaint is:
>
> ERROR:  column reference "v_status" is ambiguous...
>
> DETAIL:  It could refer to either a PL/pgSQL variable or a table column.
>
> The function returns table (category, status, and tool_count) using
> RETURN QUERY in front of the query.
>
> I used <<block>> before Declare section and try using block.v_status but
> this is not allowed (has syntax error). When I use #variable_conflict
> use_variable, there is no error anymore, but the resulted Status field
> is null. Seemed like Postgresql does not assign the v_status as we wish.
>
> /CREATE OR REPLACE FUNCTION get_status/
>
> /RETURNS TABLE (category SMALLINT, status TEXT, tool_count BIGINT) AS/
>
> /$BODY$/
>
> //
>
> #variable_conflict use_variable
>
> /DECLARE/
>
> /v_status TEXT;/

I am not seeing where v_status is being used. Below it is an alias name 
in the query, which is where the conflict is coming in.


>
> /BEGIN/
>
> /    RETURN QUERY SELECT category, v_status as status, count (tool_id)
> AS tool_count/
>
> /    FROM /
>
> /    (SELECT distinct category, tool_id, ‘active’ as v_status/
>
> /FROM tools/
>
> /                                 WHERE time >= 123456/
>
> /                                UNION/
>
> /                SELECT distinct e1.category, e1.tool_id, ‘inactive’ as
> v_status/
>
> /                FROM tools e1/
>
> /                WHERE not exists/
>
> /                                (SELECT e2.category, e2.tool_id/
>
> /                                FROM tools e2/
>
> /                                WHERE e2.sim_time >= 123456/
>
> /                                AND e2.category = e1.category/
>
> /                                AND e2.tool_id = e1.tool_id)/
>
> /   ) AS derivedTable/
>
> /GROUP BY category, Status;/
>
> //
>
> /END; $BODY$/
>
> /LANGUAGE plpgsql;/
>
> Thanks in advance for your insight or suggestion!
>
> Michelle
>


-- 
Adrian Klaver
adrian.klaver@aklaver.com

Re: SQL works but same function is confused

От
Tom Lane
Дата:
"Bui, Michelle P" <michelle.p.bui@boeing.com> writes:
> I have this query that when executed as a SQL statement, it works perfect!

OK ...

> I used <<block>> before Declare section and try using block.v_status but
> this is not allowed (has syntax error).

That should work (in the sense of not getting a syntax error), but since
you've not shown us exactly what you wrote, it's impossible to say what
you did wrong.  However, that's mostly beside the point, because ...

> When I use #variable_conflict use_variable, there is no error anymore, but the resulted Status field is null. Seemed
likePostgresql does not assign the v_status as we wish. 

According to the above, the behavior you want is use_column.  Why are you
trying to get it to use the variable when that's not what you want?

            regards, tom lane


Re: SQL works but same function is confused

От
Adrian Klaver
Дата:
On 04/01/2014 06:44 PM, Bui, Michelle P wrote:
> v_status is not used inthe SQL statement but is used in the function because we need to return a table (catgory,
tool_count,status). 
>
> Even when I did not use v_status, and assign value 'valid' or 'invalid' to the output parameter directly, the same
erroroccurred. 

Not use v_status where, in the DECLARE block or as an alias in the query?

If it where me and I wanted to keep the variable in the DECLARE block I
would do:

DECLARE

_v_status TEXT;

At least you would be able to track which variable is in play.


 > Can we assign value for an alias in a function?

An SQL alias for table, column, etc or an alias for a function argument?

http://www.postgresql.org/docs/9.3/interactive/plpgsql-declarations.html#PLPGSQL-DECLARATION-ALIAS

>
>   Thanks,
> Michelle




--
Adrian Klaver
adrian.klaver@aklaver.com


Re: SQL works but same function is confused

От
"Bui, Michelle P"
Дата:
Thanks Tom and Adrian - Here are my SQL and the function:

SELECT category, v_status as status, count (tool_id) AS tool_count
FROM
    (SELECT distinct category, tool_id, 'active' as v_status
                                  FROM tools
                                 WHERE time >= 123456
      UNION
                SELECT distinct e1.category, e1.tool_id, 'inactive' as v_status
                FROM tools e1
                WHERE not exists
                                (SELECT e2.category, e2.tool_id
                                FROM tools e2
                                WHERE e2.sim_time >= 123456
                                AND e2.category = e1.category
                                AND e2.tool_id = e1.tool_id)
   ) AS derived_table
GROUP BY category, Status

And here is the function:
CREATE OR REPLACE FUNCTION get_status
RETURNS TABLE (category SMALLINT, status TEXT, tool_count BIGINT) AS
$BODY$

#variable_conflict use_variable
DECLARE
v_status TEXT;
BEGIN
    RETURN QUERY SELECT category, v_status as status, count (tool_id) AS tool_count
    FROM
    (SELECT distinct category, tool_id, 'active' as v_status
FROM tools
                                 WHERE time >= 123456
                                UNION
                SELECT distinct e1.category, e1.tool_id, 'inactive' as v_status
                FROM tools e1
                WHERE not exists
                                (SELECT e2.category, e2.tool_id
                                FROM tools e2
                                WHERE e2.sim_time >= 123456
                                AND e2.category = e1.category
                                AND e2.tool_id = e1.tool_id)
   ) AS derivedTable
GROUP BY category, Status;

END; $BODY$
LANGUAGE plpgsql;


-----Original Message-----
From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
Sent: Tuesday, April 01, 2014 7:21 PM
To: Bui, Michelle P
Cc: pgsql-general@postgresql.org
Subject: Re: [GENERAL] SQL works but same function is confused

"Bui, Michelle P" <michelle.p.bui@boeing.com> writes:
> I have this query that when executed as a SQL statement, it works perfect!

OK ...

> I used <<block>> before Declare section and try using block.v_status
> but this is not allowed (has syntax error).

That should work (in the sense of not getting a syntax error), but since you've not shown us exactly what you wrote,
it'simpossible to say what you did wrong.  However, that's mostly beside the point, because ... 

> When I use #variable_conflict use_variable, there is no error anymore, but the resulted Status field is null. Seemed
likePostgresql does not assign the v_status as we wish. 

According to the above, the behavior you want is use_column.  Why are you trying to get it to use the variable when
that'snot what you want? 

            regards, tom lane


Re: SQL works but same function is confused

От
David Johnston
Дата:
Bui, Michelle P wrote
> #variable_conflict use_variable
> DECLARE
> v_status TEXT;
> BEGIN
>     RETURN QUERY SELECT category, v_status as status, count (tool_id) AS
> tool_count
>     FROM
>     (SELECT distinct category, tool_id, 'active' as v_status

Seriously? Just pick a different alias for the 'active/inactive' column in
the sub-query. Problem solved.

Or, even smarter, don't even declare the variable since you never actually
use it anywhere in the function...

The variable_conflict variable should generally be used for backward
compatibility and not for newly coded functions.  For those just choose
names that do not conflict. The exception is for function return names that
you want to match existing column names in which case you need to prefix
appropriately.

You may want to provide your attempt to name the block to see if we can
figure why it gave a syntax error.

David J.





--
View this message in context:
http://postgresql.1045698.n5.nabble.com/SQL-works-but-same-function-is-confused-tp5798277p5798298.html
Sent from the PostgreSQL - general mailing list archive at Nabble.com.