无法启用约束。 一行或多行包含违反非空,唯一或外键约束的值

我做了一个外连接,并成功地在informix数据库中执行,但是在我的代码中出现以下exception:

 DataTable dt = TeachingLoadDAL.GetCoursesWithEvalState(i, bat); 

无法启用约束。 一行或多行包含违反非空,唯一或外键约束的值。

我知道这个问题,但我不知道如何解决这个问题。

我使外部联接的第二个表包含一个复合主键,在以前的外部联接查询中为空。

编辑:

  SELECT UNIQUE a.crs_e, a.crs_e || '/ ' || a.crst crs_name, b.period, b.crscls, c.crsday, c.from_lect, c.to_lect, c.to_lect - c.from_lect + 1 Subtraction, c.lect_kind, e.eval, e.batch_no, e.crsnum, e.lect_code, e.prof_course FROM rlm1course a, rfc14crsgrp b, ckj1table c, mnltablelectev d, OUTER(cc1assiscrseval e) WHERE a.crsnum = b.crsnum AND b.crsnum = c.crsnum AND b.crscls = c.crscls AND b.batch_no = c.batch_no AND c.serial_key = d.serial_key AND c.crsnum = e.crsnum AND c.batch_no = e.batch_no AND d.lect_code= e.lect_code AND d.lect_code = .... AND b.batch_no = .... 

问题发生在表cc1assiscrseval 。 主键是(batch_no,crsnum,lect_code)。

如何解决这个问题?


编辑:

根据@PaulStockbuild议:我做他所说的,我得到:

? dt.GetErrors()[0] {System.Data.DataRow} HasErrors:true ItemArray:{object [10]} RowError:“列'eval'不允许DBNull.Value。

所以我解决了我的问题,通过replacee.evalNVL (e.eval,'') eval 。这解决了我的问题。 非常感谢。

此问题通常是由下列之一引起的

  • 为未设置为AllowDBNull的列返回空值
  • 使用相同的主键返回重复的行。
  • 数据库和数据集之间的列定义(例如,char字段的大小)不匹配

如果结果集不是太大,请尝试本机运行查询并查看结果。 如果你已经消除了空值,那么我的猜测是主键列被重复。

或者,要查看确切的错误,您可以手动添加一个Try / Catch块到生成的代码中,然后在发生exception时中断:

在这里输入图像说明

然后在命令窗口中,调用GetErrors方法获取错误。
对于C#来说,命令会是? dataTable.GetErrors() ? dataTable.GetErrors()
对于VB来说,命令是? dataTable.GetErrors ? dataTable.GetErrors

在这里输入图像说明

这将显示所有有错误的数据行。 你可以看看RowError中的每一个,它会告诉你这个问题的列是无效的。 因此,要查看错误的第一个数据行错误,该命令是:
? dataTable.GetErrors(0).RowError
或者在C#中呢? dataTable.GetErrors()[0].RowError ? dataTable.GetErrors()[0].RowError

在这里输入图像说明

您可以禁用数据集上的约束。 它将允许您识别不良数据并帮助解决问题。

