1

我有以下存储过程:

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,..等。

4

3 回答 3

2

像这样的情况通常表明您没有连接到正确的数据库。

于 2013-11-08T17:59:31.587 回答
0

除了@Marek 暗示的与数据库连接的可能混淆之外,还有另一个典型的陷阱:

的不同设置search_path,可以解析'NetworkAddress_seq'为不同模式中的同名 SEQUENCE,甚至可以get_next_network()在不同模式中找到函数。

  select into ip (inet'10.41.142.0' + nextval('NetworkAddress_seq'));

顺便说一句,我从不在 Postgres 中使用 CaMeL 大小写标识符。那只是自找麻烦

该调用nextval('NetworkAddress_seq')查找具有 CaMeL-case 名称的序列,该序列使用以下命令创建:

CREATE SEQUENCE "NetworkAddress_seq";  -- with double-quotes!

但不是:

CREATE SEQUENCE NetworkAddress_seq;

.. 这会产生一个名为 的序列networkaddress_seq,您必须使用:

nextval('networkaddress_seq')

可能是问题的一部分。


此外,一切可能都是正确的,并且序列在其间增加了很多次。你排除了,对吧?

于 2013-11-08T18:35:31.740 回答
0

问题是 CACHE 设置为 256。我删除了它(默认 1),现在无论我从哪里调用我的程序,我都会得到下一个值..

来自这里的解释

在 PostgreSQL 的情况下,可以将一个序列对象配置为在单个后端进程中缓存多个值,这样如果您生成大量值,特定后端可能会一次“声明”到 100 个值的范围,使并发进程之间的冲突消失。

缓存的一个缺点是值可以并且将在此过程中被跳过。如果您期望它们以某种确切的顺序排列,那么这种期望将会失败。

我期待对过程的每次调用都会随着增量的增加而增加序列,无论它从哪里执行。

于 2013-11-11T09:15:56.290 回答