在Insert操作中刷新主键识别列

Categories: Data
Tags: No Tags
Comments: No Comments
Published on: 2010 年 06 月 18 日

[原文作者]:John Chen

[原文链接]:Refresh the Primary Key Identity Column during Insert Operation

        如果你在数据表中定义了主键标识列,当你在这个表中插入新行时,数据库引擎会自动设置它的值。这个标识值是由列的标识种子和标识递增的属性决定的。

        在客户端应用中,你可以在对应的ADO.NET 数据表中插入新行(数据表可以被看做数据库在缓存中的数据表,在本文中我会用数据表举例说明)。

        在这篇文章中,我将描述一下利用VS 数据库工具如何检索ADO.NET应用程序中的标识值。用Windows Forms Application DataSet举例,数据库服务器是SQL Server.

        首先在VS(2005或者之后的版本)服务器资源管理器中建立和一个SQL Server数据库的连接。创建一个名称为MyCustomer的表,包含三列:CustId, Name和Company. CustId被定义为主键和标识列。标识种子和标识递增为缺省值1,如下表:

clip_image001

图1 数据库中定义的MyCustomer 表

        然后我通过数据源配置向导创建DataSet,或者可以增加一个DataSet,然后将MyCustomer从服务器资源管理器拖到DataSet设计器上面。打开DataSet,学则CustId列,你将会看到它有以下的属性:AutoIncrement=True, AutoIncrementSeed = -1 , AutoIncrementStep = -1 (图2)。这些属性会被ADO.NET用来自动生成CustId新增行的占位符。

clip_image002

图2 数据表中CustId的属性

        数据库中属性AutoIncrement对应于Identity,属性AutoIncrementSeed和AutoIncrementStep 分别对应于Identity Seed和Identity Increment。你可能对AutoIncrementSeed和AutoIncrementStep都设置为-1感到奇怪。原因是这样可以保证ADO.NET生成的占位符的值不会和数据库中已有的值冲突,另外一个好处是它看起来不真实,所以用户会知道它仅仅是一个临时的占位符。

现在如果你点击MyCustomerTableAdapter header并且显示出Insert命令,你会看到:

INSERT INTO [MyCustomer] ([Name], [Company]) VALUES (@Name, @Company);

SELECT CustId, Name, Company FROM MyCustomer WHERE (CustId = SCOPE_IDENTITY())

这些命令行包括了两个语句,第二个语句在Insert操作提交后用来检索主键值。注意SCOPE_IDENTITY函数的运用,在MSDN中获取详细信息。

第二个插入语句的自动生成是由TableAdapter Configuration Wizard(表3)中的“refresh data table option”控制的。

clip_image003

3 TableAdapter Configuration Wizard中刷新数据表的高级选项

        现在让我们来体验一下在运行时应用refresh data table 功能。打开窗口,显示出Data Sources Window,将表MyCustomer拖到窗口上得到如下的布局(图4):

clip_image004

图4 设计时:将表MyCustomer从DataSourcesWindow拖到窗口上

按下F5运行,点击Add New(the+sign)按钮增加新的行,注意我会得到的CustId 列的值分别为-1,-2, -3等。

clip_image005

图5 CustForm运行时(提交之前)

现在我点击Save(the disk sign)按钮,CustId的值更新为9,10,11。哦!我本来期望的是2,3,4;

可能是有人在我操作之前增加了新的行。在这里你可以看到-1,-2,-3的优势,它们清楚的表明了没有提交的值。

clip_image006

图6 CustForm运行时(提交之后)

        现在如果你使用MS Access 数据库或者SQL CE,你将会看到以上的步骤不会像期望的那样工作。当你点击Save,主键-1,-2,-3是保持不变的。如果你检查TableAdapter Configuration Wizard, Refresh the data table 选项是不可用的。如果你检查生成的Insert命令,只有一条语句。原因是MS Access 数据库和SQL CE不支持SQL 批处理语句,因此不能使用SCOPE_IDENTITY()函数。Refresh the data table选项对于这些数据库是无效的。

        有一个好消息是找到一个解决办法,通过Adapter.RowUpdated事件重新设置主键标识值。请看Beth Massi的博客Using TableAdapters to Insert Related Data into an MS Access Database. Beth Massi 也会写一篇关于SQL CE的文章。

        总之,SQL server 或其它任何支持批处理的数据库通过使用SCOPE_IDENTITY()函数都可以可靠地检索标识值,Visual Studio Data Tool提供了自动生成Insert命令通过默认打开“Refresh the data table”选项。对于不支持批处理SQL 语句的数据库来说,通过RowUpdated事件重新设置主键值是好的解决方法。

No Comments - Leave a comment

Leave a comment


Welcome , today is 星期五, 2017 年 04 月 28 日