1

Я получаю следующую ошибку из веб-приложения VB NET, написанного в VS 2003, в фреймворке 1.1. Веб-приложение работает на Windows Server 2000, IIS 5 и читает из базы данных SQL Server 2000, запущенной на том же компьютере.Проблема с загадочными ограничениями с SQL Server 2000

System.Data.ConstraintException: Не удалось включить ограничения. Один или строк содержат значения, нарушающие непустые, уникальные или внешние ключи . на System.Data.DataSet.FailedEnableConstraints() в System.Data.DataSet.EnableConstraints() на System.Data.DataSet.set_EnforceConstraints (булевых значение) при System.Data.DataTable.EndLoadData()
на System.Data.Common.DbDataAdapter.FillFromReader (Object данных, String srcTable, IDataReader DataReader, Int32 startRecord, Int32 MaxRecords, DataColumn parentChapterColumn, объект parentChapterValue) в System.Data.Common.DbDataAdapter.Fill (DataSet dataSet, String s rcTable, IDataReader DataReader, Int32 startRecord, Int32 MaxRecords) в System.Data.Common.DbDataAdapter.FillFromCommand (Object данных, Int32 startRecord, Int32 MaxRecords, String srcTable, команды IDbCommand, CommandBehavior поведение) в системе .Data.Common.DbDataAdapter.Fill (DataSet DATASET, Int32 startRecord, Int32 MaxRecords, String srcTable, команда IDbCommand, CommandBehavior поведение) при System.Data.Common.DbDataAdapter.Fill (DataSet DATASET)

Проблема возникает, когда веб-приложение находится под высокой нагрузкой. Система работает нормально, когда уровень громкости низкий, но когда количество запросов становится высоким, система начинает отклонять входящие запросы с указанным выше сообщением об исключении. Как только проблема появляется, очень немногие запросы действительно проходят через и обрабатываются нормально, около 2 за каждые 30. Подавляющее большинство запросов завершается с ошибкой, пока не перезагрузится SQL Server или перезагрузка IIS. Затем система начинает обработку запросов обычно, и через некоторое время она начинает бросать ту же ошибку.

Ошибка возникает, когда адаптер данных запускает метод Fill() в отношении оператора SELECT, чтобы заполнить сильно типизированный набор данных. Похоже, что набор данных не нравится данные, которые он задает, и выбрасывает это исключение. Эта ошибка возникает в разных операторах SELECT, действующих на разные таблицы.

Я восстановил набор данных и проверил соответствующие ограничения, а также таблицу, из которой считываются данные. Как определение набора данных, так и данные в таблице являются точными.

Правда, оборудование работает как веб-приложение и SQL Server 2000 серьезно устарел, учитывая количество входящих запросов в настоящее время он получает. Объем оперативной памяти, потребляемой SQL Server, динамически распределяется, и в пиковые времена SQL Server может потреблять до 2.8 ГБ из общей суммы 3,5 ГБ на сервере.

Сначала я подозревал какой-то индекс или повреждение базы данных, но после запуска DBCC CHECKDB в базе данных ошибок не обнаружено.Поэтому теперь мне интересно, является ли эта ошибка результатом аппаратных ограничений системы. Возможно ли, что SQL Server каким-то образом испортил данные, которые он должен передать в набор данных, что приводит к нарушению ограничения из-за несоответствия типа данных/длины?

Я попытался получить доступ к сообщениям RowError строк данных в полученных наборах наборов данных, но я продолжал получать пустые строки. Я знаю, что HasErrors = true для данных, о которых идет речь. Я не установил EnableConstraints = false, и я не хочу этого делать.

Заранее спасибо.

Ray

ответ

0

Проблема заключается в отсутствии полезного сообщения диагностической ошибки. Я написал класс, содержащий методы, чтобы рассказать вам о проблеме с вашими ограничениями, вместо того, чтобы просто дать вам бесполезное общее сообщение об ошибке. Вы используете методы следующим образом.

Dim ds As New dsMyDataset 

'Turn off constraints during the data load' 
DatasetAnalyzer.DatasetAnalyzer_Init(ds) 

'Ready to fill one or more tables' 
Dim da1 As New dsMyDatasetTableAdapters.Table1TableAdapter 
da1.Fill(ds.Table1) 

