如何在数据库中添加一条记录的时候同时得到该记录中“自动增长”字段的值?

hproof 2003-04-07 11:38:20
数据库中有一个表,其中id字段是自动增长的,我无法知道当前它的“上限”,利用insert语句中就不能指定其id的值。

我需要在增加一条新记录时,不用重新查询就可以知道该记录的id值,以便在其它地方使用该数据。类似:int id = Insert(...),该id为新记录的主键/自动增长的值。

(C#,OleDb)
...全文
338 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hproof 2003-05-15
  • 打赏
  • 举报
回复
asam2183(三山) 的方法比较简单,但在 Select @@identity 后不要加上 as 'id',像这样就可以了:

int id = Convert.ToInt32(Cmd.ExecuteScalar("Insert into ...;Select @@identity"));
rouser 2003-04-07
  • 打赏
  • 举报
回复
這樣的話,如果系統為多用戶呢?即當你Insert一條記錄後其它的用戶也添加了一條記錄
那麼你緊接著Select出來的是誰Insert的id呢?
我認為是不是應該鎖定表呢?但是我不會具體的做法 :(
afengsunwin 2003-04-07
  • 打赏
  • 举报
回复
如果用存储过程,可以通过传出参数实现
like this:
create procedure spTest
(
@name varchar(50),
@newID int out

)

as
insert into yourTable values(@name)

select @newID=@@identity

如果是用sql语句在应用程序在操作的,则可能要在执行完insert操作后再执行
select max(id) from yourTable之类的东东将其取出
seabirdforever 2003-04-07
  • 打赏
  • 举报
回复
1。selece Max(ID) .......... 得到最大的ID
可以用游标来防止出错
2 sqlserver 2000提供了两个全新的函数(IDENT_CURRENT,SCOPE_IDENTITY
),并且改进了@@IDENTITY的不足.当你插入新记录后,可以调用函数:
PRINT IDENT_CURRENT('table') '这将获得新的IDENTITY值,不管数据库中是不是有记
录添加(这就避免了@@IDENTITY的连接限制)
或者:PRINT SCOPE_IDENTITY() '这将获得在当前存储过程,触发器等其他程序创建的
最新记录的IDENTITY值.
而全局变量@@IDENTITY有一个问题,当对一张表执行insert时,如果该表有触发器程序
在执行插入操作,然后,接着在另一张表中插入记录,这样返回@@IDENTITY值就是第二
张表的IDENTITY值。
如果你用的不是SQL Server 2000,你最好一个简单的存储过程来解决这个问题。
CREATE PROCEDURE myProc
@param1 INT
AS
BEGIN
SET NOCOUNT ON
INSERT INTO someTable
(
intField
)
VALUES
(
@param1
)
SET NOCOUNT OFF
SELECT NEWID = @@IDENTITY
END

也可以用触发器来 insert 触发器来 得到最新的ID

不知这样你满意不
呵呵

cqnimin 2003-04-07
  • 打赏
  • 举报
回复
select cast(isnull(max(id),0) as int) from 表名
zwp315 2003-04-07
  • 打赏
  • 举报
回复
这样做有什么好处?
Knight94 2003-04-07
  • 打赏
  • 举报
回复
方法一:利用其它唯一字段进行查询;
方法二:对数据库相应的表写Insert的Trigger事件,由它来返回。
zwztu 2003-04-07
  • 打赏
  • 举报
回复
如果是SQL server的话
strSql="SELECT @@IDENTITY AS ID";
~~~~~~~~~~~~~~~~~~~~~~~~~~
command= new SqlCommand(strSql, connection );
dr=command.ExecuteReader();
if (dr.Read())
{
ID=dr["ID"].ToString();
}
dr.Close();
asam2183 2003-04-07
  • 打赏
  • 举报
回复
try:
string sql = "insert into table1 (column1,column2) values ('abc',123);select @@identity as 'id'";
sqlCommand oCmd=new SqlCommand(sql,oConn);
int i = Convert.ToInt32(oCmd.ExecuteScalar());
hproof 2003-04-07
  • 打赏
  • 举报
回复
可惜我用的不是ADO 也不是 SQL2K,ADO名字空间在哪里我找不到,SQL中我“无法登录”。
还好这个问题已经马马乎乎解决了,但现在发现一个新问题,就是当数据库为空是将发生错误在:
int max = (int)cmd.ExecuteScalar ();
处,因为记录为空,所以无法转换,我只好又这样改写:
try
{
int max = (int)cmd.ExecuteScalar ();
}
catch
{
max=1;
}
// ,数据库这东西太陌生了,,哎。

seabirdforever 2003-04-07
  • 打赏
  • 举报
回复
已经说过了 sqlserver 2000提供了两个全新的函数(IDENT_CURRENT,SCOPE_IDENTITY
),可以避免@@IDENTITY的连接限制
access只能用 select max(id).....
rouser 2003-04-07
  • 打赏
  • 举报
回复
Access?用ADO的話它在AddNew一個記錄後直接調用Recordset的id字段就返回了,我上次試了

還有,樓上的,你的方法只能解決B/S模式的lock,要是C/S模式的怎麼辦呢?
hproof 2003-04-07
  • 打赏
  • 举报
回复
static public int Insert(...)
{
lock(typeof(MyClass))
{
OleDbConnection conn = new OleDbConnection (ConnStr );
conn.Open ();
OleDbCommand cmd = new OleDbCommand ("Select max(Id) from [table]", conn);
int max = (int)cmd.ExecuteScalar ();
// ...其它操作
conn.Close();
}
}

该max既为最大的id值,为了防止多用户时的冲突,该操作放在单独的一个“组件”中,并通过lock(this)或lock(typeof(MyClass))进行线程同步。我刚做出来,由于用的是Access库,很多功能都没有,只能用这种死办法了?。。。//ExecuteScalar()返回第一行的第一列的Object类型,但这已够用了。

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