Falha ao ativar restrições. Uma ou mais linhas contêm valores que violam restrições não nulas, exclusivas ou de chave estrangeira

168

Eu faço uma junção externa e executada com sucesso no informixbanco de dados, mas recebo a seguinte exceção no meu código:

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

Falha ao ativar restrições. Uma ou mais linhas contêm valores que violam restrições não nulas, exclusivas ou de chave estrangeira.

Conheço o problema, mas não sei como corrigi-lo.

A segunda tabela na qual faço a junção externa contém uma chave primária composta que é nula na consulta de junção externa anterior.

EDITAR:

    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 = ....

O problema acontece com a tabela cc1assiscrseval. A chave primária é (batch_no, crsnum, lect_code).

Como consertar esse problema?


EDITAR:

De acordo com o @PaulStockconselho: faço o que ele disse e recebo:

? dt.GetErrors () [0] {System.Data.DataRow} HasErrors: true ItemArray: {object [10]} RowError: "A coluna 'eval' não permite DBNull.Value."

Então eu resolver o meu problema, substituindo e.evala, NVL (e.eval,'') eval.e isso resolve o meu problema. Muito obrigado.

Anyname Donotcare
fonte
Quando removo ,e.eval,e.batch_no,e.crsnum,e.lect_code,e.prof_courseda consulta, tudo corre bem. qual é o problema por favor?
Anyname Donotcare
Há também um erro no ADO.NET em que um "índice clusterizado não exclusivo" criará um item Data.UniqueConstraint incorreto no DataTable.
precisa saber é o seguinte

Respostas:

352

Esse problema geralmente é causado por um dos seguintes

  • valores nulos retornados para colunas não definidas como AllowDBNull
  • linhas duplicadas sendo retornadas com a mesma chave primária.
  • uma incompatibilidade na definição da coluna (por exemplo, tamanho dos campos de caracteres) entre o banco de dados e o conjunto de dados

Tente executar sua consulta de forma nativa e observe os resultados, se o conjunto de resultados não for muito grande. Se você eliminou valores nulos, meu palpite é que as colunas da chave primária estão sendo duplicadas.

Ou, para ver o erro exato, você pode adicionar manualmente um bloco Try / Catch ao código gerado dessa maneira e interromper quando a exceção for gerada:

insira a descrição da imagem aqui

Em seguida, na janela de comando, chame o GetErrorsmétodo na tabela que está recebendo o erro.
Para C #, o comando seria ? dataTable.GetErrors()
Para VB, o comando é? dataTable.GetErrors

insira a descrição da imagem aqui

Isso mostrará todas as datarows com erro. Você pode obter uma olhada em RowErrorcada uma delas, que deve indicar a coluna inválida junto com o problema. Portanto, para ver o erro da primeira datarow com erro, o comando é:
? dataTable.GetErrors(0).RowError
ou em C # seria? dataTable.GetErrors()[0].RowError

insira a descrição da imagem aqui

PaulStock
fonte
4
Muito obrigado . >? dt.GetErrors()[0] {System.Data.DataRow} HasErrors: true ItemArray: {object[10]} RowError: "Column 'eval' does not allow DBNull.Value."
Anyname Donotcare
4
Impressionante. Isso não funcionou, mas eu poderia adicionar um relógio para o conjunto de dados e digitar .GetErrors após ele e expandir os valores. Isso é extremamente útil. Esperemos que não vou esquecê-lo antes da próxima vez que eu precisar dele :)
dwidel
6
Sim, isso foi realmente útil - o motivo do meu erro foi o tamanho do campo ser maior que o maxLength da coluna no adaptador de tabela. Uma coisa que notei foi que, para atingir o ponto de interrupção no arquivo de designer, você precisa ir em Ferramentas> Opções> Depuração e garantir que a opção "Ativar apenas meu código" esteja desmarcada. Isso permitirá que você percorra o código do arquivo do designer.
e-on
1
Obrigado @PaulStock por sua resposta, resolvi meu mesmo problema.
Uday
1
Isso foi extremamente útil, encontrei uma incompatibilidade entre o comprimento da coluna de dados - ela foi aumentada no banco de dados e não no conjunto de dados.
28417 Rob
38

