systemlog表中ID字段为自增列
...
con=new SqlConnection(sConStr);
SqlCommand cmd=new SqlCommand("Select * from systemlog Where id is null",con);
ad=new SqlDataAdapter(cmd);
SqlCommandBuilder bd=new SqlCommandBuilder(ad);
ad.InsertCommand=bd.GetInsertCommand();
tb=new DataTable();
ad.Fill(tb);
row=tb.NewRow();
tb.Rows.Add(row);
row["UserName"]="aaa";
row["Attemp_Login_Time"]=DateTime.Now;
ad.Update(tb);
tb.AcceptChanges();
此是,row["ID"]是DBNULL,各位达人,如何获得数据库里这条新增记录的ID字段的值?
...
con=new SqlConnection(sConStr);
SqlCommand cmd=new SqlCommand("Select * from systemlog Where id is null",con);
ad=new SqlDataAdapter(cmd);
SqlCommandBuilder bd=new SqlCommandBuilder(ad);
ad.InsertCommand=bd.GetInsertCommand();
tb=new DataTable();
ad.Fill(tb);
row=tb.NewRow();
tb.Rows.Add(row);
row["UserName"]="aaa";
row["Attemp_Login_Time"]=DateTime.Now;
ad.Update(tb);
tb.AcceptChanges();
此是,row["ID"]是DBNULL,各位达人,如何获得数据库里这条新增记录的ID字段的值?
RETRUN @@IDENTITY
2,select ident_current('表名')
或者一个object 类型的数据
你自己强制转换就好了 (int)cmd.ExecuteScaler()
select max(id) from systemlog;得到这个id号。
StringBuilder sb = new StringBuilder();
sb.Append("INSERT INTO xxx");
sb.Append(" (a, b)");
sb.Append(" VALUES");
sb.Append(" (@a, @b); ");
sb.Append("SELECT CAST(SCOPE_IDENTITY() AS Int)");
上面的SQL构造代码用于SQLServer,你用command.ExecuteScalar试试看
或者一个object 类型的数据
你自己强制转换就好了 (int)cmd.ExecuteScaler()所以InsertCommand需要自己重写吧。
你用这种方法写.update成功后再刷新一下数据(select)即可得到.如果要insert语句后获取刚刚插入的id,就用SCOPE_IDENTITY()或@@IDENTITY,推荐SCOPE_IDENTITY().
这两个是有区别的.你可以查一下
SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值
1)要么就是基于store procedure,我不愿用store procedure,因为这降低了程序本身的聚合度。这是另外一个话题了,结构化程序的耦合和聚合问题。
2)要么就是跑完我的语句以后来个select max(id),这需要我在insert之前就要将表锁住,我不大想把表锁住,因为其实我要面对的只是一条新记录而已。
能在我的语句后稍加修改就能获得吗?这其实是原来ADO,RDO,DAO等可以刷新一下即可完成的事。
存储过程你早晚都要接触。为何不从现在做起?以下文字来自MSDN
SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY 是相似的函数,因为它们都返回插入到标识列中的值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。有关详细信息,请参阅 IDENT_CURRENT (Transact-SQL)。SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。例如,有两个表 T1 和 T2,并且在 T1 上定义了 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。该方案演示了两个作用域:在 T1 上的插入,以及在 T2 通过触发器的插入。假设 T1 和 T2 都有标识列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。@@IDENTITY 将返回在当前会话中的任何作用域内插入的最后一个标识列的值。这是在 T2 中插入的值。SCOPE_IDENTITY() 将返回在 T1 中插入的 IDENTITY 值。这是在同一个作用域内发生的最后的插入。如果在任何 INSERT 语句作用于作用域中的标识列之前调用 SCOPE_IDENTITY() 函数,则该函数将返回空值。如果语句和事务失败,它们会更改表的当前标识,从而使标识列中的值出现不连贯现象。即使未提交试图向表中插入值的事务,也永远无法回滚标识值。例如,如果因 IGNORE_DUP_KEY 冲突而导致 INSERT 语句失败,表的当前标识值仍然会增加。
看我18楼怎么回复的
你用你的方法写.update成功后再刷新一下数据(select一下)即可得到.
现在,我需要的是想如何在这段代码上做些修改,让他跑起来。
[ID] [int] IDENTITY (1, 1) NOT NULL ,
[UserName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[Attemp_Login_Time] [datetime] NULL
) ON [PRIMARY]private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=book;User ID=sa;Password=");
SqlCommand cmd = new SqlCommand("Select * from systemlog Where id is null", con);
SqlDataAdapter ad = new SqlDataAdapter(cmd);
SqlCommandBuilder bd = new SqlCommandBuilder(ad);
ad.InsertCommand = bd.GetInsertCommand();
DataTable tb = new DataTable();
ad.Fill(tb);
DataRow row = tb.NewRow();
tb.Rows.Add(row);
row["UserName"] = "ccc";
row["Attemp_Login_Time"] = DateTime.Now;
ad.Update(tb); //刷新
SqlDataAdapter ad2 = new SqlDataAdapter("select * from systemlog order by id desc", con);
DataTable dt2 = new DataTable();
ad2.Fill(dt2);
MessageBox.Show("rows:"+dt2.Rows.Count.ToString());
MessageBox.Show("ID="+dt2.Rows[0][0].ToString());
}
终极方法:con=new SqlConnection(sConStr);
con.Open();
SqlCommand cmd=new SqlCommand("insert into systemlog(UserName,Attemp_Login_time,Success_Flag,Re,IP_Address) values(@UserName,@Attemp_Login_time,@Success_Flag,@Re,@IP_Address);Select @ID= SCOPE_IDENTITY()",con);
cmd.Parameters.Add("@UserName", SqlDbType.VarChar, 50);
cmd.Parameters["@UserName"].Value="aaa";
cmd.Parameters.Add("@Attemp_Login_time", SqlDbType.DateTime);
cmd.Parameters["@Attemp_Login_time"].Value=DateTime.Now;
cmd.Parameters.Add("@Success_Flag", SqlDbType.Char,1);
cmd.Parameters["@Success_Flag"].Value="Y";
cmd.Parameters.Add("@Re", SqlDbType.VarChar,500);
cmd.Parameters["@Re"].Value="aaa";
cmd.Parameters.Add("@IP_Address", SqlDbType.VarChar,20);
cmd.Parameters["@IP_Address"].Value="kk";
cmd.Parameters.Add("@ID",SqlDbType.Int);
cmd.Parameters["@ID"].Direction=ParameterDirection.Output;
cmd.ExecuteNonQuery();
int iID=Convert.ToInt32(cmd.Parameters["@ID"].Value);
已经对你无语了.上边的人发的那些代码.说的那些都是让你这样做.可你非说要按你顶楼发那种办法获取.
按你顶楼那样做只能刷新一下.因为sqldataadapter.update是可以进行批insert的.
这个就行
在页面中获取一下
如何得到SqlServer的自增ID: SqlServer中的自增的ID的最后的值: SELECT SCOPE_IDENTITY() --返回插入到同一作用域中的 IDENTITY 列内的最后一个 IDENTITY 值。
SELECT @@IDENTITY --返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值
SELECT IDENT_CURRENT( 'TbName ')--不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。 一个作用域就是一个模块——存储过程、触发器、函数或批处理。因此,如果两个语句处于同一个存储过程、函数或批处理中,则它们位于相同的作用域中。
参考的例子如下: USE pubs
DROP TABLE t6
DROP TABLE t7 GO
CREATE TABLE t6(id int IDENTITY)
CREATE TABLE t7(id int IDENTITY(100,1))
GO
CREATE TRIGGER t6ins ON t6 FOR INSERT
AS
BEGIN
INSERT t7 DEFAULT VALUES
SELECT @@IDENTITY as [@@IDENTITY]
SELECT SCOPE_IDENTITY() as [SCOPE_IDENTITY]
END
GO
--end of trigger definition SELECT * FROM t6
--id is empty. SELECT * FROM t7
--id is empty.
--Do the following in Session 1
INSERT t6 DEFAULT VALUES
SELECT @@IDENTITY
/*Returns the value 100, which was inserted by the trigger.*/ SELECT SCOPE_IDENTITY()
/* Returns the value 1, which was inserted by the
INSERT stmt 2 statements before this query.*/ return
SELECT IDENT_CURRENT( 't7 ')
/* Returns value inserted into t7, i.e. in the trigger.*/ SELECT IDENT_CURRENT( 't6 ')
/* Returns value inserted into t6, which was the INSERT statement 4 stmts before this query.*/ -- Do the following in Session 2
SELECT @@IDENTITY
/* Returns NULL since there has been no INSERT action
so far in this session.*/ SELECT SCOPE_IDENTITY()
/* Returns NULL since there has been no INSERT action
so far in this scope in this session.*/ SELECT IDENT_CURRENT( 't7 ')
/* Returns the last value inserted into t7.*/
总结:
对于马上使用的刚才插入的新记录ID用SCOPE_IDENTITY()是最合适的;
对于想要得到一系列的操作中最后得到的那个自增的ID最好用@@IDENTITY;
对于想要得到一个表中的最后一个插入操作所产生的ID的最好用IDENT_CURRENT( 'TBName ') http://topic.csdn.net/t/20041114/18/3551908.html
Public Function AddProductCategory( _
ByVal newName As String, ByVal connString As String) As Integer
Dim newProdID As Int32 = 0
Dim sql As String = _
"INSERT INTO Production.ProductCategory (Name) VALUES (@Name); " _
& "SELECT CAST(scope_identity() AS int);" Using conn As New SqlConnection(connString)
Dim cmd As New SqlCommand(sql, conn)
cmd.Parameters.Add("@Name", SqlDbType.VarChar)
cmd.Parameters("@Name").Value = newName
Try
conn.Open()
newProdID = Convert.ToInt32(cmd.ExecuteScalar())
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using Return newProdID
End Function
C# 复制代码
static public int AddProductCategory(string newName, string connString)
{
Int32 newProdID = 0;
string sql =
"INSERT INTO Production.ProductCategory (Name) VALUES (@Name); "
+ "SELECT CAST(scope_identity() AS int)";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("@Name", SqlDbType.VarChar);
cmd.Parameters["@name"].Value = newName;
try
{
conn.Open();
newProdID = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return (int)newProdID;
}