我有一个像这样定义的 Oracle 序列:
CREATE SEQUENCE "DALLAS"."X_SEQ"
MINVALUE 0
MAXVALUE 999999999999999999999999999
INCREMENT BY 1 START WITH 0 NOCACHE NOORDER NOCYCLE ;
Run Code Online (Sandbox Code Playgroud)
它在存储过程中用于插入记录:
PROCEDURE Insert_Record
(p_name IN VARCHAR2,
p_userid IN INTEGER,
cur_out OUT TYPES_PKG.RefCursor)
IS
v_id NUMBER := 0;
BEGIN
-- Get id value from sequence
SELECT x_seq.nextval
INTO v_id
FROM dual;
-- Line below is X_PKG line 40
INSERT INTO X
(the_id,
name,
update_userid)
VALUES
(v_id,
p_name,
p_userid);
-- Return new id
OPEN cur_out FOR
SELECT v_id the_id
FROM dual;
END; …Run Code Online (Sandbox Code Playgroud) 我有以下
CREATE TABLE [MyTable]
(
[ID] [bigint] PRIMARY KEY NOT NULL,
[Title] [nvarchar](64) NOT NULL
)
CREATE SEQUENCE MyTableID
START WITH 1
INCREMENT BY 1
NO CACHE
;
GO
Run Code Online (Sandbox Code Playgroud)
我想在 MyTable 上插入新记录并将 ID 设置为序列的下一个值。我该怎么做?也许是触发器,还是有其他方法?如何?
当我使用 SQL Server 2012 时,我不想使用 Identity 因为 gap bug。
最近我确实以超级用户的身份创建了一个表,其中包括一个序列号列,例如,
create table my_table
(
id serial primary key,
data integer
);
Run Code Online (Sandbox Code Playgroud)
因为我希望我的非超级用户用户拥有对该表的写访问权限,所以我授予了它权限:
grant select, update, insert, delete on table my_table to writer;
Run Code Online (Sandbox Code Playgroud)
在这样做之后的随机时间点,该用户所做的插入开始失败,因为该用户没有修改my_table_id_seq与串行列关联的序列的权限。不幸的是,我无法在我当前的数据库上重现它。
我通过授予用户所需的权限来解决这个问题,如下所示:
grant all on table my_table_id_seq to writer;
Run Code Online (Sandbox Code Playgroud)
有人可以帮我理解
在 PostgreSQL (9.3) 数据库中,我的 Accounts 和 Customers 之间是一对多的关系,因此在 Customers 表中,我有每个 Customer 的主键的全局唯一 id,以及相应的 Account id。但我还想为每个人分配一个特定于帐户的 ID - 只是一个数字,每个帐户的第一个客户从 1 开始,每个额外的客户递增 - 只是作为帐户中的用户在 UI 中引用客户的一种简单方法.
我可以想到两种可能的解决方案:
使用max()聚合函数获取用于 Account 的最后一个 Customer id 并将其递增
用一个 sequence
sequence某种方式为每个新帐户创建一个单独的帐户(然后在删除帐户时/当删除帐户时将其删除),否则每个帐户将在其客户 ID 序列中得到不连续的值更新
为了澄清最后一点,id 序列中总会出现一些差距;例如,一旦客户被删除,但这些都是意料之中的。除此之外,添加几个新客户的用户通常会希望他们有连续的 id,即使他们相隔几天添加。
OTOH,sequence为所有客户使用一个单一的客户几乎肯定会看到由分配给同时为其他账户创建的客户的 id 引入的常规的、无法解释的差距。
我不是 Postgres 专家,所以我担心我可以多么健壮地实现其中任何一个,尤其是当我一直在努力寻找任何可以遵循的示例时。
有没有普遍接受的方法来做到这一点?
我id serial PRIMARY KEY在 PostgreSQL 表中有一个列。id因为我删除了相应的行,所以缺少许多s。
现在我想通过重新启动序列并以保留id原始id顺序的方式重新分配s来“压缩”表。是否可以?
例子:
id | data
----+-------
1 | hello
2 | world
4 | foo
5 | bar
Run Code Online (Sandbox Code Playgroud)
id | data
----+-------
1 | hello
2 | world
3 | foo
4 | bar
Run Code Online (Sandbox Code Playgroud)
我尝试了 StackOverflow answer 中建议的内容,但没有奏效:
# alter sequence t_id_seq restart;
ALTER SEQUENCE
# update t set id=default;
ERROR: duplicate key value violates unique constraint t_pkey
DETAIL: Key …Run Code Online (Sandbox Code Playgroud) 我必须添加一个触发器,它应该使用以下格式字符串更新列:<current_date>_<per_day_incremental_id>,例如2015-10-01_36. Id 必须是增量的,并且允许有间隙。
我的方法相当天真:制作一个包含当前日期和当前序列值的表,并在其中维护一条记录:
create table DailySequence
(
date date,
sequence int
)
insert into DailySequence values (getdate(), 1);
CREATE TRIGGER MakeHumanReadableId ON dbo.AuditMeasures
FOR INSERT
AS
DECLARE @ret int;
DECLARE @tempDate date;
DECLARE @nowDate date;
SET @nowDate = getdate();
SELECT @ret = t.sequence, @tempDate = t.date from DailySequence as t;
IF @nowDate = @tempDate
BEGIN
SET @ret = @ret + 1;
UPDATE DailySequence
SET sequence = @ret;
END
ELSE
BEGIN
SET @ret = 0;
UPDATE …Run Code Online (Sandbox Code Playgroud) 有人可以告诉下面明显的查询有什么问题:
db2 => select next value for schema_name.sequence_name;
Run Code Online (Sandbox Code Playgroud)
结果我得到:
SQL0104N An unexpected token "END-OF-STATEMENT" was found following
"schema_name.sequence_name". Expected tokens may include: "<table_expr>".
SQLSTATE=42601
Run Code Online (Sandbox Code Playgroud) 在过去的一年里,开发人员在我们的 postgres 9.6 数据库中遇到了序列问题,他们停止工作,因此他们采取了诸如根据最后插入的记录的 pid 手动创建的 pid 插入行,并使用以下代码重置序列的方法:
SELECT pg_catalog.setval(pg_get_serial_sequence('mytable', 'pid'),
(SELECT MAX(pid)+1 FROM mytable) );
Run Code Online (Sandbox Code Playgroud)
我有足够的经验,知道我们应该能够依靠数据库来创建我们的 id,并且基于最后一个最大值创建自己的 PID 不是“最佳实践”,也不是对所有场景都安全,尽管它通常适用于我们的日常使用。
他们第一次停止工作的原因是众所周知的原因,例如表被恢复。但是,此时我认为手动代码和序列是相互踩踏的,序列重置代码并不可靠。很明显,插入最后一个最大值会破坏序列,它只会增加自己的数字。
当我在阅读时,我想知道今天是否有人指出我正确的方向以恢复序列并在现有表上完美工作 - 即使代码到位,有时也会插入来自代码的 pid,基于最后一个最大值。(当然,从长远来看,我完全意识到最好删除所有此类代码 - 但现在有没有办法解决该代码?)
包含在解决方案中的将是 postgreSQL 9.6 中的一种方法,如果发生冲突,它可以自行重置序列 - 不确定是否可能,并准备接受更有经验的人的讲座 - 但这就是我在这里的原因!
最后——这是让我来到这里的一个令人不安的事实——在 pg admin 中重置序列后,我在 pg admin 3 和 4 的表中看到两个 pid,它们也显示在创建脚本中。在 psql 中执行 \d 时不显示“第二个”PID 列,这很好 - 但我认为它可能是相关的。
更新 - 在最后一点上,导致 pg admin 中表的幽灵重复 PID 是因为同一列/表组合有两个序列,第二个是在某个时间创建的,以尝试修复损坏的序列(例如 mytable_pid_seq 和mytable_pid_seq1)。不知道为什么/如何允许在数据库中发生这种情况。
从创建的角度来看,假设在 Postgres 中通过自动递增的 PK 排序将按时间顺序对记录进行排序是否安全?我有一个多对多的关系,除了关系本身和某种形式的创建顺序之外,我不需要跟踪其他任何东西。我正在尝试决定是否需要为此合并时间戳列,或者是否可以出于相同目的重新利用现有的自动递增 PK 列。
我在 PostgreSQL 13 中有下表:
field type
----- ----
Seq bigserial
code varchar
Run Code Online (Sandbox Code Playgroud)
Seq是主键(自增)
Code是唯一键索引
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing --> Seq value is 1
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('001') On Conflict(Code) Do Nothing
Insert Into newtable (Code) Values ('002') On Conflict(Code) Do Nothing --> Seq value is 4
Run Code Online (Sandbox Code Playgroud)
为什么是序列4?有什么方法可以仅在成功插入时增加价值?
sequence ×10
postgresql ×6
primary-key ×2
sql-server ×2
db2 ×1
oracle ×1
permissions ×1
t-sql ×1
upsert ×1