我有以下存储过程:
CREATE OR REPLACE FUNCTION get_next_network()
RETURNS inet AS
$BODY$
/* get the next networkd */
DECLARE
ip inet;
BEGIN
select into ip (inet'10.41.142.0' + nextval('NetworkAddress_seq'));
return ip;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
序列NetworkAddress_seq以256:
递增CREATE SEQUENCE "NetworkAddress_seq"
INCREMENT 256
MINVALUE 256
MAXVALUE 9223372036854775807
START 256
CACHE 256;
ALTER TABLE "NetworkAddress_seq"
OWNER TO my_user;
当我从pgAdmin调用该函数时,我得到:10.41.143.0
当我从php / Doctrine / ORM调用它时:
$stmt = $this->_em->getConnection()->prepare("select get_next_network()");
$stmt->execute();
$stmt->fetchColumn(0);
我得到类似10.56.142.0
为什么?
编辑: 我检查了我通过硬编码返回值使用相同的过程 - 在这种情况下,我在pgadmin和php中获得相同的值。这也把问号放在序列上,但是当我从程序中查询它而不是直接我会假设无论从哪里调用get_next_network过程它都会使用相同的序列...或者我错了?
EDIT2: 奇怪的行为与php方面无关 - 如果得到同样奇怪的结果 打开多个pgAdmin SQL查询窗口(不同的数据库连接?)。例如:在Window1中我运行
select * from get_next_network();
结束获取:10.43.143.0 如果我再次运行它,我得到:10.43.144.0,10.43.145.0,......等 在Window2中 - 相同的查询返回:10.44.143.0并且所有后续查询得到: 10.44.144.0,10.44.145.0,..等。
答案 0 :(得分:2)
这些情况通常表明您没有连接到正确的数据库。
答案 1 :(得分:0)
除了像@Marek暗示的数据库连接可能混淆之外,还有另一个典型的陷阱:
search_path
的不同设置,可以将'NetworkAddress_seq'
解析为不同架构中同名的SEQUENCE,甚至可以在不同架构中找到函数get_next_network()
。< / p>
select into ip (inet'10.41.142.0' + nextval('NetworkAddress_seq'));
BTW,我永远在Postgres中使用CaMeL案例标识符。 That's just asking for trouble
调用nextval('NetworkAddress_seq')
查找具有CaMeL案例名称的序列,使用:
CREATE SEQUENCE "NetworkAddress_seq"; -- with double-quotes!
但不是:
CREATE SEQUENCE NetworkAddress_seq;
..导致名为networkaddress_seq
的序列,您必须使用:
nextval('networkaddress_seq')
可能是问题的一部分。
此外,一切都可能是正确的,并且序列在其间多次增加。你排除了这个,对吧?
答案 2 :(得分:0)
问题是CACHE设置为256.我删除它(默认为1),现在无论我从哪里调用我的程序,我都会得到下一个值..
来自here
的解释对于PostgreSQL,可以将序列对象配置为在单个后端进程中缓存多个值,这样,如果要生成大量值,则特定后端可能会“声明”到100个值的范围立刻,并发进程之间的冲突消失了。
缓存的一个缺点是值可以并且将在此过程中被跳过。如果你期望它们按照一些确切的顺序排列,那么期望就会失败。
我期待每次调用该过程都会增加序列的增量,无论它从哪里执行。