数据库的范围~identity可以限制范围吗

问题描述:在SQL SERVER 2008中,向数据表中字段插入数据时,会报错,错误如下:&当 IDENTITY_INSERT 设置为 OFF 时,不能向表 'OrderList' 中的标识列插入显式值。&解决方案:&&1 --允许将显式值插入表的标识列中 ON-允许 &OFF-不允许2 set identity_insert OrderList ON--打开3&4 insert into OrderList(id,ordername,createdate)5 values(4520,'set',getdate())6&7 set identity_insert OrderList OFF--关闭&在这个执行插入语句时,多了一个开关设置,设置如下:&&&1 --语法:&2&&3 SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF }&&4 允许将显式值插入表的标识列中&5&&6 参数说明:&7 database:针对&8 table:针对某张表&9&10 ON:允许插入显式值插入标识列11 OFF:不允许&注意:&(1))任何时候,只有一个表的 IDENTITY_INSERT 属性可以设置为 ON。如果某个表已将此属性设置为 ON,并且为另一个表发出了 SET IDENTITY_INSERT ON 语句,则返回一个错误信息,指出 SET IDENTITY_INSERT 已设置为 ON 并报告此属性已设置为ON的表。&(2)如果插入值大于表的当前标识值,则 SQL Server 自动将新插入值作为当前标识值使用。&(3)SET IDENTITY_INSERT 的设置是在执行或运行时设置,而不是在分析时设置。
您对本文章有什么意见或着疑问吗?请到您的关注和建议是我们前行的参考和动力&&数据库中identity字段不必是系统产生的唯一值--性能优化方法添新招 - SuperSaiyan - 博客园
Blog Stats
Posts - 28
Stories - 1
Comments - 87
Trackbacks - 4
具有identity特性的字段,其值是系统产生的,自动增加的,所以,一般把这个用在一个表的主键上。
但是,具有identity特性的字段,不需要具有唯一性,更不必须是主键。
可以通过,set identity_insert& tablename (on|off),在运行时控制,是否可以在identity字段中指定值,而不是由系统自动的插入值。
那么,这有什么用处呢。举个例子来说,两个用户之间的聊天,可以有多次,这个用一个chatsession来表示。在数据库中,我们需要三个表: user, chatsession(sessionid identity,...), user_chatsession (userid, sessionid, ...), 来表示这个关系。这里面,多出了一个表chatsession, 其主键sessionid具有identity特性,并且在user_chatsession中被引用。
但是,我们知道,数据库写操作比读操作的开销要大很多,如果我想做优化,把chatsession整个的去掉,那应该怎么做呢.
这时,就会用到我说的这一点。首先把 user_chatsession 中的sesssionid变成identity 字段,在插入一个chat session中的第一个 user-session (for user a)记录时,让系统自动产生sessionid, 然后记录下这个sessionid, 在插入一个session中后续的 user-session (for user b, user c...), 执行set identity_insert& tablename on,就可以把先前记录的sessionid值插入。
还有另外一个方法,比较笨一点,就是用 select max(sessionid) + 1 from table where userid = @useridA,来获得要新插入的sessionid,&这种方法性能上显然差了许多。&数据库中identity字段不必是系统产生的唯一值 性能优化方法(新招)
字体:[ ] 类型:转载 时间:
具有identity特性的字段,其值是系统产生的,自动增加的,所以,一般把这个用在一个表的主键上。
但是,具有identity特性的字段,不需要具有唯一性,更不必须是主键。 可以通过,set identity_insert tablename (on|off),在运行时控制,是否可以在identity字段中指定值,而不是由系统自动的插入值。 那么,这有什么用处呢。举个例子来说,两个用户之间的聊天,可以有多次,这个用一个chatsession来表示。在数据库中,我们需要三个表: user, chatsession(sessionid identity,...), user_chatsession (userid, sessionid, ...), 来表示这个关系。这里面,多出了一个表chatsession, 其主键sessionid具有identity特性,并且在user_chatsession中被引用。 但是,我们知道,数据库写操作比读操作的开销要大很多,如果我想做优化,把chatsession整个的去掉,那应该怎么做呢. 这时,就会用到我说的这一点。首先把 user_chatsession 中的sesssionid变成identity 字段,在插入一个session中的第一个 user-session (for user a)记录时,让系统产生sessionid, 然后记录下这个sessionid, 在插入一个session中后续的 user-session (for user b, user c...), 执行set identity_insert tablename on,就可以把先前记录的sessionid值插入。 还有另外一个方法,比较笨一点,就是用 select max(sessionid) + 1 from table where userid = @useridA,来获得要新插入的sessionid, 这种方法性能上显然差了许多。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具    最近帮一个客户搭建跨洋的合并复制,由于数据库非常大,跨洋网络条件不稳定,因此只能通过备份初始化,在初始化完成后向海外订阅端插入数据时发现报出如下错误: Msg 548, Level 16, State 2, Line 2
The insert failed. It conflicted with an identity range check constraint in database %s, replicated table %s, column %s. If the identity column is automatically managed by replication, update the range as follows: for the Publisher, execute sp_adjustpu for the Subscriber, run the Distribution Agent or the Merge Agent.   原因?     在SQL Server中,对于自增列的定义是对于每一条新插入的行,都会自动按照顺序新生成一个递增的数字,改数字通常和业务无关且被用于作为主键。但如果该表用于可更新事务复制或者合并复制,那么该自增列的区间范围则由复制管理。     此时,复制可以保证自增列可控,因为复制代理插入行时不会导致自增列自增,只有用户显式插入时才会导致自增列自增。     让我们来做一个实验。首先创建表,表定义如下:
CREATE TABLE [dbo].[Table_1](
[c1] [int] IDENTITY(1,1),
[c2] [int] NULL,
[ROWGUID] [uniqueidentifier] NOT NULL,
[rowguid4] [uniqueidentifier] ROWGUIDCOL NOT NULL,
CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]     此时我们对创建合并复制,并把该表包含在内,并使用快照代理初始化复制,当完成该步骤时,我们发现该表上自动多了两个约束,如图1所示。图1.合并复制所加的约束           我们看到该约束的定义只允许以及之间的数据被插入。     此时如果出现了一些BUG或者人为改动了该表自增列种子的值,则会报错,如图2所示。图2.改动种子值导致插入数据出错     该约束会由合并代理自动递增,比如说我们用如下代码插入2000条数据,则发现该约束会自动递增如图3所示。
DECLARE @index INT=1
WHILE @index&2000
INSERT INTO table_1(c2,ROWGUID) VALUES(2,NEWID())
SET @index=@index+1
END      图3.约束区间自动递增滑动 解决办法       此时我已经找出了上面报错的原因,因为是由于从备份初始化,那么备份以及备份传输期间发布库又有新的数据插入,此时发布库比如说,该表的种子大小已经增加到了6000,而备份中该表大小还是5000,而约束已经滑动到了6000,那么在订阅端插入数据时就会发生这种问题。解决办法1    在发布端使用sp_adjustpublisheridentityrange 存储过程使得约束范围自动向后滑动,比如从滑动到。缺点自增值之间会有一个GAP。如果业务允许,推荐使用该做法。    sp_adjustpublisheridentityrange @table_name=’表名称‘解决办法2    在发布端运行SELECT  IDENT_CURRENT('表名称'),找到发布表的种子值。在订阅端通过DBCC CHECKIDENT (表名称,RESEED, 设置为上面值)命令将两端种子值设置为一致。解决办法3    在订阅端运行合并代理,即可修复数据。如果此方法不行,则再次尝试上述方法。解决办法4    不用自增列,而使用GUID列,但这涉及到表结构以及程序的修改,而且需要重新初始化复制,因此不是每一个环境都有条件这么做。    此时,就可以正常插入数据了。
、 、 、 、 、}

我要回帖

更多关于 identity 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信