简体   繁体   English

没有 RESEED 的 MSSQL 身份插入

[英]MSSQL Identity Insert without RESEED

I have 4 databases in 4 different locations.我在 4 个不同的位置有 4 个数据库。 I wrote a program to sync each other.我写了一个程序来相互同步。 The program is working fine for maximum of 2 locations.该程序最多可用于 2 个位置。 I will explain why.我会解释原因。

Each database has identity primary key for each table.每个数据库的每个表都有标识主键。 If I configured ONLY two databases.如果我只配置了两个数据库。 I can set identity for the first database as IDENTITY(1,1) and another as IDENTITY(-1,-1).我可以将第一个数据库的身份设置为 IDENTITY(1,1),将另一个设置为 IDENTITY(-1,-1)。 But if there are multiple locations then I will have to follow some pattern for each database.但是如果有多个位置,那么我将不得不为每个数据库遵循一些模式。 Like,像,

1st - Identity(1,5)
2nd - Identity(2,5)
3rd - Identity(3,5)
........
........

Now my question is, when I synchronizing data in between each database.现在我的问题是,当我在每个数据库之间同步数据时。 I use IDENTITY_INSERT ON keyword.我使用 IDENTITY_INSERT ON 关键字。 After INSERTING rows to another database, SEED value will be changing to the MAX and it will break that pattern. INSERTING 行到另一个数据库后,SEED 值将更改为 MAX,这将打破该模式。

As an example, Database A has values like this,例如,数据库 A 具有这样的值,

1
6
11
16

Database B has values,数据库 B 有值,

2
7
12
17

If I synced data from Database B to A. It(A) will SEED to 17 and the next value would be 22. The pattern will break at this point.如果我将数据从数据库 B 同步到 A。It(A) 将 SEED 为 17,下一个值将是 22。此时模式将中断。

Someone asked the same question in some other forum.有人在其他论坛上问过同样的问题。 Here is the link.链接在这里。 https://www.sqlservercentral.com/forums/topic/identity-insert-without-reseed/page/2 But the solution is not working for me. https://www.sqlservercentral.com/forums/topic/identity-insert-without-reseed/page/2但该解决方案对我不起作用。 They suggested to use "REPLICATION=TRUE;"他们建议使用“REPLICATION=TRUE;” in the connection string to avoid RESEED but that is not working for me.在连接字符串中以避免 RESEED 但这对我不起作用。

How to solve this issue?如何解决这个问题? I think I can do this by assigning range for each database but I would preferred to go for a sequence number.我想我可以通过为每个数据库分配范围来做到这一点,但我更愿意选择一个序列号。

Thanks.谢谢。

If you have multiple servers with identity columns and you want to combine the data in a single place, then SQL Server offers multiple replication and distribution possibilities.如果您有多个带有标识列的服务器,并且您希望将数据合并到一个地方,那么 SQL Server 提供了多种复制和分发的可能性。

If I understand your question, then you can set the servers to use different ranges of values.如果我理解您的问题,那么您可以将服务器设置为使用不同范围的值。 One method is to start the identity columns to different values on each server:一种方法是在每个服务器上将标识列启动为不同的值:

identity(1, 1)
identity(1000000, 1)

This assumes you will never have more than 1000000 rows on each server.这假设您在每台服务器上的行永远不会超过 1000000。

A slightly different way is to put even numbers on one server and odd numbers on the other:一种稍微不同的方法是将偶数放在一台服务器上,将奇数放在另一台服务器上:

identity(1, 2)
identity(2, 2)

Both of these guarantee that the identity values will not conflict after "merging".这两者都保证了“合并”后身份值不会发生冲突。

... mark the identity column as "not for replication" ... 将标识列标记为“不用于复制”

ssms tab_1 (normal connection): ssms tab_1(正常连接):

use tempdb
go
drop table if exists dbo.x;
drop table if exists dbo.y;
go

create table dbo.x(id int identity(1,5), a char(1) default('a'));
create table dbo.y(id int identity(1,5) not for replication, a char(1) default('a'));
go

insert into dbo.x(a)
values ('a'), ('a'), ('a');
insert into dbo.y(a)
values ('a'), ('a'), ('a');
go

select 'x' as tbl, * from dbo.x;
select 'y' as tbl, * from dbo.y;
go

ssms tab_2 (..Options-->Additional Connection Parameters--> add Replication=true;) : ssms tab_2 (..Options-->Additional Connection Parameters--> add Replication=true;) :

set identity_insert dbo.x on;
insert into dbo.x(id, a)
output inserted.*
values (12, 'b');
set identity_insert dbo.x off;
select 'x' as tbl, * from dbo.x;
go

set identity_insert dbo.y on;  --..not actually needed
insert into dbo.y(id, a)
output inserted.*
values (12, 'b');
set identity_insert dbo.y off;  --.. 
select 'y' as tbl, * from dbo.y;
go

/*
--error for a "typical" insertion when in "Replication"
--:Explicit value must be specified for identity column in table 'y' either when IDENTITY_INSERT is set to ON 
-- or when a replication user is inserting into a NOT FOR REPLICATION identity column.

insert into dbo.y(a)
values ('a')
*/

ssms tab_3 (normal connection): ssms tab_3(正常连接):

insert into dbo.x(a)
values('z'), ('z');
go

insert into dbo.y(a)
values('z'), ('z');
go

select 'x' as tbl, * from dbo.x;
select 'y' as tbl, * from dbo.y;
go

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM