我试图将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
任何人都可以告诉我做错了什么吗?
看来你的函数实际上返回了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
。比数字更快,使用更少的空间。