Você pode desativar as restrições no conjunto de dados. Isso permitirá que você identifique dados incorretos e ajude a resolver o problema.

por exemplo

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

O método de preenchimento pode ser um pouco diferente para você.

HockeyJ
fonte
1
Isso me ajudou a encontrar os dados que estavam causando o meu problema, que não eram "dados incorretos", mas um comportamento inadequado do Assistente de Configuração da Fonte de Dados. Aparentemente, ele não está recebendo restrições de coluna revisadas (e estou perdendo uma tabela adicionada para inicializar), apesar de sair e conversar com o banco de dados ... e com o cache não ativado.
fortboise
Obrigado por esta resposta. Eu estava com um problema que diferenciava maiúsculas de minúsculas e só precisava configurá-lo adequadamente no conjunto de dados.
Dan
10

Isso encontrará todas as linhas da tabela com erros, imprima a chave primária da linha e o erro que ocorreu nessa linha ...

Isso está em C #, mas convertê-lo em VB não deve ser difícil.

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

Ups - desculpe PKColumns é algo que adicionei quando estendi o DataTable que me diz todas as colunas que compõem a chave primária do DataTable. Se você conhece as colunas Chave Primária na sua tabela de dados, você pode percorrê-las aqui. No meu caso, como todas as minhas tabelas de dados conhecem suas colunas PK, eu posso escrever a depuração desses erros automaticamente para todas as tabelas.

A saída é assim:

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

Se você estiver confuso sobre a seção PKColumns acima - isso imprime nomes e valores de colunas e não é necessário, mas adiciona informações úteis para a solução de problemas para identificar quais valores de coluna podem estar causando o problema. Remover esta seção e manter o restante ainda imprimirá o erro SQLite que está sendo gerado, que observará a coluna que está com o problema.

shindigo
fonte
1
Maneira brilhante de descobrir exatamente onde deu errado. Totalmente me ajudou a resolver problemas em uma solução que herdei onde havia inconsistências com os dados. Embora estivesse em um DataSet e eu apenas iterasse através de cada tabela e, em seguida, de cada linha. +10 se eu pudesse.
Andez
Isso funcionou para mim. Era um Column 'MyColumn' does not allow DBNull.Value, mas não mostraria isso de nenhuma outra maneira. Obrigado :) #
1148
7
  • Verifique se os campos nomeados na consulta do adaptador de tabela correspondem aos da consulta que você definiu. O DAL não parece gostar de incompatibilidades. Isso normalmente acontece com seus sprocs e consultas depois que você adiciona um novo campo a uma tabela.

  • Se você alterou o comprimento de um campo varchar no banco de dados e o XML contido no arquivo XSS não o selecionou, localize o nome do campo e a definição de atributo no XML e altere-o manualmente.

  • Remova as chaves primárias das listas de seleção nos adaptadores de tabela se elas não estiverem relacionadas aos dados que estão sendo retornados.

  • Execute sua consulta no SQL Management Studio e verifique se não há registros duplicados sendo retornados. Registros duplicados podem gerar chaves primárias duplicadas, o que causará esse erro.

  • Uniões SQL podem significar problemas. Modifiquei um adaptador de tabela adicionando um registro 'selecione um funcionário' antes dos outros. Para os outros campos, forneci dados fictícios, incluindo, por exemplo, cadeias de comprimento um. O DAL inferiu o esquema desse registro inicial. Registros seguintes com seqüências de comprimento 12 falharam.

Bob Sullentrup
fonte
1
Bem-vindo ao SO, Bob. Editei sua resposta (ainda em revisão). Por exemplo, preferimos não ter saudações e assinaturas nas respostas (é considerado "noice", consulte as Perguntas frequentes). Seu nome e gravatar sempre serão exibidos abaixo da resposta de qualquer maneira.
precisa saber é o seguinte
5

Isso funcionou para mim, fonte: aqui

