Query is too complex.

StewartBW 1,805 Reputation points
2024-05-24T08:22:33.26+00:00

Hello

To delete many selected records at once:

In a loop I populate question marks: QuestionMarks = QuestionMarks + "?, "

Then:

"DELETE FROM table WHERE theID = ? AND fld IN (" + QuestionMarks + ")"

And:

For Each MyRow As DataGridViewRow In DataGridView.SelectedRows

...Parameters.AddWithValue("@fld", MyRow.Cells.Item(0).Value.ToString)

Next

For small number of records, it works, I tested on 20,000 records and got error:

Query is too complex.

Microsoft 365 and Office | Access | Development
Developer technologies | VB
Developer technologies | C#
{count} votes

3 answers

Sort by: Most helpful
  1. Jiachen Li-MSFT 34,221 Reputation points Microsoft External Staff
    2024-05-24T09:36:46.68+00:00

    Hi @StewartBW ,

    You can try using a temporary table to store the IDs of the rows to be deleted, and then perform a single delete operation based on this temporary table.

    Best Regards.

    Jiachen Li


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Viorel 122.6K Reputation points
    2024-05-24T12:57:55.39+00:00

    To avoid inserting or deleting data row-by-row, consider operating on group of rows, for example:

    For Each chunk In DataGridView.SelectedRows.Cast(Of DataGridViewRow).Chunk(30)
    
        ' build QuestionMarks based on 'chunk.Length'
        ' ...
    
        For Each MyRow In chunk
    
            '... Parameters.AddWithValue("@fld", MyRow.Cells.Item(0).Value.ToString)
    
        Next
    
        ' execute 'DELETE FROM table WHERE theID = ? AND fld IN (" + QuestionMarks + ")"'
        ' ...
    Next
    

    Try any value instead of 30 that is accepted by Access.

    (Chunk is available in .NET 7 etc.)

    0 comments No comments

  3. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2024-05-24T21:13:32.9666667+00:00

    You can do this with Dapper where in the example below one condition is done but can be done with one than one condition.

    The identifiers would be collected by first iterating the DataGridView SelectedRows.

    public void Remove(List<int> identifiers)
    {
        var statement =
            """
             DELETE FROM table 
             WHERE theID IN @Identifier
            """;
        _cn.Execute(statement, identifiers);
    }
    
    Public Sub Remove(ByVal identifiers As List(Of Integer))
    	Dim statement = "DELETE FROM table WHERE theID IN @Identifier"
    	_cn.Execute(statement, identifiers)
    End Sub
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.