首页 新闻 会员 周边

唯一性约束问题

0
悬赏园豆:50 [已解决问题] 解决于 2014-01-15 15:28

唯一性约束问题

 

环境

Visual Studio 2008 (UNIQUE约束不允许出现重复的NULL值)

SQLite ADO.NET

SQLite 3.1.9.2085 (UNIQUE约束允许出现重复的NULL值)

 

 

数据库DBTest.db,表UNIQUE_TEST

1 CREATE TABLE [UNIQUE_TEST] (
2 [ID] INTEGER PRIMARY KEY,
3 [SNO] INTEGER NULL,
4 CONSTRAINT [UNIQUE_ID] UNIQUE([SNO])
5 );

 

 

在Visual Studio 2008的项目中新建一个包含如下清单的窗体

控件

名称

备注

DataGridView

dataGridView1

用于显示数据库中的数据

Button

btnFill

用于从数据库填充数据到DataGridView

Button

btnUpdate

用于将变更更新到数据源

 

把DBTest.db作为数据源添加到项目,在自动生成的数据集文件UNIQUE_TEST.xsd中,找到关于约束的定义,如下

1 <xs:unique name=”Constraint1” msdata:PrimaryKey=”true”>
2     <xs:selector xpath=”.//mstns:UNIQUE_TEST” />
3     <xs:field xpath=”mstns:ID” />
4 </xs:unique>

上述自动生成的代码中并无与[UNIQUE_TEST].[SNO]列对应的UNIQUE约束。

 

自定义工具生成的代码对应的文件UNIQUE_TEST.Designer.cs中,找到关于约束的定义,如下

1 this.Constraints.Add(new
2     Global::System.Data.UniqueConstraint(“Constraint1”,
3         new Global::System.Data.DataColumn[]{ this.columnID }, true));
4 this.columnID.AllowDBNull = false;
5 this.columnID.Unique = true;

上述自动生成的代码中并无与[UNIQUE_TEST].[SNO]列对应的UNIQUE约束。

 

以上是Visual Studio 2008自动生成的代码,在未修改前可正常通过Adapter.Fill()方法填充数据。

但这与要求不符。

要求:SNO列不能重复(可以不填留空)

 

此时只在数据库端有约束控制,应用程序端可以在dataGridView1中的SNO列输入重复内容,不会引发DataError事件,但执行Update操作时出现违反约束的异常。

 

 

为了在应用端控制输入数据的合法性,手动在数据集文件UNIQUE_TEST.xsd文件中对SNO列添加UNIQUE约束,如下

 1 <!— ID IS PRIMARY KEY -->
 2 <xs:unique name=”Constraint1” msdata:PrimaryKey=”true”>
 3     <xs:selector xpath=”.//mstns:UNIQUE_TEST” />
 4     <xs:field xpath=”mstns:ID” />
 5 </xs:unique>
 6 
 7 <!— SNO IS UNIQUE -->
 8 <xs:unique name=”Constraint2” >
 9     <xs:selector xpath=”.//mstns:UNIQUE_TEST” />
10     <xs:field xpath=”mstns:SNO” />
11 </xs:unique>

 

在Visual Studio 2008中重新运行自定义工具,生成的UNIQUE_TEST.Designer.cs中,关于约束的定义,如下

 1 this.Constraints.Add(new
 2     Global::System.Data.UniqueConstraint(“Constraint1”,
 3         new Global::System.Data.DataColumn[]{ this.columnID }, true));
 4 this.Constraints.Add(new
 5     Global::System.Data.UniqueConstraint(“Constraint2”,
 6         new Global::System.Data.DataColumn[]{ 
 7             this.columnSNO }, false));
 8 this.columnID.AllowDBNull = false;
 9 this.columnID.Unique = true;
10 this.columnSNO.Unique = true;

 

修改后的代码逻辑上与要求相符。

运行,在数据库中SNO列为空,行数超过1行的情况下,在填充时问题出现了:

System.Data.ConstraintException: 未能启用约束。一行或多行中包含违反非空、唯一或外键约束的值。

 

 

 

调试状态程序无法继续运行,执行状态程序崩溃。

 

 

 

问题

1. 如何在应用程序段实现要求:SNO列不能重复(可以不填留空)?

goooogs的主页 goooogs | 初学一级 | 园豆:64
提问于:2013-06-07 10:35
< >
分享
最佳答案
0

我觉得可以这样来实现:

  1. Unique_Test表中不加唯一性约束,另外建一张表Unique_Test_sno,新增一个sno列,对Unique_Test_sno表的sno列增加一个唯一性约束。
  2. 创建一个触发器,当Unique_Test表新增了一个非null的数据时,将该sno值插入Unique_Test_sno表,如果插入Unique_Test_sno表失败,则将其从Unique_Test表中删除。
  3. 创建一个触发器,当Unique_Test表删除了一个非null的数据时,将其sno值从Unique_Test_sno表中删除。

简单的说,通过触发器在Unique_Test_sno表中插入数据来限制非null的sno列唯一。

收获园豆:50
天方 | 大侠五级 |园豆:5407 | 2013-06-07 20:30

Unique列是否允许出现重复的NULL与数据库引擎有关,可以采取计算列等方式解决。

goooogs | 园豆:64 (初学一级) | 2014-01-15 15:29
其他回答(1)
0

Unique列是否允许出现重复的NULL与数据库引擎有关,可以采取计算列等方式解决。

goooogs | 园豆:64 (初学一级) | 2014-01-15 15:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册