제약 조건을 활성화하지 못했습니다. 하나 이상의 행에 null이 아니거나 고유하거나 외래 키 제약 조건을 위반하는 값이 있습니다.


168

외부 조인을 만들어 informix데이터베이스 에서 성공적으로 실행 했지만 내 코드에서 다음 예외가 발생합니다.

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

제약 조건을 활성화하지 못했습니다. 하나 이상의 행에 null이 아니거나 고유하거나 외래 키 제약 조건을 위반하는 값이 있습니다.

문제를 알고 있지만 해결 방법을 모르겠습니다.

외부 조인을 수행하는 두 번째 테이블에는 이전 외부 조인 쿼리에서 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.eval하여 문제를 NVL (e.eval,'') eval해결하면 문제가 해결됩니다. 고마워


,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_course쿼리에서 제거하면 모든 것이 정상적으로 진행됩니다. 문제가 무엇입니까?
Anyname Donotcare

"독특하지 않은 클러스터형 인덱스"가 DataTable에 잘못된 Data.UniqueConstraint 항목을 만드는 ADO.NET의 버그도 있습니다.
Brain2000

답변:


352

이 문제는 일반적으로 다음 중 하나에 의해 발생합니다.

  • AllowDBNull로 설정되지 않은 열에 대해 null 값이 반환 됨
  • 동일한 기본 키로 리턴되는 중복 행
  • 데이터베이스와 데이터 세트 사이의 열 정의 불일치 (예 : char 필드의 크기)

쿼리를 기본적으로 실행하고 결과 집합이 너무 크지 않은 경우 결과를 확인하십시오. null 값을 제거했다면 기본 키 열이 복제되는 것 같습니다.

또는 정확한 오류를 확인하기 위해 생성 된 코드에 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

4
대박. 그것은 작동하지 않았지만 데이터 세트에 대한 시계를 추가하고 그 뒤에 .GetErrors를 입력하고 값을 확장 할 수 있습니다. 매우 유용합니다. 잘만되면 나는 다음에 내가 그것을 필요로하기 전에 그것을 잊지 않을 것이다 :)
dwidel

6
예, 이것이 정말 도움이되었습니다. 오류의 원인은 필드 길이가 테이블 어댑터의 열 최대 길이보다 길기 때문입니다. 디자이너 파일에서 중단 점에 도달하려면 도구> 옵션> 디버깅으로 이동하여 "내 코드 만 사용"을 선택 취소해야합니다. 그런 다음 디자이너 파일 코드를 단계별로 살펴볼 수 있습니다.
e-on

1
@PaulStock에 감사드립니다. 같은 문제가 해결되었습니다.
Uday

1
이것은 매우 유용했습니다. 데이터 열 길이가 일치하지 않습니다. 데이터 세트가 아닌 데이터베이스에서 증가했습니다.
Rob

38

데이터 세트에 대한 제약 조건을 비활성화 할 수 있습니다. 잘못된 데이터를 식별하고 문제를 해결하는 데 도움이됩니다.

예 :

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

채우기 방법이 약간 다를 수 있습니다.


1
이를 통해 문제를 일으키는 데이터를 찾을 수있었습니다. 이는 "나쁜 데이터"가 아니라 데이터 소스 구성 마법사의 나쁜 동작입니다. 외출하고 DB와 대화하면서 캐시가 활성화되지 않은 상태에서 수정 된 열 제약 조건을 얻지 못하고 (부팅 할 추가 테이블이 누락되었습니다.)
포트 보이즈

이 답변에 감사드립니다. 대소 문자를 구분하는 문제가 있었고 데이터 세트에서 적절하게 설정해야했습니다.
Dan

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 열을 알고 있기 때문에 모든 테이블에 대해 이러한 오류에 대한 디버그를 자동으로 작성할 수 있습니다.

결과는 다음과 같습니다.

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
Andez

이것은 나를 위해 일했습니다. 그것은 Column 'MyColumn' does not allow DBNull.Value이지만 다른 방법으로는 보이지 않습니다. 감사합니다 :)
Alex

