1. 程式人生 > >vb.net 下的sql多表查詢問題

vb.net 下的sql多表查詢問題

前一陣子在做一個關於配件維修程式的專案
技術選型為vb.Net 和access資料庫
資料庫的結構是這樣的
分別有客戶表,機器表,配件表三個基本資訊表
將客戶和機器資訊對應形成客戶機器表,為客戶機器表中的機器新增配件形成機器配件表,像機器配件表裡加維修時間形成配件維修表
在一個datagridview中我首先想實現的功能是統計客戶的機器數
sql 語句是這麼寫的
</pre><pre name="code" class="sql">select 客戶表.ID as ID,客戶表.姓名,count(機器客戶表.ID) as 機器數,客戶表.電話 as 客戶電話,客戶表.手機 as 客戶手機,客戶表.聯絡地址 as 客戶地址,客戶表.備註 as 備註 
from 客戶表  left join 機器客戶表 on  客戶表.ID=機器客戶表.客戶號  group by 客戶表.ID,客戶表.姓名,客戶表.電話,客戶表.手機,客戶表.聯絡地址,客戶表.備註 

而後再連表中join 配件表後,隨著記錄的增加,機器數目將會發生變化

而且accees 不支援distinct 函式

然後我採取的解決方案是

 Public Function willPjCount(ByVal khId As String) As String '返回即將維修配件數量
        On Error GoTo ErrorHandler
        Dim con = New OleDbConnection(Autumn_CString1)
        Dim Sql As String
        willPjCount = 0
        Sql = "select sum(iif(DateDiff('d',date(),配件機器表.提醒時間)>0 and DateDiff('d',date(),配件機器表.提醒時間)<配件表.預警時間, 1,0)) as 即將維修配件數"
        ' ''sqlshowJqData = sqlshowJqData & "機器客戶表.備註 as 備註"
        Sql = Sql & " from 客戶表,機器客戶表,配件機器表,配件表 where 客戶表.ID=機器客戶表.客戶號 and 配件機器表.機器ID = 機器客戶表.ID  and 配件表.ID =配件機器表.配件ID " & khId
        con.Open()
       
        Dim cmd = New OleDbCommand(Sql, con)
        Dim myreader As OleDbDataReader = cmd.ExecuteReader
        While myreader.Read

            If myreader("即將維修配件數").GetType.ToString() = "System.Double" Then
                willPjCount = myreader("即將維修配件數")
            End If
        End While
        cmd.Dispose()
        con.Close()
        Exit Function
ErrorHandler:
        MsgBox("錯誤號:" & Err.Number & vbCrLf & +Err.Description, vbExclamation + vbOKOnly, "其他錯誤!")
        Exit Function

    End Function
 Public Function OutPjCount(ByVal khId As String) As String '返回過期維修配件數量
        On Error GoTo ErrorHandler
        Dim con = New OleDbConnection(Autumn_CString1)
        Dim Sql As String
        OutPjCount = 0
        Sql = "select sum(iif(DateDiff('d',date(),配件機器表.提醒時間)<0 , 1,0)) as 過期維修配件數"
        ' ''sqlshowJqData = sqlshowJqData & "機器客戶表.備註 as 備註"
        Sql = Sql & " from 客戶表,機器客戶表,配件機器表 where 客戶表.ID=機器客戶表.客戶號 and 配件機器表.機器ID = 機器客戶表.ID   " & khId


        con.Open()
        Dim cmd = New OleDbCommand(Sql, con)
        Dim myreader As OleDbDataReader = cmd.ExecuteReader
        While myreader.Read


            OutPjCount = myreader("過期維修配件數")


        End While


        cmd.Dispose()
        con.Close()
        Exit Function
ErrorHandler:
        'MsgBox("錯誤號:" & Err.Number & vbCrLf & "錯誤內容:系統基本資訊" & khId & "設定不完整,請新增供應商名稱", vbExclamation + vbOKOnly, "其他錯誤!")
        Exit Function


    End Function
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">而後採取的解決方案是在myread裡二次讀取</span>
<span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Arial, Helvetica, sans-serif;"> willPj = willPjCount("and 客戶表.ID =" & myreader("ID"))</span>
   outPj = OutPjCount("and 客戶表.ID =" & myreader("ID"))
    .Rows(i).Cells(4).Value = willPj
   .Rows(i).Cells(5).Value = outPj
    If Convert.ToInt32(willPj) > 0 Then
      .Rows(i).Cells(4).Style.BackColor = Color.Red
   End If
    If Convert.ToInt32(outPj) > 0 Then
    .Rows(i).Cells(5).Style.BackColor = Color.Blue
    End If
    .Rows(i).Cells(6).Value = myreader("客戶電話")
    .Rows(i).Cells(7).Value = myreader("客戶手機")
    .Rows(i).Cells(8).Value = myreader("客戶地址")
      .Rows(i).Cells(9).Value = myreader("備註")

