【xmzhaoym原创,请勿转载】
-
1、自动返回自增ID自增值的方法
原理:ADO.NET对象SqlDataAdapter 在更新数据对象时,如更新DataTable或DataRow时,SqlDataAdapter 的SqlCommand对象(InsertCommand、UpdateCommand )的返回值,会自动回写到DataRow的相应字段名的值。通过这种方式可以将自增ID值和时间戳字段值返回到客户端ADO.NET对象中。具体实现要点如下:
SqlDataAdapter da = new SqlDataAdapter();
da.InsertCommand = this.insertCommand;
da.UpdateCommand = this.updateCommand;
da.DeleteCommand = this.deleteCommand;
da.Update(this.dataTable);
假设自增表结构为
CREATE TABLE Test (
ID smallint IDENTITY(1,1),
Name varchar(20) NULL,
LastChanged timestamp NULL,
PRIMARY KEY CLUSTERED (ID ASC)
)
go
InsertCommand 对应的存储过程:
CREATE PROCEDURE dbo.TestInsert
(
@Name varchar(20),
@LastChanged timestamp
)
AS
INSERT INTO dbo.Test
(
Name
)
VALUES
(
@Name
)
--关键脚本,通过Select 字段名,实现返回值。SqlDataAdapter 对象自动将返回值回写到前台DataRow对象
Select ID ,LastChanged From dbo.Test Where ID = @@IDENTITY
GO
-
2、避免数据行被多用户相互覆盖的方式
一个简单便捷的方法是在保存数据时,通过SQLSERVER2005的时间戳字段,检查数据是否被其他用户修改。
时间戳字段介绍:
时间戳字段 timestamp 是SQLSERVER2005新增的字段类型,它的作用在于:只要数据库的表增加一个时间戳字段,数据库系统将自动维护任何该表的行记录的修改时间戳,它是一个数值型,行记录只要有任何字段被修改,该时间戳字段将自动累加一个数值。这个机制,为检查行记录是否被其他用户修改提供了简单高效的支持。特别在两个副本表之间数据同步,或数据仓库需要差异读取子上次修改后的行记录,这些特备影响性能的查询,均可以用时间戳实现高效的查询。以往获取差异数据,往往要进行时间字段的对比。时间戳的数据累加基数是定位在表,也就是说时间戳的值在表里面一定是不重复的。
存储过程示例:
CREATE PROCEDURE dbo.TestUpdate
(
@ID smallint,
@Name varchar(20),
@LastChanged timestamp
)
AS
UPDATE dbo.Test SET
Name = @Name
WHERE
ID = @ID AND LastChanged=@LastChanged -- where条件加入时间戳条件,如果数据行被外部用户修改了,则时间戳值一定和当----前值不一致,导致更新0行,通过 “IF @@ROWCOUNT = 0” 判断,抛出异常,阻止外部保存
IF @@ROWCOUNT = 0
RAISERROR('Row has been edited by another user', 16, 1)
SELECT LastChanged --每次修改,时间戳都会产生新值,所以最新值必须返回到前台客户端,原理同1介绍的方法。
FROM dbo.Test WHERE ID = @ID
RETURN
UI层注意事项
WINFORM的dataGridView1控件在显示timestamp字段时,会出现异常错误。实际上用户不需要在UI看到timestamp字段。
解决的方法,隐藏或删除grid的时间戳column列。如this.dataGridView1.Columns["LastChanged"].Visible = false。