未能启用约束。一行或多行包含违反非空、唯一或外键约束的值

我创建了一个外部连接并在 informix数据库中成功执行,但在代码中遇到了以下异常:

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)。

如何解决这个问题?


编辑:

根据 @PaulStock的建议: 我照他说的做了,然后我得到了:

? dt. GetError ()[0]{ System. Data. DataRow } HasError: true ItemArray: { object [10]} RowError: “列‘ eval’不允许 DBNull.Value。”

所以我通过把 e.eval替换成 NVL (e.eval,'') eval来解决我的问题,这也解决了我的问题。 非常感谢。

261124 次浏览

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

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

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

此问题通常由下列原因之一引起

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

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

或者,为了查看确切的错误,您可以像这样手动向生成的代码添加一个 Try/Catch 块,然后在引发异常时中断:

enter image description here

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

enter image description here

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

enter image description here

目前尚不清楚为什么运行 SELECT 语句需要启用约束。我不了解 C # 或相关技术,但我了解 Informix 数据库。如果您的查询代码正在启用(可能也在禁用)约束,那么系统会出现一些奇怪的情况。

您还应该避免使用老式的、非标准的 InformixOUTER 连接符号。除非您使用的是不可能的老版本 Informix,否则应该使用 SQL-92风格的连接。

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

e”与其他表之间的连接条件是:

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

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

这些都不是您问题的确切答案; 但是,它可以提供一些指导。

  • 确保表适配器查询中命名的字段与您定义的查询中的字段相匹配。DAL 似乎不喜欢不匹配。这通常发生在向表中添加新字段之后的 sprocs 和查询中。

  • 如果已经更改了数据库中 varchar 字段的长度,而 XSS 文件中包含的 XML 没有识别该字段,请在 XML 中查找字段名和属性定义并手动更改它。

  • 如果主键与要返回的数据无关,则从表适配器中的选择列表中删除主键。

  • 在 SQLManagementStudio 中运行查询,并确保没有返回重复记录。重复的记录可以生成重复的主键,这将导致此错误。

  • SQL 联合可能会带来麻烦。我修改了一个表适配器,在其他表适配器之前添加了一条“请选择一名员工”记录。对于其他字段,我提供了虚拟数据,例如长度为1的字符串。DAL 从该初始记录推断出模式。以下记录长度为12的字符串失败。

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

例如:。

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

对于您来说,fill 方法可能略有不同。

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

这直接给出了错误

这个错误也显示在我的项目中。我尝试了这里提出的所有解决方案,但一点运气都没有,因为问题与字段大小、表关键字字段定义、约束或 EnforcConstraint 数据集变量无关。

在我的例子中,我也有一个。Xsd 对象,我在项目设计时放在那里(数据访问层)。当您将数据库表对象拖动到 Dataset 可视项中时,它会从底层数据库中读取每个表定义,并将约束完全按照在数据库中创建表时的定义复制到 Dataset 对象中(在我的例子中是 SQL Server 2008 R2)。这意味着,在 SQL 语句或存储过程的结果中,还必须包含用“非空”或“外键”约束创建的每个表列。

在将所有键列和定义为“ not null”的列包含到查询中之后,问题就完全消失了。

这对我有用,来源: 给你

我有这个错误,它与 DB 约束无关(至少在我的例子中是这样)。我有一个。带有返回一组记录的 GetRecord 查询的 xsd 文件。该表中的一列是“ nvarchar (512)”,在项目进行到一半时,我需要将其更改为“ nvarchar (MAX)”。

一切工作正常,直到用户在该字段输入超过512,我们开始得到著名的错误消息“未能启用约束。一行或多行包含违反非空、唯一或外键约束的值。”

解决方案: 检查 DataTable 中列的所有 MaxLlength 属性。

我从“ nvarchar (512)”更改为“ nvarchar (MAX)”的列在 MaxLlength 属性上仍然有512值,所以我更改为“-1”,它工作了! !.

这将查找表中所有有错误的行,打印出该行的主键和该行发生的错误..。

这是在 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 协议,我可以为所有表自动编写这些错误的调试。

输出如下:

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

如果您对上面的 PKColumns 部分感到困惑-这将打印出列名称和值,并且不是必需的,但是为识别哪些列值可能导致问题添加了有用的故障排除信息。删除此部分并保留其余部分仍将打印正在生成的 SQLite 错误,该错误将指出存在问题的列。

如果您正在使用可视化工作室数据集设计器来获取数据表,并且它正在抛出一个错误“未能启用约束”。我遇到过同样的问题,尝试从数据集设计器本身预览数据,并将其与数据库中的表匹配。

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

谢谢你到目前为止提供的信息。我只想补充一点,虽然一个人可能已经成功地规范化了数据库,更新了他们的应用程序的任何模式更改(例如数据集) ,还有另一个原因: sql 笛卡儿积(当在查询中连接表时)。

笛卡尔查询结果的存在将导致连接两个或多个表的主表(或键优先)中出现重复记录。 即使您在 SQL 中指定了一个“ Where”子句,如果 JOIN 与次要表包含不等的连接(当从2个或更多个不相关的表获取数据时很有用) ,笛卡尔函数仍然可能出现:

从 tbFirst 内连接 TbSystem ON tbFirst.reference _ str < > tbSystem.systemKey _ str

解决方案: 表应该是相关的。

谢谢,查格伯特

* 次要方法: *


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

删除其主键属性:

在 DataSet > TableAdapter > 右键单击[ id ] column > select Delete key..。

问题会解决的。

我也有这个问题,在修改 * 之后就解决了。Xsd 来反映底层 SQL 服务器中更改的列的修改后的大小。