Eu tive esse erro e não estava relacionado às restrições de banco de dados (pelo menos no meu caso). Eu tenho um arquivo .xsd com uma consulta GetRecord que retorna um grupo de registros. Uma das colunas dessa tabela era "nvarchar (512)" e no meio do projeto eu precisei alterá-lo para "nvarchar (MAX)".

Tudo funcionou bem até que o usuário inseriu mais de 512 nesse campo e começamos a receber a famosa mensagem de erro "Falha ao ativar restrições. Uma ou mais linhas contêm valores que violam restrições não nulas, exclusivas ou de chave estrangeira".

Solução: verifique todas as propriedades MaxLength das colunas em sua DataTable.

A coluna que eu mudei de "nvarchar (512)" para "nvarchar (MAX)" ainda tinha o valor 512 na propriedade MaxLength, então mudei para "-1" e funciona !!.

Alguém
fonte
Meu problema deve ter sido MaxLength também. Eu uso o designer de conjunto de dados VWD 2010. A tabela de origem foi alterada por outra pessoa. Modifiquei a Consulta SQL para select *, pensando que atualizaria todas as colunas, mas aparentemente não atualizava os comprimentos existentes. Então, modifiquei a consulta para selecionar um campo, salvei o .xsd, abri o .xsd no Notepad ++ para verificar se todos os exceção de MaxLength foram excluídos, mas modifiquei a consulta novamente para select *. Isso atualizou o MaxLengths e me levou além desse erro.
Mark Berry
Muito obrigado. Estive coçando minha cabeça durante todo o dia, pois tudo estava voltando bem. Eu também tive que mudar para nvarchar (MAX), mas o DataTable manteve MaxLength em 10! Te devo uma bebida!
Jon D
4

O problema está no designer de acesso a dados. No Visual Studio, quando extraímos uma Visualização do "Server Explorer" para a janela Designer, ela adiciona uma chave Primária em uma coluna aleatoriamente ou marca algo a um NOT NULL, embora na verdade seja definido como nulo. Embora a criação de exibição real no servidor db SQL não tenha nenhuma chave primária definida ou NOT NULL definido, o designer do VS está adicionando essa chave / restrição.

Você pode ver isso no designer - ele é mostrado com um ícone de chave à esquerda do nome da coluna.

Solução: Clique com o botão direito do mouse no ícone de chave e selecione 'Excluir chave'. Isso deve resolver o problema. Você também pode clicar com o botão direito do mouse em uma coluna e selecionar "Propriedades" para ver a lista de propriedades de uma coluna no designer de acesso a Dados do VS e alterar os valores adequadamente.

Shankar Arigela
fonte
3

Este erro também foi exibido no meu projeto. Tentei todas as soluções propostas postadas aqui, mas não tive sorte porque o problema não tinha nada a ver com o tamanho dos campos, a definição dos campos-chave da tabela, as restrições ou a variável do conjunto de dados EnforceConstraints.

No meu caso, também tenho um objeto .xsd que eu coloquei lá durante o tempo de design do projeto (a camada de acesso a dados). À medida que você arrasta os objetos de tabela do banco de dados para o item visual do conjunto de dados, ele lê cada definição de tabela do banco de dados subjacente e copia as restrições no objeto do conjunto de dados exatamente como você as definiu ao criar as tabelas no banco de dados (SQL Server 2008 R2 em meu caso). Isso significa que todas as colunas da tabela criadas com a restrição de "não nulo" ou "chave estrangeira" também devem estar presentes no resultado da sua instrução SQL ou procedimento armazenado.

Depois de incluir todas as colunas-chave e as colunas definidas como "não nulas" nas minhas consultas, o problema desapareceu completamente.

jgarcias
fonte
3

O meu começou a funcionar quando eu defini AllowDBNullcomo True em um campo de data em uma tabela de dados no arquivo xsd.

Roger Perkins
fonte
2

Parece que possivelmente uma ou mais das colunas estão sendo selecionadas com:

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

tem AllowDBNull definido como False na sua definição de conjunto de dados.

Sheldon Warkentin
fonte
Coloquei allow null = true para todas as colunas nesta tabela, mas em vão.
Anyname Donotcare
2

