简体   繁体   English

如何查询数据库以及如何通过第二个查询联接结果(VB.NET)

[英]How to query DB, and Join results with second query (VB.NET)

I'm fairly new to VB.NET, and have what I hope is an easy problem. 我是VB.NET的新手,我希望这是一个简单的问题。 I'm trying to query a DB, store results to a Dataset, and then query the same DB, and Join the results for a DELETE task. 我正在尝试查询数据库,将结果存储到数据集,然后查询同一数据库,并为删除任务加入结果。 Here's what I have so far, if anyone has a moment to assist. 如果有人有时间可以帮助,这就是我到目前为止的情况。 Thanks in advance. 提前致谢。 Also; 也; I prefer to learn what I've done wrong, rather than someone just telling me how to fix it. 我更喜欢了解自己做错了什么,而不是只是告诉我如何解决。

   Private Sub cmdDelete_Click(sender As System.Object, e As System.EventArgs) Handles cmdDelete.Click
    'Set/Open Connection
    Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\youngje\Documents\SQL Server Management Studio\Projects\Nwind.accdb")
    con.Open()

    'Set TIMEID
    Dim Yr, Mnth, fRng As String
    Yr = Year(Now)
    Mnth = Format(Month(Now), "00")
    fRng = Yr + Mnth + "00"

    'Query 1/Fill Temp Table (tmp)
    Dim cmdA As OleDbCommand = New OleDbCommand("SELECT PRODUCT, SHIPTO, TIMEID " & _
                                                "FROM tblFactSales " & _
                                                "WHERE (BILLTO = 'INPUT_BILLTO') AND (BRANCHPLANT = 'INPUT_BRANCHPLANT') AND (FRTHANDLE = 'INPUT_FRTHANDLE') AND (DATATYPE = 'FORECAST') AND (TIMEID > '" & fRng & "' )" & _
                                                "AND (SIGNEDDATA >= - .01) AND (SIGNEDDATA <= .01) AND (SALESDATA = 'short_tons')", con)

    'Query 2, joined with Query 1
    Dim cmdB As OleDbCommand = New OleDbCommand("DELETE FS " & _
                                                "FROM tblFactSales as FS INNER JOIN tmp T" & _
                                                "ON FS.PRODUCT=T.PRODUCT AND FS.SHIPTO=T.SHIPTO AND FS.TIMEID=T.TIMEID " & _
                                                "WHERE (FS.DATATYPE = 'FORECAST') AND (FS.TIMEID > '" & fRng & "' )", con)


    'Execute Queries
    cmdA.ExecuteNonQuery()
    cmdB.ExecuteNonQuery()

    'Clean Up
    cmdA.Dispose()
    cmdB.Dispose()
    con.Close()
    GC.Collect()

    'Confirmation
    MessageBox.Show("Records Removed Successfully.", "Clear Complete", _
        MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)
End Sub

havent totallty fixed it, but I think I'm getting closer. 还没有完全解决它,但是我想我越来越近了。 I'm getting a "Record is deleted" error now on cmdB.ExecuteNonQuery. 我在cmdB.ExecuteNonQuery上收到“记录已删除”错误。 It creates/populates the tmp table, but nothing gets deleted. 它创建/填充了tmp表,但是没有任何内容被删除。

Updated Code: 更新的代码:

    Private Sub cmdDelete_Click(sender As System.Object, e As System.EventArgs) Handles cmdDelete.Click
    'Set/Open Connection
    Dim con As OleDbConnection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\youngje\Documents\SQL Server Management Studio\Projects\Nwind.accdb")
    con.Open()

    'Set TIMEID
    Dim Yr, Mnth, fRng As String
    Yr = Year(Now)
    Mnth = Format(Month(Now), "00")
    fRng = Yr + Mnth + "00"

    'SELECT, to find unique IDs (PRODUCT, SHIPTO, TIMEID, DATATYPE)
    Dim cmdA As OleDbCommand = New OleDbCommand("SELECT PRODUCT, SHIPTO, TIMEID, DATATYPE INTO tmp IN 'C:\Users\youngje\Documents\SQL Server Management Studio\Projects\Nwind.accdb'" & _
                                                "FROM tblFactSales " & _
                                                "WHERE (BILLTO = 'INPUT_BILLTO') AND (BRANCHPLANT = 'INPUT_BRANCHPLANT') AND (FRTHANDLE = 'INPUT_FRTHANDLE') AND (DATATYPE = 'FORECAST') AND (TIMEID >= '" & fRng & "' )" & _
                                                "AND (SIGNEDDATA >= - .01) AND (SIGNEDDATA <= .01) AND (SALESDATA = 'short_tons')", con)

    'DELETE, joined with cmdA results
    Dim cmdB As OleDbCommand = New OleDbCommand("DELETE tblFactSales.* " & _
                                                "FROM tblFactSales INNER JOIN tmp T " & _
                                                "ON tblFactSales.PRODUCT=T.PRODUCT AND tblFactSales.SHIPTO=T.SHIPTO AND tblFactSales.TIMEID=T.TIMEID", con)

    'Execute Queries
    cmdA.ExecuteNonQuery()
    cmdB.ExecuteNonQuery()

    'Clean Up
    cmdA.Dispose()
    cmdB.Dispose()
    con.Close()
    GC.Collect()

    'Confirmation
    MessageBox.Show("Records Removed Successfully.", "Clear Complete", _
        MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)