例如

 dataset.TableA.Clear(); dataset.EnforceConstraints = false; dataAdapter1.daTableA.Fill(dataset, TableA"); 

填充方法可能会略有不同。

  • 确保表适配器查询中指定的字段与您定义的查询中的字段匹配。 DAL似乎不喜欢不匹配。 在将新字段添加到表后,这通常会发生在您的sprocs和查询中。

  • 如果您更改了数据库中varchar字段的长度,并且XSS文件中包含的XML没有find,请在XML中查找字段名称和属性定义,然后手动更改它。

  • 如果表格适配器中的select列表中的主键与正在返回的数据无关,请将其移除。

  • 在SQL Management Studio中运行您的查询,并确保没有重复的logging被返回。 重复logging可能会生成重复的主键,这将导致此错误。

  • SQL工会可以拼出麻烦。 我通过在其他人之前添加一个“请select员工”logging来修改了一个表格适配器。 对于其他领域,我提供了虚拟数据,包括例如长度为1的string。 DAL从最初的logging中推断出模式。 以下string长度为12的logging失败。

这将查找表中有错误的所有行,打印出该行的主键以及该行发生的错误…

这是在C#中,但将其转换为VB应该不难。

  foreach (DataRow dr in dataTable) { if (dr.HasErrors) { Debug.Write("Row "); foreach (DataColumn dc in dataTable.PKColumns) Debug.Write(dc.ColumnName + ": '" + dr.ItemArray[dc.Ordinal] + "', "); Debug.WriteLine(" has error: " + dr.RowError); } } 

糟糕 – 对不起,PKColumns是我扩展DataTable时添加的,它告诉我组成DataTable主键的所有列。 如果您知道数据表中的主键列,则可以在这里遍历它们。 在我的情况下,因为我所有的数据表知道他们的PK列我可以写这些错误自动debugging所有表。

输出如下所示:

 Row FIRST_NAME: 'HOMER', LAST_NAME: 'SIMPSON', MIDDLE_NAME: 'J', has error: Column 'HAIR_COLOR' does not allow DBNull.Value. 

这对我来说,来源: 这里

我有这个错误,这是不相关的DB约束(至less在我的情况)。 我有一个.xsd文件与GetRecord查询返回一组logging。 该表中的一列是“nvarchar(512)”,在项目的中间,我需要将其更改为“nvarchar(MAX)”。

一切正常,直到用户input超过512字段,我们开始得到着名的错误信息“无法启用约束。一个或多个行包含违反非空,唯一或外键约束的值”。

解决scheme:检查DataTable中所有列的MaxLength属性。

我从“nvarchar(512)”更改为“nvarchar(MAX)”的列在MaxLength属性中仍然有512个值,所以我改为“-1”,它的工作原理是!!

这个错误也显示在我的项目中。 我尝试了这里发布的所有build议解决scheme,但没有运气,因为问题与字段大小,表键字段定义,约束或EnforceConstraints数据集variables无关。

在我的情况下,我也有一个.xsd对象,我在项目devise时(数据访问层)放在那里。 在将数据库表对象拖放到数据集可视项中时,它会从基础数据库中读取每个表定义,并将约束复制到数据集对象中,就像您在数据库中创build表时所定义的一样(在我的SQL Server 2008 R2中案件)。 这意味着每个使用“not null”或“foreign key”约束创build的表列也必须出现在SQL语句或存储过程的结果中。

在我把所有的键列和定义为“not null”的列都包含进我的查询之后,问题完全消失了。

问题在于数据访问devise器。 在Visual Studio中,当我们从“服务器资源pipe理器”中将视图拉到devise器窗口时,它将随机添加一个主键或者将一些东西标记为NOT NULL,尽pipe它实际上设置为null。 虽然在SQL数据库服务器中创build实际的视图,但没有定义任何主键或定义了NOT NULL,VSdevise者正在添加此键/约束。

您可以在devise器中看到它 – 它显示在列名左侧的一个关键图标上。

解决scheme:右键点击钥匙图标,然后select“删除钥匙”。 这应该解决问题。 您也可以右键单击列并select“属性”以查看VS Data访问devise器中列的属性列表,并适当更改值。

这听起来可能是一个或多个被选中的列:

  e.eval, e.batch_no, e.crsnum, e.lect_code, e.prof_course 

在您的数据集定义中将AllowDBNull设置为False

不清楚为什么运行SELECT语句应该包含启用约束。 我不知道C#或相关技术,但我知道Informix数据库。 如果您的查询代码启用(也可能禁用)约束,则系统会有一些奇怪的事情发生。

您还应该避免使用老式的,非标准的Informix OUTER连接表示法。 除非您使用的是Informix的不可能的旧版本,否则您应该使用SQL-92连接风格。

你的问题似乎提到了两个外部连接,但在示例查询中只显示一个连接。 这也有点令人费解。

e ”和其他表格的join条件是:

 AND c.crsnum = e.crsnum AND c.batch_no = e.batch_no AND d.lect_code= e.lect_code 

这是一个不寻常的组合。 由于我们没有相关的参照完整性约束的模式的相关子集,很难知道这是否正确,但是像这样的3个表之间join是有点不寻常的。

这些都不是对你问题的明确答案。 但是,它可能会提供一些指导。

感谢所有迄今为止提出的意见。 我只是想补充一点,虽然一个人可能已经成功地规范了数据库,更新了任何模式更改到他们的应用程序(如数据集)左右,还有另一个原因:SQL CARTESIAN产品(当在查询中join表)。

笛卡尔式查询结果的存在会导致两个或更多表正在联接的主(或键优先)表中的重复logging。 即使在SQL中指定了“Where”子句,如果与辅助表的JOIN例如包含不相等的联接(在从2个或更多联合关系表中获取数据时有用),笛卡儿仍可能发生:

FROM tbFirst INNER JOIN tbSystem ON tbFirst.reference_str <> tbSystem.systemKey_str

这个解决scheme:表格应该是相关的。

谢谢。 chagbert

我通过将其从false更改为true来解决同样的问题。 最后,我进入数据库,并改变了我的位域允许null,然后刷新我的xsd,并刷新我的wsdl和reference.cs,现在一切都很好。

 this.columnAttachPDFToEmailFlag.AllowDBNull = true; 

当我在xsd文件中的数据表的date字段上设置AllowDBNull为True时,Mine开始工作。

DirectCast(dt.Rows(0),的DataRow).RowError

这直接给出错误

如果您正在使用Visual Studio数据集devise器来获取数据表,并且正在抛出一个错误“无法启用约束”。 我遇到了同样的问题,尝试从数据集devise器本身预览数据,并将其与数据库中的表匹配。

解决此问题的最佳方法是删除表格适配器并创build一个新的表格。

*次要方法:*


如果你不需要[id]作为主键,

删除其主键属性:

在你的DataSet> TableAdapter>右击[id]列>select删除键…

问题将被修复。

我也遇到了这个问题,在修改* .xsd以反映在底层SQL服务器中修改的列的大小后,问题就解决了。

为了解决这个错误,我从数据集devise器中取出了麻烦的表格适配器,并保存了数据集,然后从服务器资源pipe理器中拖出了表格适配器的新副本,并将其修复

我解决了这个问题,通过用XML阅读器打开.xsd文件,并删除了我的一个视图上的约束。 无论出于什么原因,当我将视图添加到数据中时,它将一个主键约束添加到其中一个列中。

另一种方法是正常打开.xsd文件,查看导致问题的表格/视图,并删除不应该出现的任何键(右键单击列,selectdelete key )。

只是想为上面列出的exception添加另一个可能的原因(特别是对于喜欢手动定义数据集模式的人):

当你在数据集中有两个表,并且存在从第一个表字段( chfield )到第二个表字段( pfield )定义的关系( DataSet.Reletions.Add() )时,就像是向该字段添加了一个隐式约束即使它可能没有在你的定义中明确指定,也不是唯一的也不是主键。

因此,如果你在父域( pfield )中有重复值的行,你也会得到这个exception。

在我的情况下,这个错误是由string列的大小引起的。 奇怪的是,当我在不同的工具中执行完全相同的查询时,重复值和空值都不存在。

然后我发现string列大小的大小是50,所以当我调用fill方法时,值被切碎,抛出这个exception。
我点击列并将属性的大小设置为200,错误消失了。

希望这个帮助

最初我正在调用一个返回一列的查询,并将查询输出存储到DataTable中。

我得到相同的错误消息,直到我修改查询并返回表适配器中定义的所有列。

然后,我从返回的DataTable的索引中select特定的列