Não está claro por que executar uma instrução SELECT envolve restrições de habilitação. Não conheço C # ou tecnologias relacionadas, mas conheço o banco de dados Informix. Há algo estranho acontecendo com o sistema se o seu código de consulta estiver ativando (e presumivelmente também desativando) restrições.

Você também deve evitar a notação de junção do Informix OUTER antiquada e antiquada. A menos que você esteja usando uma versão impossivelmente antiga do Informix, você deve usar o estilo de junções SQL-92.

Sua pergunta parece mencionar duas junções externas, mas você mostra apenas uma na consulta de exemplo. Isso também é um pouco intrigante.

As condições de junção entre ' e' e o restante das tabelas são:

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

Esta é uma combinação incomum. Como não temos o subconjunto relevante do esquema com as restrições de integridade referencial relevantes, é difícil saber se isso está correto ou não, mas é um pouco incomum juntar-se entre três tabelas como essa.

Nada disso é uma resposta definitiva para o seu problema; no entanto, pode fornecer algumas orientações.

Jonathan Leffler
fonte
2

Obrigado por todas as contribuições feitas até agora. Eu só quero acrescentar que, embora alguém possa ter normalizado o banco de dados com êxito, atualizado quaisquer alterações de esquema em sua aplicação (por exemplo, no conjunto de dados) ou mais, há também outra causa: sql CARTESIAN product (ao juntar tabelas em consultas).

A existência de um resultado de consulta cartesiana fará com que registros duplicados na tabela primária (ou chave primeiro) de duas ou mais tabelas sejam unidas. Mesmo se você especificar uma cláusula "Where" no SQL, um Cartesiano ainda poderá ocorrer se JOIN com tabela secundária, por exemplo, contiver uma junção desigual (útil para obter dados de 2 ou mais tabelas não relacionadas):

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

Solução para isso: as tabelas devem estar relacionadas.

Obrigado. chagbert

Chagbert
fonte
1

Resolvi o mesmo problema, alterando isso de falso para verdadeiro. no final, entrei no banco de dados e alterei meu campo de bits para permitir nulo, atualizei meu xsd e atualizei meu wsdl e reference.cs e agora está tudo bem.

this.columnAttachPDFToEmailFlag.AllowDBNull = true;
hamish
fonte
1

Solução curta e fácil:

Vá para o MSSQL Studio Sever;

Execute a consulta da causa deste erro: no meu caso, vejo que o valor do ID era nulo porque esqueci de definir o incremento da especificação de identidade em 1.

insira a descrição da imagem aqui

Assim, digite 1 para o campo id, pois é autoincremane e modifique, não permita NULLS na exibição desing

insira a descrição da imagem aqui

Esse foi o erro que causou o erro de ativação do adaptador bindingsource e tabel neste código:

   this.exchangeCheckoutReportTableAdapter.Fill(this.sbmsDataSet.ExchangeCheckouReportTable);
Daniel Adenew
fonte
0

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

Isso dá diretamente o erro

Som
fonte
2
Boa sugestão, mas isso só funciona se for a primeira linha da tabela de dados que apresenta o erro, não é? Se 100 linhas boas forem retornadas e, em seguida, 1 linha ruim, não haverá um RowErrorativado Rows(0), haverá?
PaulStock
0

Se você estiver usando o designer de conjunto de dados do visual studio para obter a tabela de dados e estiver lançando um erro 'Falha ao ativar restrições'. Eu enfrentei o mesmo problema, tente visualizar os dados do próprio designer do conjunto de dados e combiná-lo com a tabela dentro do seu banco de dados.

A melhor maneira de resolver esse problema é excluir o adaptador de tabela e criar um novo.

albin.varghese
fonte
0

* Caminho secundário: *


Se você não precisar que [id] seja a chave primária,

Remova seu atributo de chave primária:

em seu DataSet> TableAdapter> clique com o botão direito do mouse na coluna [id]> selecione Excluir chave ...

Problema será corrigido.

Zolfaghari
fonte
0

Também tive esse problema e foi resolvido após a modificação do * .xsd para refletir o tamanho revisado da coluna alterada no servidor SQL subjacente.