但在記錄數超過20個時,就會出線未知的錯誤

最後的解決方案

Dim cmd = New OleDbCommand(Sql, con)
            Dim myreader As OleDbDataReader = cmd.ExecuteReader
            Dim i As Integer
            Dim idI As New Dictionary(Of String, Integer)
            Dim outPj As String = ""
            Dim willPj As String = ""
            Dim tempId As Integer
            Dim maxId As Integer
            i = 0
            With datagridview_t
                .Columns.Clear()
                客戶資訊列表頭初始化(datagridview_t)
                While (myreader.Read)
                    .Rows.Add()
                    .Rows(i).Cells(1).Value = myreader("ID")
                    idI.Add(myreader("ID"), i)


                  
                    .Rows(i).Cells(2).Value = myreader("姓名")
                    .Rows(i).Cells(3).Value = myreader("機器數")
                 
                    .Rows(i).Cells(6).Value = myreader("客戶電話")
                    .Rows(i).Cells(7).Value = myreader("客戶手機")
                    .Rows(i).Cells(8).Value = myreader("客戶地址")


                    .Rows(i).Cells(9).Value = myreader("備註")




                    i = i + 1
                End While
                maxId = i - 1
                Sql = "select   客戶表.ID as ID,sum(iif(DateDiff('d',date(),配件機器表.提醒時間)>-7 and DateDiff('d',date(),配件機器表.提醒時間)<配件表.預警時間, 1,0)) as 即將維修配件數,sum(iif(DateDiff('d',date(),配件機器表.提醒時間)<-7 , 1,0))  as 過期維修配件數"
             
                Sql = Sql & " from 客戶表,機器客戶表,配件機器表,配件表 where 客戶表.ID=機器客戶表.客戶號 and 配件機器表.機器ID = 機器客戶表.ID  and 配件表.ID =配件機器表.配件ID     group by 客戶表.ID"
                cmd = New OleDbCommand(Sql, con)
                myreader = cmd.ExecuteReader
                i = 0
                While (myreader.Read)




                    tempId = i
                    If tempId <> 0 Then
                        tempId += 1
                    End If
                    i = idI(myreader("ID"))
                    For j = tempId To i - 1
                        .Rows(j).Cells(4).Value = 0
                        .Rows(j).Cells(5).Value = 0
                    Next
                    .Rows(i).Cells(4).Value = Convert.ToInt32(myreader("即將維修配件數"))
                    .Rows(i).Cells(5).Value = Convert.ToInt32(myreader("過期維修配件數"))
                    If .Rows(i).Cells(4).Value > 0 Then


                        .Rows(i).Cells(4).Style.BackColor = Color.Red
                    End If
                    If .Rows(i).Cells(5).Value > 0 Then
                        .Rows(i).Cells(5).Style.BackColor = Color.Blue
                    End If


                    willPj = willPjCount("and 客戶表.ID =" & myreader("ID"))
                    outPj = OutPjCount("and 客戶表.ID =" & myreader("ID"))


                    .Rows(i).Cells(4).Value = willPj
                    .Rows(i).Cells(5).Value = outPj


                    If Convert.ToInt32(willPj) > 0 Then
                        .Rows(i).Cells(4).Style.BackColor = Color.Red
                    End If
                    If Convert.ToInt32(outPj) > 0 Then
                        .Rows(i).Cells(5).Style.BackColor = Color.Blue
                    End If
                    .Rows(i).Cells(6).Value = myreader("客戶電話")
                    .Rows(i).Cells(7).Value = myreader("客戶手機")
                    .Rows(i).Cells(8).Value = myreader("客戶地址")


                    .Rows(i).Cells(9).Value = myreader("備註")






                End While
                For j = i + 1 To maxId
                    .Rows(j).Cells(4).Value = 0
                    .Rows(j).Cells(5).Value = 0
                Next
   


                .Rows.Add()


            End With 

還是沒有實現一次sql實現,在研究還有什麼好的方法,還有第一次讀取的結果加在第二次後面的In 會提高效率,但資料量不是很大,並沒有寫