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


168

我进行了外部联接并在informix数据库中成功执行,但是在代码中收到以下异常:

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

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

我知道问题所在,但不知道如何解决。

我进行外部联接的第二个表包含一个复合主键,在上一个外部联接查询中该主键为null。

编辑:

    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.GetErrors()[0] {System.Data.DataRow} HasErrors:true ItemArray:{object [10]} RowError:“列'eval'不允许DBNull.Value。”

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


当我,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_course从查询中删除所有内容时,一切正常。请问是什么问题。
Anyname Donotcare 2011年

ADO.NET中还有一个错误,其中“非唯一聚集索引”将在DataTable上创建错误的Data.UniqueConstraint项。
Brain2000 '18

Answers:


352

此问题通常是由以下原因之一引起的

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

如果结果集不太大,请尝试以本机方式运行查询并查看结果。如果您消除了空值,那么我的猜测是主键列正在重复。

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

在此处输入图片说明

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

在此处输入图片说明

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

在此处输入图片说明


4
非常感谢 。>? dt.GetErrors()[0] {System.Data.DataRow} HasErrors: true ItemArray: {object[10]} RowError: "Column 'eval' does not allow DBNull.Value."
Anyname Donotcare 2011年

4
太棒了 那没有用,但是我可以添加一个监视数据集,然后在其后键入.GetErrors并扩展值。那是非常有用的。希望我在下次需要它之前不会忘记它:)
dwidel

6
是的,这确实很有帮助-我的错误原因是字段长度比表适配器中列的maxLength长。我注意到的一件事是,要在设计器文件中达到断点,您需要转到“工具”>“选项”>“调试”,并确保未选中“启用我的代码”。然后,它将允许您逐步浏览设计器文件代码。
e-on 2012年

1
感谢@PaulStock给您答复,我也解决了同样的问题。
Uday

1
这非常有用,我发现数据列长度不匹配-数据库中而不是数据集中的长度不匹配。
罗布

38

您可以禁用数据集上的约束。这将使您能够识别不良数据并帮助解决问题。

例如

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

填充方法可能对您略有不同。


1
这帮助我找到了引起问题的数据,这不是“不良数据”,而是数据源配置向导的不良行为。尽管外出并与DB通讯……并且未启用缓存,但显然并没有获得修订的列约束(并且我缺少引导添加的表)。
fortboise 2012年

感谢您的回答。我遇到了区分大小写的问题,只需要在数据集中适当地设置它即可。
2014年

10

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

这在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 col,因此我可以为所有表自动编写针对这些错误的调试。

输出看起来像这样:

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

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


1
找出错误原因的绝佳方法。在我继承的数据不一致的解决方案中,完全帮助我解决了问题。尽管它位于DataSet上,但我只是遍历每个表,然后遍历每一行。如果可以的话,+ 10。
安德斯

这对我有用。这是一个Column 'MyColumn' does not allow DBNull.Value,但没有其他方式显示。谢谢:)
亚历克斯

7
  • 确保表适配器查询中命名的字段与您定义的查询中的字段匹配。DAL似乎不喜欢不匹配。在向表中添加新字段后,存储和查询通常会发生这种情况。

  • 如果您已更改数据库中varchar字段的长度,而XSS文件中包含的XML尚未选择它,请在XML中找到字段名称和属性定义并手动进行更改。

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

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

  • SQL联合会带来麻烦。我通过在其他适配器之前添加“请选择一名雇员”记录来修改一个适配器。对于其他字段,我提供了伪数据,包括例如长度为一的字符串。DAL从该初始记录推断出架构。后面跟着长度为12的字符串的记录失败。


1
欢迎来到SO,鲍勃 我已经编辑了您的答案(不过仍在审核中)。例如,我们不希望答案中带有问候语和签名(被认为是“ noice”,请参阅FAQ)。无论如何,您的名字和头像将始终显示在答案下方。
Christoffer Lette 2012年

5

这对我有用,来源:这里

我遇到此错误,并且它与数据库约束无关(至少在我的情况下)。我有一个带有GetRecord查询的.xsd文件,该记录返回一组记录。该表的其中一列是“ nvarchar(512)”,在项目的中间,我需要将其更改为“ nvarchar(MAX)”。

一切正常,直到用户在该字段上输入了512个以上,并且我们开始收到著名的错误消息“未能启用约束。一个或多个行包含违反非空,唯一或外键约束的值”。

解决方案:检查数据表中列的所有MaxLength属性。

我从“ nvarchar(512)”更改为“ nvarchar(MAX)”的列在MaxLength属性上仍然具有512值,因此我更改为“ -1”,它可以正常工作!!


我的问题也一定是MaxLength。我使用VWD 2010数据集设计器。源表已被其他人更改。我将SQL Query修改为select *,认为可以刷新所有列,但显然它不会更新现有长度。因此,我修改了查询以选择一个字段,保存了.xsd,在Notepad ++中打开了.xsd,以检查除MaxLength定义之外的所有定义均已消失,然后再次将查询修改为select *。刷新了MaxLengths,让我克服了这个错误。
马克·贝里

非常感谢您,我整天都在抓头,因为一切都恢复正常。我还必须更改为nvarchar(MAX),但是DataTable的MaxLength保持为10!我欠你一杯!
Jon D

4