Ravi
fonte
0

Para corrigir esse erro, tirei o adaptador de tabela problemático do designer do conjunto de dados, salvei o conjunto de dados e arrastei uma nova cópia do adaptador de tabela do explorador do servidor, que foi corrigido

Edwin Ikechukwu Okonkwo
fonte
0

Resolvi esse problema abrindo o arquivo .xsd com um leitor XML e excluindo uma restrição colocada em uma das minhas visualizações. Por qualquer motivo, quando adicionei a visualização aos dados, ela adicionou uma restrição de chave primária a uma das colunas quando não deveria haver uma.

A outra maneira é abrir o arquivo .xsd normalmente, observe a tabela / exibição que está causando o problema e exclua as chaves (coluna da direita, selecione delete key) que não deveriam estar lá.

peroija
fonte
0

Apenas queira adicionar outro motivo possível para a exceção aos listados acima (especialmente para pessoas que gostam de definir o esquema do conjunto de dados manualmente):

quando em seu conjunto de dados você tem duas tabelas e existe um relacionamento ( DataSet.Reletions.Add()) definido do campo da primeira tabela ( chfield) para o campo da segunda tabela ( pfield), parece que uma restrição implícita é adicionada a esse campo para ser exclusiva mesmo que não seja especificado como tal explicitamente em sua definição, nem como exclusivo nem como chave primária.

Como conseqüência, se você tiver linhas com valores repetitivos nesse campo pai ( pfield), também receberá essa exceção.

serop
fonte
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();
                }
            }
Martin.Martinsson
fonte
0

Recebi o mesmo tipo de erro e, no meu caso, ele resolveu removendo os campos de seleção e substituindo-os por um *. Não faço ideia por que isso estava acontecendo. A consulta não teve erros de digitação nem nada sofisticado.

Não é a melhor solução, mas nada mais funcionou e eu estava ficando exausta.

Na minha busca por uma resposta clara, encontrei isso: https://www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont

Solução 8

Este erro também foi exibido no meu projeto, usando o Visual Studio 2010. Tentei outras soluções postadas em outros blogs, mas não tive sorte porque o problema não tinha nada a ver com o tamanho dos campos, a definição dos campos-chave da tabela, as restrições ou a EnforceConstraintsvariável do conjunto de dados.

No meu caso, tenho um objeto .xsd que eu coloquei lá durante o tempo de design do projeto (na camada de acesso a dados). À medida que você arrasta os objetos de tabela do banco de dados para o item visual Conjunto de Dados, ele lê cada definição de tabela do banco de dados subjacente e copia as restrições no Datasetobjeto exatamente como você as definiu quando criou as tabelas no banco de dados (SQL Server 2008 R2 no meu caso ) Isso significa que todas as colunas da tabela criadas com a restrição de "não nulo" ou "chave estrangeira" também devem estar presentes no resultado da sua instrução SQL ou procedimento armazenado.

Depois de incluir todas as colunas restritas (não nulas, chave primária, chave estrangeira etc.) nas minhas consultas, o problema desapareceu completamente.

Talvez você não precise que todas as colunas da tabela estejam presentes no resultado da consulta / procedimento armazenado, mas como as restrições ainda são aplicadas, o erro será mostrado se alguma coluna restrita não aparecer no resultado.

Espero que isso ajude outra pessoa.

Babak Bandpey
fonte
-1

No meu caso, esse erro foi provocado pelo tamanho de uma coluna de string. O que foi estranho foi quando eu executei exatamente a mesma consulta em uma ferramenta diferente, valores repetidos nem valores nulos não estavam lá.

Descobri que o tamanho de uma coluna de string era 50 e, quando chamei o método de preenchimento, o valor foi cortado, lançando essa exceção.
Clico na coluna e defino nas propriedades o tamanho para 200 e o erro se foi.

Espero que esta ajuda

tapatio
fonte
-1

Resolvi esse problema fazendo o "subselecionar" como ele:

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

Quando fazê-lo no mysql, todas as propriedades de collunms (únicas, não nulas ...) serão limpas.

ISFO
fonte