BassamKassem Ответов: 2

У меня возникла ошибка при выполнении SQL-запроса с использованием метода parameters (дочерний список не может быть создан


Я получаю вызов ошибки "Дочерний список для клиентов полей не может быть создан". после выполнения запроса , особенно после изменения моих sql-запросов на параметры вместо запросов sql-инъекций, вот код

//////НОВИНКИ\\\\\\\

Извините за то , что не предоставил полную информацию, однако вот необходимые обновления: ошибка появляется только в том случае, если я использовал запрос клиента, который представляет собой использование оператора sql в текстовом поле под названием SQLText.Текст и он указывает на нижеприведенную строку
DataGridViewReports.DataMember = "Customers"


при отладке вот ценность sqlQry = "клиенты обновления установить шорткод = '0000', где (имя='заблокировать всю рекламу и объявления блок SupplierName=' - все поставщики и SupplierFeedbackDate='.... / .... / .....' И Supplier_Feedback='.....');"

чтобы быть точным : нет никаких ошибок вообще в случае, если я использовал запросы из флажков

Что я уже пробовал:

Private Sub btn_custom_query_Click(sender As Object, e As EventArgs) Handles btn_custom_query.Click
    Try
        If cnnOLEDB.State = ConnectionState.Open Then
            cnnOLEDB.Close()
        End If
        cnnOLEDB.ConnectionString = strConnectionString
        cnnOLEDB.Open()
        Dim sqlQry As String = SQLText.Text
        'Only add "WHERE" if at least one of the boxes is checked
        sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked Or Reason.Checked Or ServiceName.Checked Or DateAdded.Checked Or SupplierFeedbackDate.Checked, " WHERE ", "")
        'Only add the parameter for Supplier if Supplier box is checked
        If SupplierName.Checked Then
            If cbo_Supplier.Text = vbNullString Then
                sqlQry &= "SupplierName IS NOT NULL"
            Else
                sqlQry &= "SupplierName = @cbo_Supplier"
            End If
        End If
        If Supplier_Feedback.Checked Then
            If cbo_Feedback.Text = vbNullString Then
                'Only add "AND" if Supplier box was checked (i.e. we already have a filter)
                sqlQry &= IIf(SupplierName.Checked, " AND ", "")
                sqlQry &= "Supplier_Feedback IS NOT NULL"
            Else
                'Only add "AND" if Supplier box was checked (i.e. we already have a filter)
                sqlQry &= IIf(SupplierName.Checked, " AND ", "")
                sqlQry &= "Supplier_Feedback = @cbo_Feedback"
            End If
        End If
        If Reason.Checked Then
            If cbo_Reason.Text = vbNullString Then
                sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked, " AND ", "")
                sqlQry &= "Reason IS NOT NULL"
            Else
                'Only add " AND " if we have a previous filter in place already
                'I.e. one or both of Supplier and/or Action is checked
                sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked, " AND ", "")
                sqlQry &= "Reason = @cbo_Reason"
            End If
        End If
        If ServiceName.Checked Then
            If TXTServiceName.Text = vbNullString Then
                'I.e. one or both of Supplier and/or Action is checked
                sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked Or Reason.Checked, " AND ", "")
                sqlQry &= "ServiceName IS NOT NULL"
            Else
                'Only add " AND " if we have a previous filter in place already
                'I.e. one or both of Supplier and/or Action is checked
                sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked Or Reason.Checked, " AND ", "")
                sqlQry &= "ServiceName LIKE %@TXTServiceName%"
            End If
        End If
        If DateAdded.Checked Then
            'Only add " AND " if we have a previous filter in place already
            'I.e. one or both of Supplier and/or Action is checked
            sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked Or Reason.Checked Or ServiceName.Checked, " AND ", "")
            sqlQry &= "DateAdded Between @cbo_DateSent And @cbo_DateSentTo"
        End If
        If SupplierFeedbackDate.Checked Then
            'Only add " AND " if we have a previous filter in place already
            'I.e. one or both of Supplier and/or Action is checked
            sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked Or Reason.Checked Or ServiceName.Checked Or DateAdded.Checked, " AND ", "")
            sqlQry &= "SupplierFeedbackDate Between @cbo_FeedbackDate And @cbo_FeedbackDateTo"
        End If
        SQLText.Text = sqlQry

        Dim ds As DataSet = New DataSet
        Dim da As New SqlDataAdapter(sqlQRY, cnnOLEDB)
        Dim cb As SqlCommandBuilder = New SqlCommandBuilder(da)

        da.SelectCommand.Parameters.AddWithValue("@cbo_Supplier", cbo_Supplier.Text)
        da.SelectCommand.Parameters.AddWithValue("@cbo_Feedback", cbo_Feedback.Text)
        da.SelectCommand.Parameters.AddWithValue("@cbo_Reason", cbo_Reason.Text)
        da.SelectCommand.Parameters.AddWithValue("@TXTServiceName", TXTServiceName.Text)
        da.SelectCommand.Parameters.AddWithValue("@cbo_DateSent", cbo_DateSent.Value)
        da.SelectCommand.Parameters.AddWithValue("@cbo_DateSentTo", cbo_DateSentTo.Value)
        da.SelectCommand.Parameters.AddWithValue("@cbo_FeedbackDate", cbo_FeedbackDate.Value)
        da.SelectCommand.Parameters.AddWithValue("@cbo_FeedbackDateTo", cbo_FeedbackDateTo.Value)

        da.Fill(ds, "Customers")
        DataGridViewReports.DataSource = ds
        DataGridViewReports.DataMember = "Customers"
        lbl_RowCount.Text = DataGridViewReports.RowCount
    Catch ex As SqlException
        MessageBox.Show(ex.Message)
    End Try
    cnnOLEDB.Close()