问题出在数据访问设计器上。在Visual Studio中,当我们将视图从“服务器资源管理器”拉到“设计器”窗口时,它实际上是在列上随机添加主键,或者将某些内容标记为NOT NULL,尽管实际上它设置为null。尽管在SQL数据库服务器中实际创建了View,但没有定义任何主键或未定义NOT NULL,但是VS设计器正在添加此Key / constraint。

您可以在设计器中看到它-列名的左侧显示有一个钥匙图标。

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


3

此错误也显示在我的项目中。我尝试了此处发布的所有建议的解决方案,但没有任何运气,因为该问题与字段大小,表键字段定义,约束或EnforceConstraints数据集变量无关。

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

在将所有关键列以及定义为“非空”的列包含到查询中之后,问题完全消失了。


3

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


2

听起来可能是通过以下方式选择了一个或多个列:

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

AllowDBNull设置为数据集中的确定指标。


我对表中的所有列都允许allow null = true,但徒劳。
Anyname Donotcare 2011年

2

目前尚不清楚为什么运行SELECT语句应该涉及启用约束。我不了解C#或相关技术,但是我知道Informix数据库。如果您的查询代码正在启用​​(并且可能还会禁用)约束,那么系统发生了一些奇怪的事情。

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

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

e”与其余表之间的连接条件为:

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

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

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


2

感谢您到目前为止所做的所有输入。我只是想补充一点,尽管一个人可能已经成功地标准化了DB,更新了对其应用程序(例如,对数据集)的任何模式更改,等等,但是还有另一个原因:sql CARTESIAN产品(在查询中加入表时)。

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

从tbFirst内联接tbSystem ON tbFirst.reference_str <> tbSystem.systemKey_str

解决方案:表应该相关。

谢谢。查格伯特


1

我通过将其从false更改为true解决了相同的问题。最后,我进入数据库并更改了bit字段以允许为null,然后刷新了xsd,刷新了wsdl和reference.cs,现在一切正常。

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

简单易用的解决方案:

转到MSSQL Studio服务器;

运行此错误原因的查询:在我的情况下,我看到id值为null,因为我忘记将Identity规范增量设置为1。

在此处输入图片说明

所以为id字段输入1,因为它是autoincremane,并且在设计视图中修改为不允许NULL

在此处输入图片说明

那是导致我的绑定源和表格适配器抛出此代码的错误的错误:

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

0

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

这直接给出了错误


2
很好的建议,但这仅在数据表的第一行出现错误时才有效,不是吗?如果返回100个好行,然后返回1个坏行,则不会出现RowErroron Rows(0),会吗?
PaulStock 2012年

0

如果您使用Visual Studio数据集设计器来获取数据表,则会引发错误“无法启用约束”。我遇到了同样的问题,请尝试从数据集设计器本身预览数据并将其与数据库中的表进行匹配。

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


0

*次要方式:*


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

删除其主键属性:

在数据集> TableAdapter上>右键单击[id]列>选择Delete key ...

问题将得到解决。


0

我也遇到了这个问题,在修改* .xsd以反映基础SQL服务器中更改的列的修订大小后,此问题已得到解决。


0

要解决此错误,我从数据集设计器中卸下了麻烦的表适配器,并保存了数据集,然后从服务器资源管理器中拖动了表适配器的新副本,并对其进行了修复。


0

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

另一种方法是正常打开.xsd文件,查看引起问题的表/视图,然后删除所有delete key不应该存在的键(右键单击列,选择)。


0

只想为上述例外添加另一个可能的例外原因(特别是对于那些希望手动定义数据集架构的人):

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

因此,如果您在该父字段(pfield)中包含具有重复值的行,那么您也会收到此异常。


0
            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();
                }
            }

0

我收到了相同的错误类型,在我的情况下,它通过删除选择字段并将其替换为*来解决了该错误。不知道为什么会这样。该查询没有错别字或任何花哨的东西。

不是最好的解决方案,但没有其他解决方案,我精疲力尽。

在寻找明确答案的过程中,我发现了以下内容:https : //www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

解决方案8

使用Visual Studio 2010在我的项目中也显示了此错误。我尝试了其他博客上发布的其他解决方案,但是一点都不走运,因为该问题与字段大小,表键字段定义,约束或EnforceConstraints数据集变量无关。

就我而言,我有一个.xsd对象,该对象在项目设计期间(在数据访问层中)放置在该对象中。将数据库表对象拖到“数据集”可视项中时,它将从基础数据库读取每个表定义,并将约束复制到Dataset完全按照在数据库中创建表时定义的定义对象中(在我的例子中是SQL Server 2008 R2 )。这意味着使用“ not null”或“ foreign key”约束创建的每个表列也必须出现在SQL语句或存储过程的结果中。

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

也许您不需要所有表列都出现在查询/存储过程结果中,但是由于仍然应用了约束,因此如果某些约束列未出现在结果中,则会显示错误。

希望这对其他人有帮助。


-1

在我的情况下,此错误是由字符串列的大小引起的。奇怪的是,当我在不同的工具中执行完全相同的查询时,没有重复的值或null值。

然后,我发现字符串列的大小为50,因此当我调用fill方法时,该值被切碎,并抛出此异常。
我单击该列,然后在属性中将大小设置为200,错误消失了。

希望有帮助


-1

我通过执行“ subselect”来解决此问题:

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

在mysql上执行此操作时,所有collunms属性(唯一,非null ...)将被清除。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.