首页 > 解决方案 > 简化 TSQL 语句以避免在 VB.NET、OLEDB 中出现“过于复杂”的异常

问题描述

我想重写以下 SQL 语句以避免异常Expression too complex in query expression。表达式的含义是在 Excel 数据表中查找特定的行号(使用 VB.NET,在本例中为第二行,不包括标题)。仅接受 26 个 OR。我尝试了很多不同的方法,包括嵌套 SQL 语句,但还没有找到解决方案(有没有办法用嵌套 SQL 来满足条件?)。非常感谢!

简化:(SELECT ... WHERE ... OR ... OR ... OR ... ...太多的 OR)

`SELECT TOP 1 * FROM [Daten$] 
WHERE [Ab] NOT IN (SELECT TOP 1 [Ab] FROM [Daten$]) 
OR [Abgrenzungsgrund] NOT IN (SELECT TOP 1 [Abgrenzungsgrund] FROM [Daten$]) 
OR [Abrechnungsmenge] NOT IN (SELECT TOP 1 [Abrechnungsmenge] FROM [Daten$]) 
OR [Abschl 01] NOT IN (SELECT TOP 1 [Abschl 01] FROM [Daten$])
OR ...` (and so on)

连接字符串(如果相关):"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='foo.xlsx';Extended Properties=Excel 12.0 Xml;"

任何想法?先感谢您!

有没有一种简单的方法可以自动将 sql 子查询的结果值作为参数传递?我发现参数化查询允许更多的条件。

标签: vb.nettsqloledb

解决方案


您可以返回所有行,然后使用 LINQ 跳过并获取第一个元素。

Sub Main()
    Dim result = getNthRow(3)
    Console.WriteLine(result)
    Console.ReadLine()
End Sub

Private Function getNthRow(n As Integer) As Daten
    Dim result As Daten
    If n < 1 Then Throw New ArgumentException("Row number must be 1 or greater", NameOf(n))
    Dim connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='foo.xlsx';Extended Properties=Excel 12.0 Xml;"
    Dim adapter As New OleDbDataAdapter
    Using connection As New System.Data.OleDb.OleDbConnection(connectionString)
        connection.Open()
        Using command = New OleDbCommand("SELECT * FROM [Daten$]", connection)
            adapter.SelectCommand = command
            Using dataset As New DataSet()
                adapter.Fill(dataset)
                ' exception here if n too large
                Dim datarow = dataset.Tables(0).AsEnumerable.Skip(n - 1).First()
                result = New Daten With {
                    .Ab = CInt(datarow.Field(Of Double)("Ab")),
                    .Abgrenzungsgrund = datarow.Field(Of String)("Abgrenzungsgrund"),
                    .Abrechnungsmenge = datarow.Field(Of String)("Abrechnungsmenge"),
                    .Abschl01 = datarow.Field(Of String)("Abschl 01"),
                    .Abschl02 = datarow.Field(Of String)("Abschl 02"),
                    .Abschl03 = datarow.Field(Of String)("Abschl 03"),
                    .Abschl04 = datarow.Field(Of String)("Abschl 04"),
                    .Abschl05 = datarow.Field(Of String)("Abschl 05")}
            End Using
        End Using
    End Using
    Return result
End Function

这是您的结果的类,因此可以进行强类型化。您应该修改属性和类型以更准确地表示您的数据

Class Daten
    Public Property Ab As Integer
    Public Property Abgrenzungsgrund As String
    Public Property Abrechnungsmenge As String
    Public Property Abschl01 As String
    Public Property Abschl02 As String
    Public Property Abschl03 As String
    Public Property Abschl04 As String
    Public Property Abschl05 As String
    Public Overrides Function ToString() As String
        Return $"{Ab}, {Abgrenzungsgrund}, {Abrechnungsmenge}, {Abschl01}, {Abschl02}, {Abschl03}, {Abschl04}, {Abschl05}"
    End Function
End Class

推荐阅读