'Checks relationships and constraints before turning them back on.' 
DatasetAnalyzer.DatasetAnalyzer_AnalyzeAndConfirm(ds) 

'Ready to use your dataset now' 
Return ds 

Полный список.

Public Class DatasetAnalyzer 

#Region " DatasetAnalyzer " 

    'Run this before loading tables in your dataset, if you plan to call DatasetAnalyzer_GetMissingParentRows. 
    'Must call DatasetAnalyzer_AnalyzeAndConfirm when done creating dataset to re-enable relations. 
#Region " DatasetAnalyzer_Init " 
    Public Shared Sub DatasetAnalyzer_Init(ByVal ds As Data.DataSet) 
     ds.EnforceConstraints = False 

     ds.BeginInit() 
     For Each dt As Data.DataTable In ds.Tables 
      dt.BeginInit() 
      dt.BeginLoadData() 

     Next 

    End Sub 
#End Region 

    'Checks for dataset constraint errors and gives detailed error messages if any are found. 
    'Assumes DatasetAnalyzer_Init is called on that dataset 
#Region " DatasetAnalyzer_AnalyzeAndConfirm " 
    Public Shared Sub DatasetAnalyzer_AnalyzeAndConfirm(ByVal ds As Data.DataSet) 
     DatasetAnalyzer_EnsureInitialization(ds) 

     Try 
      For Each dt As Data.DataTable In ds.Tables 
       dt.EndLoadData() 
       dt.EndInit() 
      Next 
      ds.EndInit() 

      ds.EnforceConstraints = True 

     Catch ex As Data.ConstraintException 
      'We've found a constraint exception...figure out what it is 

      Dim sErrorMessage As String = "DatasetAnalyzer_AnalyzeAndConfirm : " 

      For Each oTbl As Data.DataTable In ds.Tables 
       If oTbl.HasErrors Then 

        'Report the first error only 
        Dim oRow As Data.DataRow = oTbl.GetErrors(0) 
        sErrorMessage &= oTbl.TableName & " : " & oRow.RowError & " : " 

        'Detail for Foreign Key Violations 
        If oTbl.ParentRelations IsNot Nothing Then 
         For Each oRel As Data.DataRelation In oTbl.ParentRelations 
          If oRel.ChildKeyConstraint IsNot Nothing AndAlso oRow.GetParentRow(oRel) Is Nothing Then 
           'a parent constraint for this relation exists and the data that is constrained is non-existant. If this isn't a null value then we found a problem 
           For Each o As Data.DataColumn In oRel.ChildColumns 
            If Not oRow.IsNull(o) Then 
             'We have a confirmed foreign key violation...generate a pretty message 

             Dim ParentColumnNames(oRel.ParentColumns.Length - 1) As String 
             Dim ChildColumnNames(oRel.ChildColumns.Length - 1) As String 


             For i As Int32 = 0 To ParentColumnNames.Length - 1 
              ParentColumnNames(i) = oRel.ParentColumns(i).ColumnName 
             Next 

             For i As Int32 = 0 To ChildColumnNames.Length - 1 
              ChildColumnNames(i) = oRel.ChildColumns(i).ColumnName 
             Next 

             sErrorMessage &= "ParentTable = " & oRel.ParentTable.TableName & " (" & String.Join(", ", ParentColumnNames) & "), " 
             sErrorMessage &= "ChildTable = " & oRel.ChildTable.TableName & " (" & String.Join(", ", ChildColumnNames) & "), " 

            End If 
           Next 
          End If 
         Next 
        End If 


        'Additional Column info that might be usefull 
        If oRow.RowError.Contains("MaxLength") Then 
         For Each oCol As Data.DataColumn In oRow.GetColumnsInError 
          sErrorMessage &= oCol.ColumnName & ".MaxLength = " & oCol.MaxLength 
         Next 
        End If 


        'Report the error with details about the row that errored 
        sErrorMessage &= Environment.NewLine & Environment.NewLine & "Debug Data = " & DatasetAnalyzer_GetRowDebugData(oRow) 
        Throw New Exception(sErrorMessage) 

       End If 
      Next 


      Throw New Exception("Dear Developer, Unknown Constraint Exeption", ex) 
     End Try 

    End Sub 