7
  • 테이블 어댑터 조회에 이름 지정된 필드가 정의한 조회의 필드와 일치하는지 확인하십시오. DAL이 일치하지 않는 것 같습니다. 이것은 일반적으로 테이블에 새 필드를 추가 한 후 sprocs 및 쿼리에서 발생합니다.

  • 데이터베이스에서 varchar 필드의 길이를 변경했지만 XSS 파일에 포함 된 XML에서 선택하지 않은 경우 XML에서 필드 이름 및 속성 정의를 찾아서 수동으로 변경하십시오.

  • 리턴되는 데이터와 관련이없는 테이블 어댑터의 선택 목록에서 기본 키를 제거하십시오.

  • SQL Management Studio에서 쿼리를 실행하고 반환되는 중복 레코드가 없는지 확인하십시오. 중복 레코드는 중복 기본 키를 생성하여이 오류가 발생할 수 있습니다.

  • SQL 공용체는 문제를 일으킬 수 있습니다. 다른 직원 앞에 '직원을 선택하십시오'레코드를 추가하여 하나의 테이블 어댑터를 수정했습니다. 다른 필드의 경우 예를 들어 길이가 1 인 문자열을 포함하여 더미 데이터를 제공했습니다. DAL은 해당 초기 레코드에서 스키마를 유추했습니다. 문자열 길이가 12 인 레코드는 실패했습니다.


1
SO에 오신 것을 환영합니다. Bob. 귀하의 답변을 편집했습니다 (아직 검토 중). 예를 들어, 답변에 인사와 서명이없는 것을 선호합니다 ( "소음"으로 간주됩니다. FAQ 참조). 어쨌든 귀하의 이름과 그라바타는 항상 답변 아래에 표시됩니다.
Christoffer Lette

5

이것은 나를 위해 일했다. here

이 오류가 발생했으며 DB 제약과 관련이 없습니다 (적어도 내 경우에는). 레코드 그룹을 반환하는 GetRecord 쿼리가있는 .xsd 파일이 있습니다. 해당 테이블의 열 중 하나는 "nvarchar (512)"이고 프로젝트 중간에 "nvarchar (MAX)"로 변경해야했습니다.

사용자가 해당 필드에 512 이상을 입력 할 때까지 모든 것이 제대로 작동했으며 "제약 조건을 활성화하지 못했습니다. 하나 이상의 행에 null이 아니거나 고유하거나 외래 키 제약 조건을 위반하는 값이 있습니다."라는 유명한 오류 메시지가 나타납니다.

솔루션 : DataTable에서 열의 모든 MaxLength 속성을 확인하십시오.

"nvarchar (512)"에서 "nvarchar (MAX)"로 변경 한 열에는 여전히 MaxLength 속성에 512 값이 있으므로 "-1"로 변경되었으며 작동합니다.


내 문제는 MaxLength 였어야합니다. VWD 2010 데이터 세트 디자이너를 사용합니다. 다른 사람이 소스 테이블을 변경했습니다. select *모든 열을 새로 고칠 것이라고 생각 하면서 SQL 쿼리를로 수정 했지만 기존 길이는 업데이트하지 않는 것 같습니다. 그래서 하나의 필드를 선택하고 .xsd를 저장하고 메모장 ++에서 .xsd를 열어 MaxLength defs 중 하나를 제외한 모든 항목이 사라 졌는지 확인한 다음 쿼리를 다시 수정했습니다 select *. 그것은 MaxLengths를 새로 고치고이 오류를 지나쳤습니다.
Mark Berry

정말 감사합니다. 모든 것이 잘보고되어 왔기 때문에 하루 종일 머리를 긁었습니다. 또한 nvarchar (MAX)로 변경해야했지만 DataTable은 MaxLength를 10으로 유지했습니다! 나는 당신에게 음료를 빚지고 있습니다!
Jon D

4

문제는 데이터 액세스 디자이너에 있습니다. Visual Studio에서 뷰를 "서버 탐색기"에서 디자이너 창으로 가져 오면 열에 기본 키가 무작위로 추가되거나 실제로 null로 설정되어 있지만 NOT NULL로 표시됩니다. SQL db 서버에서 실제보기 작성에는 기본 키가 정의되어 있지 않거나 NOT NULL이 정의되어 있지 않지만 VS 디자이너는이 키 / 제약을 추가합니다.

디자이너에서 이것을 볼 수 있습니다-열 이름 왼쪽에 키 아이콘이 표시됩니다.

해결 방법 : 키 아이콘을 마우스 오른쪽 버튼으로 클릭하고 '키 삭제'를 선택하십시오. 문제를 해결해야합니다. 열을 마우스 오른쪽 버튼으로 클릭하고 "속성"을 선택하여 VS 데이터 액세스 디자이너에서 열 속성 목록을보고 값을 적절히 변경할 수 있습니다.


3

