创建 table 时出错:“@”处或附近的语法错误
Error while creating table : Syntax error at or near "@"
我正在尝试将 SQL 服务器存储函数转换为 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
任何人都可以告诉我做错了什么吗?
看来你的函数实际上 return 是 SELECT 查询的结果,而不是布尔值,所以 returns boolean
开头是错误的。
要return一个结果,需要将函数声明为returns table()
。但是,正如您似乎只是 building
table 中的 return 行一样,您可以将其定义为 returns setof building
.
然后删除似乎完全没有必要的无用动态SQL。
在 PL/pgSQL 中没有 table 变量,并且在 returning 那个 table 的结果之前将查询结果复制到一个中似乎是一个不必要的步骤只会减慢速度。在 Postgres 中,您只需 return 查询结果,无需将其存储在本地。
另外:与其在函数内将参数转换为另一种类型,不如用您期望的类型声明该参数。
因此 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
。比数字快得多,使用的 space 也更少。
我正在尝试将 SQL 服务器存储函数转换为 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
任何人都可以告诉我做错了什么吗?
看来你的函数实际上 return 是 SELECT 查询的结果,而不是布尔值,所以 returns boolean
开头是错误的。
要return一个结果,需要将函数声明为returns table()
。但是,正如您似乎只是 building
table 中的 return 行一样,您可以将其定义为 returns setof building
.
然后删除似乎完全没有必要的无用动态SQL。
在 PL/pgSQL 中没有 table 变量,并且在 returning 那个 table 的结果之前将查询结果复制到一个中似乎是一个不必要的步骤只会减慢速度。在 Postgres 中,您只需 return 查询结果,无需将其存储在本地。
另外:与其在函数内将参数转换为另一种类型,不如用您期望的类型声明该参数。
因此 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
。比数字快得多,使用的 space 也更少。