简体   繁体   中英

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. 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. It creates/populates the tmp table, but nothing gets deleted.

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.

Rather than attempt to perform a join against a client side result set, would it be fitting to create the temp table with SQL? Many RDBMS's support such a feature. 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.

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. 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.

Hope This Helps!

I've reworked your queries using SSMS for formatting and readability. 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. 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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