|
在SQL(SQL Server)中,是否可以从表的标识列中检索下一个ID(整数),而实际上无需插入行?如果删除了最近的行,则不一定是最高ID加1。; g& l, y- ~" w( g
我之所以这样问,是因为我们有时不得不用新行更新活动数据库。该行的ID在我们的代码中使用(例如,Switch(ID){Case
9 Z. k# @3 P( q. a. |6 tID:},并且必须相同。如果我们的开发数据库和实时数据库不同步,最好预先预测一个行ID部署之前。! l8 z! @2 x3 |& a8 e9 `
我当然可以 SET IDENTITY OFF SET INSERT_IDENTITY# G% i0 H# y: j
ON或运行事务(这会回滚ID吗?)等,但我想知道是否有一个函数返回下一个ID(而不递增)。: ~0 }5 F/ J4 S- _
* n; z# E" l0 ^( @8 X: Q2 [ _5 H$ [+ N
解决方案:
/ j5 k s' l% {8 B 2 k0 b3 Y& V+ ~
& N+ ?* G# J3 L/ ^' x8 q* r4 x
4 v v" g* {: j3 n3 Y9 [ 编辑:
: D: V; I0 B, c- d在花了几个小时比较整个页面转储之后,我意识到有一种更简单的方法,我应该留在DMV上。
, b2 X% ?3 @+ p该值在备份/还原后仍然有效,这清楚地表明了该值已存储-我转储了数据库中的所有页面,但是找不到添加记录时的位置/更改。比较20万行的页面转储并不是一件好事。
7 e/ z5 a: F N' v$ x我使用了专用的管理控制台,对每个暴露的内部表都进行了转储,插入了一行,然后又对系统表进行了转储。这两个转储是相同的,这表明它可以生存,因此必须进行存储,即使在该级别也没有暴露。6 j4 ~2 `7 W( C" _
因此,绕了一圈后,我意识到DMV确实有答案。' B" n5 t) ]. z
create table foo (MyID int identity not null, MyField char(10))
8 o' D. n7 d- _& e5 T8 O6 \) p! |insert into foo values ('test')' @* E1 W% [8 w
go 10
9 L i2 @8 x/ Z8 ~+ ]( P" V-- Inserted 10 rows
6 i0 z1 F u$ s8 K7 oselect Convert(varchar(8),increment_value) as IncrementValue,
+ P" b8 ]2 ?; f2 z% r& X9 H; E Convert(varchar(8),last_value) as LastValue
$ Q4 u3 A! P( v5 f( Kfrom sys.identity_columns where name ='myid'
+ p% w% n6 S9 f0 h! O
8 `6 I1 q6 e/ Y7 [. h: _-- insert another row
" J$ _0 s" E) T: o7 C, ]( f% B$ ^3 oinsert into foo values ('test')
, a4 ~; S, G; m" r: |7 u: t$ I- ?-- check the values again
, P! ?- N% d1 y; ^( h# ?9 H& v nselect Convert(varchar(8),increment_value) as IncrementValue,1 d: L5 q& ~- h/ _
Convert(varchar(8),last_value) as LastValue
. L+ z4 K6 `' s- H3 L4 x7 Rfrom sys.identity_columns where name ='myid'
0 |" }( G7 A$ n8 u-- delete the rows: U$ T j, i- A5 w# r, l& G2 e
delete from foo
% @# z; H& O. X" S/ c: S+ G* n8 B- s, L% N
-- check the DMV again$ C6 \+ O2 I9 ?0 `, j
select Convert(varchar(8),increment_value) as IncrementValue,, `( d5 `3 B6 b3 q7 W
Convert(varchar(8),last_value) as LastValue$ A. V6 I9 u* Q: q
from sys.identity_columns where name ='myid'
) |+ n& ]- z) a d' A+ T9 \' w; {-- value is currently 11 and increment is 1, so the next insert gets 12
7 b0 F7 n* b5 S& v4 v% a0 m6 iinsert into foo values ('test')
$ }. d4 \" B4 G* T5 z; H: J0 _select * from foo, R% T, K. L) c* @% s8 q7 @
Result:* J+ z0 @, _ z, H$ X, W
MyID MyField) m. e, w' ^; V1 D: y) N# \
----------- ----------
2 q' s+ L7 v& Z$ }- b12 test
9 r9 W) m* }$ n(1 row(s) affected)! q- O7 k& Z. Q, O3 Y6 S# c
仅仅因为行被删除,最后一个值没有被重置,所以最后一个值+增量应该是正确的答案。* w# d8 b/ Q5 s1 W
也要在我的博客上写剧集。+ @. j8 c/ L; T. m' M9 r0 L
哦,这是所有方法的捷径:
4 d2 G* i4 N7 {select ident_current('foo') + ident_incr('foo')5 X: c1 ~5 J, R3 g9 u! w
因此,事实证明这很容易-但这一切都假设在您找回ID时,没有其他人使用过您的ID。可以进行调查,但是我不想在代码中使用它。 |
|