#End Region 

    'Returns an array of detached rows that are "missing" in the ParentTable. 
    'Returns an empty array if no values exist 
#Region " DatasetAnalyzer_GetMissingParentRows " 
    Public Shared Function DatasetAnalyzer_GetMissingParentRows(ByVal ParentTable As Data.DataTable) As Data.DataRow() 
     If ParentTable.DataSet Is Nothing Then 
      Throw New Exception("Dear Developer, DatasetAnalyzer_GetMissingParentRows : ParentTable must belong to a dataset. Table = " & ParentTable.TableName) 
     End If 

     DatasetAnalyzer_EnsureInitialization(ParentTable.DataSet) 

     Dim drMissingParents As New Collections.Generic.List(Of Data.DataRow) 

     Try 
      'Turn on the constraints to see if anything breaks 
      ParentTable.DataSet.EnforceConstraints = True 

     Catch ex As Data.ConstraintException 

      For Each oRel As Data.DataRelation In ParentTable.ChildRelations 
       If oRel.ChildKeyConstraint IsNot Nothing AndAlso oRel.ChildTable.HasErrors Then 
        'This relationship has a child key constraint...this child table has errors 

        For Each oRow As Data.DataRow In oRel.ChildTable.GetErrors 
         If oRow.GetParentRow(oRel) Is Nothing Then 
          ' This foreign key that is constrained is non-existant. If this isn't a null value then we found a problem 
          For Each o As Data.DataColumn In oRel.ChildColumns 
           If Not oRow.IsNull(o) Then 
            ' non-null missing foreign key constraint 
            Dim drMissingParent As Data.DataRow = ParentTable.NewRow 

            ' Create the proposed parent record by matching the child record 
            For i As Int32 = 0 To oRel.ParentColumns.Length - 1 
             drMissingParent(oRel.ParentColumns(i)) = oRow(oRel.ChildColumns(i)) 
            Next 

            'Search for a duplicate Missing Parent...only need to report each one once 
            Dim bFoundDupe As Boolean = False 
            For Each dr As Data.DataRow In drMissingParents 
             bFoundDupe = True 

             For i As Int32 = 0 To ParentTable.Columns.Count - 1 
              If Not dr(i).Equals(drMissingParent(i)) Then 
               bFoundDupe = False 
               Exit For 
              End If 
             Next 

             If bFoundDupe Then Exit For 
            Next 

            If Not bFoundDupe Then 
             drMissingParents.Add(drMissingParent) 
            End If 

            Exit For 'Checking for non-nulls Columns 
           End If 
          Next 
         End If 
        Next 
       End If 
      Next 
     End Try 

     ParentTable.DataSet.EnforceConstraints = False 

     Return drMissingParents.ToArray 
    End Function 
#End Region 

    'Returns the string representation of row data 
#Region " DatasetAnalyzer Private Support Methods " 

    Private Shared Function DatasetAnalyzer_GetRowDebugData(ByVal oRow As Data.DataRow) As String 
     Dim Values(oRow.Table.Columns.Count - 1) As String 


     For Each oCol As Data.DataColumn In oRow.Table.Columns 
      Dim Value As String 
      If oRow.IsNull(oCol) Then 
       Value = "<NULL>" 
      Else 
       Value = oRow(oCol).ToString 
      End If 

      Values(oCol.Ordinal) = oCol.ColumnName & ":" & Value 
     Next 


     Return String.Join(", ", Values) 
    End Function 

    Private Shared Sub DatasetAnalyzer_EnsureInitialization(ByVal ds As Data.DataSet) 
     If ds Is Nothing Then 
      Throw New Exception("Dear Developer, Must construct the ds object before calling InDatasetAnalyzer_Init (ds = New ...)") 
     End If 

     If ds.EnforceConstraints Then 
      Throw New Exception("Dear Developer, call DatasetAnalyzer_Init before calling DatasetAnalyzer_AnalyzeAndConfirm") 
     End If 
    End Sub 
#End Region 
#End Region 

End Class 

Теперь вы должны иметь возможность устранения неполадок с полезной информацией.

Смежные вопросы