이 오류는 내 프로젝트에도 표시되었습니다. 여기에 게시 된 모든 제안 된 솔루션을 시도했지만 문제는 필드 크기, 테이블 키 필드 정의, 제약 조건 또는 EnforceConstraints 데이터 세트 변수와 관련이 없기 때문에 운이 없습니다.

필자의 경우 프로젝트 디자인 시간 (데이터 액세스 레이어)에 .xsd 객체도 넣었습니다. 데이터베이스 테이블 개체를 데이터 집합 시각적 항목으로 끌어다 놓으면 기본 데이터베이스에서 각 테이블 정의를 읽고 데이터베이스에 테이블을 만들 때 정의한대로 제약 조건을 데이터 집합 개체에 복사합니다 (SQL Server 2008 R2 in 케이스). 이는 "not null"또는 "foreign key"제한 조건으로 작성된 모든 테이블 열이 SQL 문 또는 스토어드 프로 시저의 결과에도 존재해야 함을 의미합니다.

모든 키 열과 "널이 아님"으로 정의 된 열을 쿼리에 포함시킨 후 문제가 완전히 사라졌습니다.


3

AllowDBNullxsd 파일의 데이터 테이블에서 날짜 필드에서 True로 설정하면 광산이 작동하기 시작했습니다 .


2

다음과 같이 하나 이상의 열을 선택하는 것처럼 들립니다.

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

AllowDBNull의 로 설정 거짓을 사용자의 데이터 집합 (고화질)에서.


이 테이블의 모든 열에 대해 allow null = true를 헛되이 넣습니다.
Anyname Donotcare

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 개 이상의 UN 관련 테이블에서 데이터를 가져올 때 유용한) 데카르트가 여전히 발생할 수 있습니다.

tbFirst 내부 참여 tbSystem ON tbFirst.reference_str <> tbSystem.systemKey_str에서

이에 대한 해결책 : 테이블이 관련되어야합니다.

감사. 채 버트


1

이것을 false에서 true로 변경하여 동일한 문제를 해결했습니다. 결국 나는 데이터베이스에 들어가서 null 필드를 허용하도록 비트 필드를 변경 한 다음 xsd를 새로 고치고 내 wsdl과 reference.cs를 새로 고쳤습니다.

this.columnAttachPDFToEmailFlag.AllowDBNull = true;

1

짧고 쉬운 해결책 :

MSSQL Studio Sever로 이동하십시오.

이 오류의 원인에 대한 쿼리를 실행하십시오. 제 경우에는 ID 사양 증분을 1 로 설정하는 것을 잊었 기 때문에 id 값이 null임을 알 수 있습니다.

여기에 이미지 설명을 입력하십시오

따라서 자동 필드이므로 id 필드에 1을 입력하고 수정보기에서 NULL을 허용하지 않습니다.

여기에 이미지 설명을 입력하십시오

이 코드에서 내 bindingsource 및 tabel 어댑터가 오류를 발생시키는 오류였습니다.

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

0

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

이것은 직접 오류를 제공합니다


2
좋은 제안이지만 오류가있는 데이터 테이블의 첫 번째 행인 경우에만 작동합니다. 100 개의 올바른 행이 반환 된 다음 1 개의 잘못된 행이 반환되면 RowErroron Rows(0)이 없을 것입니까?
PaulStock

0

Visual Studio 데이터 세트 디자이너를 사용하여 데이터 테이블을 가져 오는 중이고 '제한 조건을 사용하지 못했습니다'라는 오류가 발생합니다. 나는 같은 문제에 직면하여 데이터 세트 디자이너 자체의 데이터를 미리보고 데이터베이스 내부의 테이블과 일치시킵니다.

이 문제를 해결하는 가장 좋은 방법은 테이블 어댑터를 삭제하고 대신 새 어댑터를 작성하는 것입니다.


0

* 이차 방법 : *


[id]가 기본 키가 될 필요가없는 경우,

기본 키 속성을 제거하십시오.

DataSet> TableAdapter에서 [id] 열을 마우스 오른쪽 버튼으로 클릭하고 Delete key ...

문제가 해결됩니다.


0

또한이 문제가 있었고 기본 SQL Server에서 변경된 열의 수정 된 크기를 반영하도록 * .xsd를 수정 한 후에 해결되었습니다.


0

이 오류를 해결하기 위해 Dataset Designer에서 문제 테이블 어댑터를 제거하고 데이터 세트를 저장 한 다음 서버 탐색기에서 테이블 어댑터의 새 사본을 끌어서 수정했습니다.


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이 아닌 ...)이 지워집니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.