End Sub

I'm not positive, but in looking at the function prototypes for DataAdapter.Fill, I can't imagine this would be filling up a table in the database, but rather a client side data set that can be iterated in .NET. 我不是很肯定,但是在查看DataAdapter.Fill的函数原型时,我无法想象这会填满数据库中的表,而是可以在.NET中进行迭代的客户端数据集。

Rather than attempt to perform a join against a client side result set, would it be fitting to create the temp table with SQL? 与其尝试对客户端结果集执行联接,不如使用SQL创建临时表是否合适? Many RDBMS's support such a feature. 许多RDBMS都支持这种功能。 Particularly the dialect that comes to mind would be: 特别是想到的方言是:

SELECT * INTO #tempTable FROM table;

This doesn't return a result set, but rather populates a temp table on the connection (perhaps within the transaction based on the database system). 这不会返回结果集,而是在连接上填充临时表(可能在基于数据库系统的事务中)。 The temp table can then be joined against other tables for that connection and used within SQL/DML statements. 然后可以将临时表与该连接的其他表联接,并在SQL / DML语句中使用。

Apart from that, it's not entirely clear what the goal is between the select and later executed delete. 除此之外,还不清楚在选择和随后执行的删除之间的目标是什么。 The where clause is identical in both queries, so if no processing or data changes are executed between the select a delete, the idea of joining the two is gratuitous. 这两个查询中的where子句相同,因此,如果在选择删除操作之间未执行任何处理或数据更改,则将两者结合在一起的想法是不必要的。 It's possible you may be able to simply execute a DELETE statement with the WHERE clause and not the join, and accomplish the same goal. 可能您可以仅使用WHERE子句而不是联接执行DELETE语句,并实现相同的目标。

Hope This Helps! 希望这可以帮助!

I've reworked your queries using SSMS for formatting and readability. 我已经使用SSMS重新整理了您的查询,以提高格式和可读性。 Reintegrate them in your code and see if they help. 将它们重新集成到您的代码中,看看它们是否有帮助。

  INSERT  INTO tmp
        (
         PRODUCT
        ,SHIPTO
        ,TIMEID
        ,DATATYPE
        )
        SELECT  PRODUCT
               ,SHIPTO
               ,TIMEID
               ,DATATYPE
        FROM    tblFactSales
        WHERE   (BILLTO = 'INPUT_BILLTO')
                AND (BRANCHPLANT = 'INPUT_BRANCHPLANT')
                AND (FRTHANDLE = 'INPUT_FRTHANDLE')
                AND (DATATYPE = 'FORECAST')
                AND (TIMEID >= ' & fRng & ')
                AND (SIGNEDDATA >= -.01)
                AND (SIGNEDDATA <= .01)
                AND (SALESDATA = 'short_tons')

DELETE  tblFactSales
WHERE   EXISTS ( SELECT 'True'
                 FROM   tmp T
                 WHERE  tblFactSales.PRODUCT = T.PRODUCT
                        AND tblFactSales.SHIPTO = T.SHIPTO
                        AND tblFactSales.TIMEID = T.TIMEID )

I will say that I'm still confused as to why you use the tmp table or why you are deleting data in this manner. 我会说我仍然对为什么使用tmp表或为什么要以这种方式删除数据感到困惑。 But give these queries a shot and see if they help. 但是试一下这些查询,看看它们是否有帮助。

i had several things wrong, but Ive gotten it to work finally. 我有几处错了,但是我终于开始工作了。 here's what I ended up with. 这就是我最终得到的。

Private Sub cmdDelete_Click(sender As System.Object, e As System.EventArgs) Handles cmdDelete.Click

    Dim Con As SqlConnection = New SqlConnection("Server = OVP-L-R8MXE5M\SQLEXPRESS;" & "Database = dbTest;" & "Trusted_Connection=TRUE")
    Con.Open()

    Dim Yr, Mnth, fRng As String
    Yr = Year(Now)
    Mnth = Format(Month(Now), "00")
    fRng = Yr + Mnth + "00"

    Dim cmdA As SqlCommand = New SqlCommand("SELECT PRODUCT, SHIPTO, TIMEID, DATATYPE INTO tmp " & _
                                                "FROM tblFactSales " & _
                                                "WHERE (BILLTO = 'INPUT_BILLTO') AND (BRANCHPLANT = 'INPUT_BRANCHPLANT') AND (FRTHANDLE = 'INPUT_FRTHANDLE') AND (DATATYPE = 'FORECAST') AND (RPTCURRENCY = 'USD') AND (TIMEID >= '" & fRng & "') " & _
                                                "AND (SIGNEDDATA >= - .01) AND (SIGNEDDATA <= .01) AND (SALESDATA = 'short_tons')", Con)

    Dim cmdB As SqlCommand = New SqlCommand("DELETE tblFactSales " & _
                                                "FROM tblFactSales RIGHT JOIN tmp " & _
                                                "ON tblFactSales.PRODUCT=tmp.PRODUCT AND tblFactSales.SHIPTO=tmp.SHIPTO AND tblFactSales.TIMEID=tmp.TIMEID AND tblFactSales.DATATYPE=tmp.DATATYPE", Con)

    cmdA.ExecuteNonQuery()
    cmdB.ExecuteNonQuery()

    MessageBox.Show("Records Removed Successfully.", "Clear Complete", _
        MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)

End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM