计算在存储过程中给出错误结果

Posted

技术标签:

【中文标题】计算在存储过程中给出错误结果【英文标题】:Count giving wrong results in stored procedure 【发布时间】:2019-10-31 07:33:07 【问题描述】:

我从存储过程中运行的查询中得到不正确的计数。 当我们运行相同的查询(在硬编码表名和模式名的值之后)它会给出正确的结果。

初步分析,提示在存储过程中运行的查询由于某种原因忽略了第二个过滤器(即 where ... 和 ...,第二部分被忽略)。

CREATE OR REPLACE PROCEDURE dev.gp_count (tablename VARCHAR(256))
AS
$$ DECLARE schema_name VARCHAR(64);

table_name VARCHAR(128);

check_count_1 INT;

check_count_2 INT;

BEGIN 

schema_name:= SPLIT_PART(tablename,'.',1);

table_name:= SPLIT_PART(tablename,'.',2);

check_count_1 := (select count(*) from information_schema.tables where table_schema = schema_name and table_name like '%' + table_name +'%');
raise info 'check_count_1 - %',check_count_1;

end;
$$
language plpgsql;

并将上述过程称为 -

call dev.gp_count ('dev.gp_test1');

从存储过程得到的结果是—— 警告: check_count_1 - 925

如果我们在替换表名和模式的值之后运行相同的查询,那么 -

select count(*) from information_schema.tables where table_schema = 'dev' and table_name like '%gp_test1%';

结果 -

count
3

现在进一步调查这个问题 -

从存储过程获得的计数与从该查询获得的计数相同 -

select count(*) from information_schema.tables where table_schema = 'dev';

结果-

count
925

我的猜测 -

所以这暗示,也许在存储过程中,第二个过滤条件被忽略了。

除了帮我解决其他问题,请帮我找出这个异常背后的原因。

提前致谢。

【问题讨论】:

Redshift 还是 Postgres?尽管它们有一些共同的根源,但它们是非常不同的数据库产品 我使用 PLPGSQL 作为存储过程的语言(在 Postgresql 中)并在 Redshift 上执行它。 【参考方案1】:

我认为您的问题在于 1)您的字符串连接和 2)使用 table_name 作为变量:

check_count_1 := (select count(*) from information_schema.tables where table_schema = schema_name and table_name like '%' + table_name +'%');

PostgreSQL 字符串连接使用||,所以应该是这样的:

check_count_1 := (select count(*) from information_schema.tables where table_schema = schema_name and table_name like '%' || table_name || '%');

尝试将其更改为如下所示:

CREATE OR REPLACE PROCEDURE gp_count (tablename VARCHAR(256))
AS
$$ DECLARE
schema_name VARCHAR(64);
table_name1 VARCHAR(128);
check_count_1 INT;
check_count_2 INT;

BEGIN 
schema_name:= SPLIT_PART(tablename,'.',1);
table_name1:= SPLIT_PART(tablename,'.',2);

check_count_1 := (select count(*) from information_schema.tables f where table_schema = schema_name and f.table_name like '%' || table_name1 || '%');

raise info 'check_count_1 - %',check_count_1;

end;
$$
language plpgsql;

披露:我为EnterpriseDB (EDB)工作

【讨论】:

有趣。感谢分享! 谢谢@richyen,它就像一个魅力。仅供参考 - PostgreSQL 确实支持使用 + 或 || 连接.这两个选项都有效。

以上是关于计算在存储过程中给出错误结果的主要内容,如果未能解决你的问题,请参考以下文章

为啥存储过程没有在一个字符串中给出输出并且在 MySql 6.0 上执行的存储过程在 MySql 5.0 上给出错误

存储过程没有给出正确的值

存储过程中的动态 SQL 不返回结果集;在 SSMS 中运行时,我得到了结果

错误代码:1054。存储过程中“字段列表”中的未知列“abcdef”

sqlserver 存储过程 返回结果集的 例子

执行不返回结果的存储过程时引发错误