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

时间:2011-08-11 13:18:32

标签: c# asp.net sql database informix

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

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

24 个答案:

答案 0 :(得分:311)

此问题通常由以下之一引起

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

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

或者,要查看确切的错误,您可以手动将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

答案 1 :(得分:35)

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

e.g。

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

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

答案 2 :(得分:8)

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

这是在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.

答案 3 :(得分:7)

  • 确保表适配器查询中指定的字段与您定义的查询中的字段匹配。 DAL似乎不喜欢不匹配。在向表中添加新字段后,通常会对您的sprocs和查询进行此操作。

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

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

  • 在SQL Management Studio中运行查询,确保没有返回重复的记录。重复记录可能会生成重复的主键,从而导致此错误。

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

答案 4 :(得分:5)

这对我有用,来源:here

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

一切正常,直到用户在该字段上输入超过512并且我们开始得到着名的错误消息“无法启用约束。一行或多行包含违反非空,唯一或外键约束的值。 “

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

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

答案 5 :(得分:4)

问题在于数据访问设计器。在Visual Studio中,当我们从" Server Explorer"中提取视图时在Designer窗口中,它会在列上随机添加主键或将某些内容标记为NOT NULL,尽管它实际上设置为null。虽然在SQL数据库服务器中实际创建了View,但没有定义任何主键或定义了NOT NULL,VS设计者正在添加此键/约束。

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

解决方案:右键单击密钥图标,然后选择“删除密钥”。这应该可以解决问题。您也可以右键单击一列,然后选择"属性"查看VS数据访问设计器中列的属性列表并相应地更改值。

答案 6 :(得分:3)

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

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

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

答案 7 :(得分:3)

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

答案 8 :(得分: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个表之间进行连接有点不寻常。

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

答案 9 :(得分:2)

听起来可能有一个或多个列被选中:

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

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

答案 10 :(得分:2)

感谢您到目前为止所做的所有输入。我只是想添加一个,虽然可能已成功规范化数据库,更新其应用程序的任何架构更改(例如更新到数据集)左右,还有另一个原因:sql CARTESIAN产品(在查询中连接表时)。

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

  

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

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

感谢。 chagbert

答案 11 :(得分:1)

简短易解:

转到MSSQL Studio服务器;

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

enter image description here

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

enter image description here

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

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

答案 12 :(得分:1)

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

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

答案 13 :(得分:0)

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

答案 14 :(得分:0)

我通过使用XML阅读器打开.xsd文件并删除其中一个视图上的约束来解决此问题。无论出于何种原因,当我将视图添加到数据时,它会在不应该有一个列时为其中一个列添加主键约束。

另一种方法是正常打开.xsd文件,查看导致问题的表/视图,并删除不应存在的任何键(右击列,选择delete key)。

答案 15 :(得分:0)

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

答案 16 :(得分:0)

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

在您的数据集中,您有两个表,并且从第一个表的字段(DataSet.Reletions.Add())到第二个表的字段({{chfield)定义了关系(pfield) {1}}),有一个隐式约束被添加到该字段唯一,即使它在您的定义中未明确指定为既不是唯一也不是主键。< / p>

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

答案 17 :(得分:0)

*次要方式:*


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

删除其主键属性:

在您的数据集&gt; TableAdapter&gt;右键单击[id]列&gt;选择删除键...

问题将得到解决。

答案 18 :(得分:0)

如果您正在使用visual studio数据集设计器来获取数据表,则会出现错误&#39;无法启用约束&#39;。我遇到了同样的问题,尝试从数据集设计器本身预览数据,并将其与数据库中的表进行匹配。

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

答案 19 :(得分: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();
                }
            }

答案 20 :(得分:0)

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

这不是最好的解决方案,但没有其他解决办法,我已经筋疲力尽了。

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

解决方案8

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

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

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

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

希望这对其他人有帮助。

答案 21 :(得分:0)

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

这直接给出错误

答案 22 :(得分:-1)

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

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

希望这个帮助

答案 23 :(得分:-1)

我通过像这样的“subselect”解决了这个问题:

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

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