Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a function in pgsql

CREATE OR REPLACE FUNCTION core.date_bs_from_ad(date_in_ad date)   RETURNS character varying AS $$ BEGIN     RETURN(         SELECT date_in_bs FROM core.date_conversion         WHERE date_in_ad = $1     ); END $$    LANGUAGE plpgsql; 

It is created with no errors, but when i use this function it through following error:

ERROR:  column reference "date_in_ad" is ambiguous LINE 3:   WHERE date_in_ad = $1                 ^ DETAIL:  It could refer to either a PL/pgSQL variable or a table column. QUERY:  SELECT (         SELECT MAX(date_in_bs) FROM core.date_conversion         WHERE date_in_ad = $1     ) CONTEXT:  PL/pgSQL function core.date_bs_from_ad(date) line 3 at RETURN ********** Error **********  ERROR: column reference "date_in_ad" is ambiguous SQL state: 42702 Detail: It could refer to either a PL/pgSQL variable or a table column. Context: PL/pgSQL function core.date_bs_from_ad(date) line 3 at RETURN 
like image 976
mban94 Avatar asked Feb 09 '14 17:02

mban94


People also ask

What does PL pgSQL mean?

PL/pgSQL (Procedural Language/PostgreSQL) is a procedural programming language supported by the PostgreSQL ORDBMS.

What is PL pgSQL used for?

PL/pgSQL procedural language adds many procedural elements, e.g., control structures, loops, and complex computations, to extend standard SQL. It allows you to develop complex functions and stored procedures in PostgreSQL that may not be possible using plain SQL.

What is record type variable in PSQL?

PostgreSQL uses record type variables which simply act as placeholders for rows of a result set, similar to a row type variable. However, unlike row type variables, they do not have a predefined structure. Their structure is only determined after assigning a row to them.


2 Answers

In cases like these, where the code is simple straightforward enough, sometimes it is useful to rely on one of these special plpgsql commands at the start of the function text:

#variable_conflict error #variable_conflict use_variable #variable_conflict use_column 

In this case, it would be used as follows:

CREATE OR REPLACE FUNCTION core.date_bs_from_ad(date_in_ad date)   RETURNS character varying AS $$ #variable_conflict use_column BEGIN     RETURN(         SELECT date_in_bs FROM core.date_conversion         WHERE date_in_ad = $1     ); END $$ 

This is especially useful for cases when the clash is not with the parameters, but rather with the output column names, such as this:

CREATE OR REPLACE FUNCTION core.date_bs_from_ad(p_date_in_ad date)   RETURNS TABLE (date_in_bs character varying) AS $$ BEGIN     RETURN QUERY         SELECT date_in_bs FROM core.date_conversion         WHERE date_in_ad = p_date_in_ad; END; $$ 

The function above will fail because it the compiler cannot decide if date_in_bs is the output variable name or one of core.date_conversion's columns. For problems like these, the command #variable_conflict use_column can really help.

like image 135
Ezequiel Tolnay Avatar answered Sep 19 '22 15:09

Ezequiel Tolnay


There is a collision between SQL identifier and PlpgSQL variable. There are no clean, what do you want. You wrote a predicate, that is TRUE always.

Good to use:

  • prefix (usually "_") for local variables
  • qualified names in embedded SQL - like table_name.column_name

so both techniques (only one is necessary)

CREATE OR REPLACE FUNCTION core.date_bs_from_ad(_date_in_ad date) RETURNS character varying AS $$ BEGIN   RETURN SELECT dc.date_in_bs              FROM core.date_conversion dc             WHERE dc.date_in_ad = _date_in_ad; END $$  LANGUAGE plpgsql; 

For these one line functions is SQL language better:

CREATE OR REPLACE FUNCTION core.date_bs_from_ad(_date_in_ad date) RETURNS character varying AS $$    SELECT dc.date_in_bs       FROM core.date_conversion dc      WHERE dc.date_in_ad = $1;  $$  LANGUAGE sql; 
like image 21
Pavel Stehule Avatar answered Sep 21 '22 15:09

Pavel Stehule