创建表时出错:“ @”处或附近的语法错误

时间:2019-04-18 11:45:20

标签: postgresql stored-functions

我正在尝试将SQL Server存储函数转换为PostgreSQL存储函数,我在declare @table1 table遇到一个语法错误

CREATE OR REPLACE FUNCTION ETL_GetBuildingDetailsByUserID ( p_nInstID   numeric=0)
RETURNS Boolean
AS $$
    declare @table1 table 
    (
    nbuilding numeric(18, 0) NOT NULL,
    sbuild_name varchar(50) NULL,
    sclient_build_id varchar(50) NULL,
    nbuilding_inst_id numeric(18, 0) NOT NULL,
    ntemp_building_id numeric(18,0) NULL,
    nno_of_floors numeric(18,0) NULL

    )

    declare v_strDeptIds text;
            v_strSubDeptIds text;

BEGIN

        v_strsql := 'SELECT     building.*
FROM         building
        WHERE     (building.nbuilding_inst_id = '|| cast(p_nInstID as varchar(1)) ||')

         ';

         print v_strsql 
         v_strsql1 text;
         v_strsql1 := v_strsql

        Insert into @table1; execute sp_executesql;  v_strsql1 
        select * from @table1;

Return true;
END;

$$ LANGUAGE plpgsql;

错误

ERROR:  syntax error at or near "@"
LINE 4:  declare @table1 table 

有人可以告诉我我在做什么错吗?

1 个答案:

答案 0 :(得分:1)

似乎您的函数实际上返回的是SELECT查询的结果,而不是布尔值,因此returns boolean开头是错误的。

要返回结果,您需要将该函数声明为returns table()。但是,您似乎只是从building表返回行,因此可以将其定义为returns setof building

然后删除似乎完全不必要的无用的动态SQL。

在PL / pgSQL中没有表变量,在从该表返回结果之前将查询结果复制到一个表中似乎是不必要的步骤,只会减慢速度。在Postgres中,您只需返回查询结果,而无需将其存储在本地。

此外:与其将参数强制转换为函数内的其他类型,不如使用您期望的类型声明该参数。

因此PostgreSQL中该函数的简化版本为:

CREATE OR REPLACE FUNCTION ETL_GetBuildingDetailsByUserID ( p_nInstID  text)
  RETURNS setof building
AS $$
    select building.*
    from building
    WHERE  building.nbuilding_inst_id = p_nInstID
$$ LANGUAGE sql;

您可以像这样使用它:

select *
from ETL_GetBuildingDetailsByUserID ('42');

不相关,但是:对于存储不带小数点的值的列使用numeric(18,0)是过大的。您应该将这些列定义为bigint。比数字快得多,占用的空间也少。