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

问题描述 投票:0回答:1

我试图将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 

任何人都可以告诉我做错了什么吗?

postgresql stored-functions
1个回答
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。比数字更快,使用更少的空间。

© www.soinside.com 2019 - 2024. All rights reserved.