我解决了同样的问题,把这个从假变成了真。最后,我进入数据库,将 bit 字段更改为允许 null,然后刷新 xsd,刷新 wsdl 和 reference. cs,现在一切正常。

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

我通过打开。使用 XML 阅读器并删除放置在我的一个视图上的约束的 xsd 文件。不管出于什么原因,当我将视图添加到数据中时,它向其中一个列添加了一个主键约束,而这个列本不应该存在。

另一种方法是打开。正常情况下,查看导致问题的表/视图并删除不应该出现的任何键(右键单击 column,选择 delete key)。

为了修复这个错误,我从 Dataset 设计器中取下令人不安的表适配器,并保存数据集,然后从服务器资源管理器中拖动表适配器的一个新副本并修复它

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

当你的数据集中有两个表,并且在第一个表的字段(chfield)和第二个表的字段(pfield)之间定义了一个关系(DataSet.Reletions.Add())时,就像在该字段中添加了一个隐式约束,即 独一无二,尽管在你的定义中可能没有明确指定它是唯一的或者主键。

因此,如果在父字段(pfield)中有具有重复值的行,也会得到这个异常。

当我在 xsd 文件中的数据表的日期字段上将 AllowDBNull设置为 True 时,我的工作就开始了。

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

然后我发现字符串列的大小是50,所以当我调用 fill 方法时,该值被删除,抛出了这个异常。
我点击列并将属性的大小设置为200,错误就消失了。

希望这能帮上忙

问题出在数据访问设计器上。在 Visual Studio 中,当我们将一个视图从“ Server Explorer”拉到 Designer 窗口时,它要么在列上随机添加一个主键,要么将某些内容标记为 NOT NULL,尽管它实际上被设置为 NULL。虽然在 SQL db 服务器中实际创建的 View 没有定义任何主键或者定义 NOT NULL,但是 VS 设计器正在添加这个 Key/约束。

您可以在设计器中看到这一点-它与列名左侧的键图标一起显示。

解决方案: 右击键盘图标,选择“删除键”。这应该能解决问题。您还可以右键单击一个列并选择“属性”,以查看 VS 数据访问设计器中列的属性列表并适当地更改值。

我解决这个问题的方法是像这样做“子选择”:

string newQuery = "select * from (" + query + ") as temp";

在 mysql 上执行此操作时,将清除所有 colunms 属性(惟一的、非空的...)。

            using (var tbl = new DataTable())
using (var rdr = cmd.ExecuteReader())
{
tbl.BeginLoadData();


try
{
tbl.Load(rdr);
}
catch (ConstraintException ex)
{
rdr.Close();
tbl.Clear();


// clear constraints, source of exceptions
// note: column schema already loaded!
tbl.Constraints.Clear();
tbl.Load(cmd.ExecuteReader());
}
finally
{
tbl.EndLoadData();
}
}

我收到了相同的错误类型,在我的例子中,它通过删除选择字段并用 * 替换它们来解决这个问题。不知道为什么会这样。该查询没有任何拼写错误或任何花哨的东西。

这不是最好的解决办法,但其他方法都不管用,我已经精疲力尽了。

在我寻找一个明确答案的过程中,我发现了这样一个问题: Https://www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

解决方案8

使用 VisualStudio2010,此错误也显示在我的项目中。我尝试了在其他博客上发布的其他解决方案,但一点运气都没有,因为这个问题与字段大小、表关键字字段定义、约束或 EnforceConstraints数据集变量没有任何关系。

在我的情况下,我有一个。Xsd 对象,我在项目设计时放在那里(在数据访问层)。当您将数据库表对象拖动到 Dataset 可视项中时,它会从底层数据库中读取每个表定义,并将约束完全复制到 Dataset对象中,就像您在数据库中创建表时所定义的那样(在我的例子中是 SQL Server 2008 R2)。这意味着,在 SQL 语句或存储过程的结果中,还必须包含用“非空”或“外键”约束创建的每个表列。

在将所有受约束的列(非 null、主键、外键等)包含到查询中之后,问题就完全消失了。

也许您不需要在查询/存储过程结果中显示所有的表列,但是因为仍然应用了约束,所以如果某些受约束的列没有出现在结果中,就会显示错误。

希望这能帮到别人。

简单明了的解决方案:

转到 MSSQL Studio 服务器;

运行导致这个错误的查询: 在我的例子中,我看到 id 值为 null,因为我忘记设置 身份规范增量为1。

enter image description here

因此,在 id 字段中输入1,因为它是自动递增的,并且在设计视图中修改不允许 NULLS

enter image description here

这个错误导致我的 bindingsource 和 tabel 适配器在这段代码中出现抛出错误:

   this.exchangeCheckoutReportTableAdapter.Fill(this.sbmsDataSet.ExchangeCheckouReportTable);

如果 DataSet (而不是 DataTable)失败:

if (dataSet.HasErrors)
foreach (DataTable table in dataSet.Tables)
if (table.HasErrors)
foreach (var row in table.GetErrors())
Debug.Write($"Error in DataTable {table.TableName}: {row.RowError}")


如果 _ sample _ DataSet 是在填充时遇到错误的数据集的名称,那么您可以将填充数据集放在 Trycatch 中,然后将以下代码放在 Catch {}块中,那么您就能够准确地找到错误的列。

            foreach (DataTable _dtable in _sample_DataSet.DataSet.Tables)
{
foreach (DataRow dr in _dtable.Rows)
{
if (dr.HasErrors)
{
if (dr.HasErrors)
{
Debug.Write("Row error="+dr.RowError);


}
}
}