我在postgres中有一个表,它的主键是用一个序列(我们称之为“a_seq”)来分配的。这个序列是用来递增值并插入当前值作为被插入记录的主键。
我用于序列的代码:
CREATE SEQUENCE public.a_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;
ALTER SEQUENCE public.AssembleTable_RowId_seq OWNER TO postgres;
字符串
我试图从磁盘复制一个文件,并将有关复制文件的信息插入到表中。磁盘中有同名文件,因此我使用此查询从序列中检索“last_value”:
SELECT last_value FROM a_seq;
型
重命名文件“_”,然后将其插入数据库,以便该文件的文件名和主键(id)是一致的,如:
id | fileName
1 | 1_asd.txt
型
但是当我插入记录时,id总是比从查询中获取的“last_value”大1个值,所以表看起来像这样:
id | fileName
2 | 1_asd.txt
型
我已经多次尝试执行上面的select查询来检查它是否增加了值,但它没有。
在插入之前,如何获得将被分配给记录的值?
注意:我使用MATLAB,这是用于插入的代码:
colnames = {'DataType' , ...
'FilePath' , ...
'FileName' , ...
'FileVersion' , ...
'CRC32Q' , ...
'InsertionDateTime', ...
'DataSource' };
data = {FileLine{5} ,... % DataType
tempPath ,... % FilePath
FileLine{1} ,... % FileName
FileLine{2} ,... % FileVersion
FileLine{3} ,... % CRC32Q
FileLine{4} ,... % InsertionDateTime
FileLine{6} ,... % DataSource};
data_table = cell2table(data, 'VariableNames', colnames);
datainsert(conn , 'CopiedFiles' , colnames , data_table);
型
5条答案
按热度按时间hof1towb1#
更新
我相信你会发生什么:当你
select last_value
-你得到最后使用的序列值,当你insert
行,id
的默认值是nextval
,它将值滚动一个以上。previous我相信你在中间步骤的某个地方有一个额外的
nextval
。如果你在一个语句中这样做,它会像你期望的那样工作,例如:字符串
update 2正如Nick巴恩斯所注意到的,进一步的(初始化1)迭代将给予错误的结果,因此您需要使用他提出的
CASE
逻辑0aydgbwb2#
这是Postgres实现序列的方式中的一个怪癖;作为事务数据库中固有的非事务对象,它们的行为有点奇怪。
当你第一次调用
nextvalue()
时,它不会 * 影响你在a_seq.last_value
中看到的数字。但是,它会 * 翻转a_seq.is_called
标志:字符串
所以如果你需要序列中的下一个值,
型
请注意,如果两个进程同时执行此操作,则会严重损坏,因为无法保证您将在下一次
nextval()
调用中实际收到此值。在这种情况下,如果您确实需要filename
来匹配id
,则需要使用trigger生成它,或者在知道id
是什么后使用UPDATE
生成它。但根据我的经验,最好避免数据和键之间的任何依赖关系,如果你只需要一个唯一的
filename
,我会创建一个独立的filename_seq
。kognpnkq3#
当执行
INSERT
语句时没有id
的值- Postgres自动从序列中使用next_val
获取它。变量colnames
中的列列表没有id
,所以PG从序列中获取下一个值。为了解决这个问题,您可以将id添加到colnames
。t3psigkw4#
为了避免数据和密钥之间的任何依赖关系,请尝试:
字符串
ffscu2ro5#
看看你发布的内容,要选择
x_seq
的last_value
,你必须像表ie那样调用它:字符串