【问题标题】:Dynamically build a SQL Insert statement based on results from a DataView根据 DataView 的结果动态构建 SQL Insert 语句
【发布时间】:2021-03-25 18:59:29
【问题描述】:

我有一个旧的数据记录工业应用程序,我正在为其编写一个新界面。该程序允许您选择设备上的点,将它们保存到配置文件,然后选择要应用该配置文件的设备。当您应用配置文件时,它会使用设备唯一 ID 作为表名为每个设备创建一个表,并为您将使用唯一点 ID 记录的每个数据点创建列。例如,我选择 3 个信息点进行数据记录,并将这三个点保存为配置文件(保存到它自己的表中),然后将点保存到标记有该配置文件的点表中:

PointID      PointName     ProfileID
33            Temp23        1
34            Hum14         1
35            Stat          1

然后我选择几个设备并将该配置文件应用到设备表中:

DeviceID     DeviceName     ProfileID
5            NWUnit         1
6            NEUnit         1

保存设备后,它会为每个设备创建表,例如:

Table Name:  DEV5
Column 1:  PNT1 - Float
Column 2:  PNT2 - Float
Column 3:  PNT3 - Bit

如您所见,表名与设备 ID 直接相关,列名与点 ID 直接相关。我可以从配置文件中添加/删除点,它会根据需要添加/删除列。应用不同的配置文件,DEV 表将被删除并重新创建。一切正常,就像被替换的旧程序一样。

现在我需要实际进行数据记录。我创建了一个简单的视图:

SELECT     dbo.Devices.DeviceID, dbo.Points.PointName, dbo.Points.PointID
FROM       dbo.Devices LEFT OUTER JOIN
                dbo.Points ON dbo.Devices.ProfileID = dbo.Points.ProfileID

到目前为止还不错:

DeviceID     PointName     PointID
5            Temp23         33
5            Hum14          34
5            Stat           35 
6            Temp23         33
6            Hum14          34
6            Stat           35

我将其放入 DataTable 中,对其执行 Columns.Add("Value") 以获得空白列,然后进行数据检索。完成后,我现在有了带有检索值的表:

DeviceID     PointName     PointID     Value
5            Temp23         33          72.34
5            Hum14          34          43.8
5            Stat           35          1
6            Temp23         33          76.80
6            Hum14          34          54.2
6            Stat           35          0

这就是我卡住的地方。我需要获取此信息,使用 DeviceID 作为表名,使用 PointID 作为列名,然后插入数据。换句话说,我需要这个:

Dim myParamList As New Dictionary(Of String, Object) From {
                        {"@SampleTime", Date.Now},
                        {"@DevTable", "Dev" & r.Item("DeviceID")},
                        HOW DO I CYCLE THROUGH TO GET THE COLUMNS HERE?
                    }
                    UpdateDatabase(MySQLConnection, "INSERT INTO @DevTable (SampleTime, AND HERE?) VALUES (@SampleTime, AND HERE)", myParamList)

我无法弄清楚循环部分。我想我应该使用 Count + Group By 来找出有多少行具有相同的设备 ID,例如 DeviceID 5 有 3 行,并使用它来循环该次数,但我只是想弄清楚如何.

对最好的方法有什么建议吗?

【问题讨论】:

    标签: sql-server vb.net


    【解决方案1】:

    因此,在努力尝试在数据视图上执行 GroupBy 之后,我决定使用 Count(*) 和 GroupBy DeviceID 进行另一个数据库查询,以获取我唯一的 DeviceID:

    DeviceID     RowCount
    5             3
    6             3
    

    然后我用它来循环遍历设备 ID,并根据需要使用 ID 过滤 myView。然后我动态创建了一个参数化的 SQL 字符串并更新了数据库:

    For Each r As DataRow In DevIDDataset.Tables("DeviceIDs").Rows
        myView.RowFilter = "DeviceID=" & r.Item("DeviceID")
        Dim myParamList As New Dictionary(Of String, Object) From {
            {"@SampleTime", Date.Now}
        }
        Dim myFields As String = "SampleTime"
        Dim myValues As String = "@SampleTime"
        For Each row As DataRowView In myView
            Dim myPointID As String = row.Item("PointID")
            myFields += ",obj" & myPointID
            myParamList.Add("@obj" & myPointID, row.Item("RetrievedValue"))
            myValues += ",@obj" & myPointID
        Next
        UpdateDatabase(MySQLConnection, "INSERT INTO dev" & r.Item("DeviceID") & " (" & myFields & ") VALUES (" & myValues & ")", myParamList)
    Next
    

    不漂亮,但它做了它需要做的事情,我想不出任何其他方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      相关资源
      最近更新 更多