End Sub

phil.o

Каково фактическое значение переменной sqlQry?

BassamKassem

вопрос был обновлен

ZurdoDev

Эта ошибка-не ошибка sql, а ошибка c#. Вы неправильно настроили свой набор данных или не заполняете его правильным sql.

BassamKassem

боюсь, что это ошибка VB, и она связана с заполнением сетки данных измененными записями

ZurdoDev

Именно так. Но все предлагают вам взглянуть на ваш sql-оператор, когда проблема заключается в вашем коде.

2 Ответов

Рейтинг:
4

Maciej Los

Мое лучшее предположение таково...
Если вы добавляете условие в свой запрос, вам также нужно добавить параметры:

    SQLText.Text = sqlQry

    Dim ds As DataSet = New DataSet
    Dim da As New SqlDataAdapter(sqlQRY, cnnOLEDB)
    Dim cb As SqlCommandBuilder = New SqlCommandBuilder(da)

    da.SelectCommand.Parameters.AddWithValue("@cbo_Supplier", cbo_Supplier.Text)
    da.SelectCommand.Parameters.AddWithValue("@cbo_Feedback", cbo_Feedback.Text)
    da.SelectCommand.Parameters.AddWithValue("@cbo_Reason", cbo_Reason.Text)
    da.SelectCommand.Parameters.AddWithValue("@TXTServiceName", TXTServiceName.Text)
    da.SelectCommand.Parameters.AddWithValue("@cbo_DateSent", cbo_DateSent.Value)
    da.SelectCommand.Parameters.AddWithValue("@cbo_DateSentTo", cbo_DateSentTo.Value)
    If SupplierFeedbackDate.Checked Then
        'Only add " AND " if we have a previous filter in place already
        'I.e. one or both of Supplier and/or Action is checked
        sqlQry &= IIf(SupplierName.Checked Or Supplier_Feedback.Checked Or Reason.Checked Or ServiceName.Checked Or DateAdded.Checked, " AND ", "")
        sqlQry &= "SupplierFeedbackDate Between @cbo_FeedbackDate And @cbo_FeedbackDateTo"
    da.SelectCommand.Parameters.AddWithValue("@cbo_FeedbackDate", cbo_FeedbackDate.Value)
    da.SelectCommand.Parameters.AddWithValue("@cbo_FeedbackDateTo", cbo_FeedbackDateTo.Value)
    End If

    da.Fill(ds, "Customers")
    DataGridViewReports.DataSource = ds
    DataGridViewReports.DataMember = "Customers"
    lbl_RowCount.Text = DataGridViewReports.RowCount
Catch ex As SqlException
    MessageBox.Show(ex.Message)
End Try
cnnOLEDB.Close()


Я бы настоятельно рекомендовал отладить программу и проверить, какая строка sqlQry переменная держится.


BassamKassem

Сделано и вопрос обновлен включая результат sqlQry

Maciej Los

Это ничего не меняет. Как видите, я сослался на Оператор if в другой части кода. Все, что вам нужно сделать, это отладить вашу программу.
Удачи вам!

BassamKassem

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

Maciej Los

Потому что инструкция update возвращает количество измененных строк вместо данных. Чтобы использовать инструкцию update, необходимо вызвать метод ExecuteNonQuery. Чтобы отобразить данные, используйте SELECT + ExecuteReader().

Рейтинг:
2

OriginalGriff

Мы не можем помочь вам на основе этой информации: мы понятия не имеем, что такое базовый запрос, к которому вы добавляете, и это, вероятно, имеет отношение к делу.

Я бы начал с использования отладчика: выясните, что именно находится внутри sqlQry когда вы создаете SqlDataAdapter, и что именно находится в каждом параметре, который вы передаете. При предположении - основанном на тексте сообщения об ошибке - вы не извлекаете данные из нужной таблицы или ваш основной запрос плох.

Затем начните просматривать свои данные и посмотрите, какие строки они должны возвращать.

Извините, но мы ничего не можем сделать для вас!


BassamKassem

Сделано сэр

OriginalGriff

И что же? Что вам показал отладчик?

BassamKassem

Это дало мне то же самое сообщение об ошибке "Дочерний список для полевых клиентов не может быть создан."

а переменная sqlQry = "клиенты обновления установить шорткод = '0000', где (имя='заблокировать всю рекламу и объявления блок SupplierName=' - все поставщики и SupplierFeedbackDate='.... / .... / .....' И Supplier_Feedback='.....');"

OriginalGriff

Вам придется научиться пользоваться отладчиком.
Идея состоит в том, что вы останавливаете выполнение кода до того, как возникнет исключение, и используете отладчик, чтобы посмотреть на ваши данные и точно выяснить, что они содержат - не то, что вы думаете, что они содержат, не то, с чего вы начали: что они на самом деле содержат, какую строку вы на самом деле отправляете в SQL, например.

Запуск в отладчике не решает вашу проблему: он позволяет вам собирать информацию, чтобы решить, как решить вашу проблему. Поэтому используйте его, чтобы точно выяснить, что происходит, и вы / мы сможем выработать решение.

BassamKassem

Я использовал его и вот что я заметил

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