postgresql 它可以引用PL/pgSQL变量或表列

btxsgosb  于 12个月前  发布在  PostgreSQL
关注(0)|答案(3)|浏览(149)

我在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;

字符串
它的创建没有错误,但当我使用这个函数时,它通过以下错误:

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

vbopmzt1

vbopmzt11#

在这样的情况下,代码足够简单直接,有时在函数文本的开头依赖这些特殊的plpgsql命令之一是有用的:

#variable_conflict error
#variable_conflict use_variable
#variable_conflict use_column

字符串
在这种情况下,它将被使用如下:

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
$$


这在冲突不是与参数冲突,而是与输出列名冲突的情况下特别有用,例如:

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;
$$


上面的函数会失败,因为编译器无法确定date_in_bs是输出变量名还是core.date_conversion的列之一。对于这样的问题,命令#variable_conflict use_column确实可以帮助解决。

bmvo0sr5

bmvo0sr52#

SQL标识符和PlpgSQL变量之间有冲突。没有干净的,你想要什么。你写了一个 predicate ,它总是TRUE。
良好的用途:

  • 局部变量的前缀(通常为“_”)
  • 嵌入式SQL中的限定名-类似table_name.column_name

所以这两种技术(只需要一种)

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;

字符串
对于这些一行函数是SQL语言更好:

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;

7vux5j2d

7vux5j2d3#

在其他答案中没有提到的另一个选项是将函数名core.date_bs_from_ad作为前缀添加到列名date_in_ad,以便获得core.date_bs_from_ad.date_in_ad
这个问题的细节清楚地表明,使用其他答案之一是提出这个问题的人的正确选择,但这是一个有效的和缺失的答案,基于问题的标题。
我是被google带到这里来的,没有找到提到的这个选项,在我的情况下,前缀的函数名称是我需要的。

相关问题