Deleting First Record Only

Joined
Jan 15, 2009
Messages
21
Programming Experience
5-10
I have a vb.net app that manages orders for a small retail store. If they have placed two of the same item in the same order and only need 1, there is a button to delete the item from the database.

The problem comes in my SQL statement which is "DELETE FROM OrderSpecs WHERE Style = '" & style & "' AND Color = '" & color & "' AND Order = '" & order & "' "

This removes both entries from the database since they have the same values. I was wondering if there is a way to delete only the first entry that fits this statement. Thanks
 
Try this:

VB.NET:
SET ROWCOUNT 1
"DELETE FROM OrderSpecs WHERE Style = '" & style & "' AND Color = '" & color & "' AND Order = '" & order & "' "
SET ROWCOUNT 0
' (1 row(s) affected)

Or this:
VB.NET:
"DELETE TOP(1) FROM OrderSpecs WHERE Style = '" & style & "' AND Color = '" & color & "' AND Order = '" & order & "' "
' (1 row(s) affected)
 
Neither of those worked for me.

The first gave me the error "Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'."

The second gave me the error "Syntax error in delete statement."
 
1. Always parameterize your queries - follow the link in my signature.

2. Try something like :-

VB.NET:
DELETE FROM
  OrderSpecs
WHERE
  OrderSpecs.ID IN
  (
    SELECT
      TOP 1
        OrderSpecs.ID
    FROM
      OrderSpecs
    WHERE
      OrderSpecs.Style = @STYLE
    AND
      OrderSpecs.Color = @COLOR
    AND
      OrderSpecs.Order = @ORDER
  )

I've assumed that ID is your Primary Key field. I would also look closely at your field names - I'm sure in most databases, Order is a reserved word and should not be utilised as a field name.
 
Delete with top clause

Please try this:
VB.NET:
"DELETE TOP 1 * FROM OrderSpecs WHERE Style = '" & style & "' AND Color = '" & color & "' AND Order = '" & order & "' "
' (1 row(s) affected)
Btw, what database are you using?

I guess it would be useful if the Admin provides an option for specifying database you use. MSSQL, MYSQL, ORACLE, MSACCESS etc.
Thanks!
 
If an item per order needs to be unique then set your database table up to enforce this restriction (primary key, constraints etc)....

To often I see a similar scenario where an identity seed column is used for the primary key but the actual columns that need to be unique per table do not have any constraints at all. Then extra coding and processing time needs to be done in order to check for these records, clean up like your trying to do here etc...

(and this is a fight I constantly have with my own boss who thinks every table should have an identity seed/primary key but he cant tell ya why...)
 
Inertia - I don't have a primary key in this table, so I used another field for ID in your statement. That ended up still deleting both entries. The field is actually OrderNum but I just typed Order to abbreviate.

Tom - Are you telling me that there is no way to delete just the top 1 from my database without a primary key? It seems like a function that would not be hard to implement.
 
Not at all... to clarify you can delete whatever records you specify. What I am saying is if you set up the proper constraints you should not have to delete anything... Deleting the record is an attempt to fix a problem after it has occurred rather then preventing the problem before it happens in the first place.

Without knowing what each of the fields are in your table, I'm guessing there is at least one field if not a combination of fields that need to be unique in the table, such as the OrderNumber & ItemNumber fields (guessing at field names). By setting these fields (in this example it would be a composite key since it is more then one field) as the primary key, it would automatically prevent an duplicate item for this order from ever being inserted into the table.
 
Last edited:
I assure you that this code deletes only one record.
"DELETE TOP 1 * FROM OrderSpecs WHERE Style = '" & style & "' AND Color = '" & color & "' AND [Order] = '" & order & "'"


Notice that Order is reserved word in most of the database's

OrderNum is actually the name of the field, so I am not using any reserved words.

Still, this delete statement gives me the error - "Syntax error in delete statement."

I am using MSACCESS by the way.
 
I assure you that this code deletes only one record.
"DELETE TOP 1 * FROM OrderSpecs WHERE Style = '" & style & "' AND Color = '" & color & "' AND [Order] = '" & order & "'"

I could not get "Delete Top 1 *" to work in Sql Server however a slight syntax change did work:

VB.NET:
Delete Top (1) From....
 
Matt can you list the field names in your table?

Is there an identity seed field (doesnt matter if its a key or not) in your table or another field such as a time stamp that would signify the newest record to delete? If so you could use a subquery to find which one record to delete.

Delete OrderSpecs
Where OrderNum =
(Select Max(OrderNum)
From OrderSpecs
Where filter critera here)

To ensure unique records keys should be defined. If you do want the user to be able to add multiple items of the same item to an order, a quantity field should be used. And this would depend on your table struture but you might even be better served by creating a seperate table for your items records. If you set everything up correctly there shouldnt be the need to have to delete records that were just added.
 
The fields are:
Style
Description
Color
Size1
Size2
Size3
...until Size15 (These fields store the amount of units ordered for each size)
Cost
Retail
Season
Division
Department
OrderNumber
Vendor

None of these fields have any kind of time stamp. I guess I will just create a new autonumber field that can contain no duplicates and just delete by that number. I just thought that Microsoft would have some way around this to deal with people like me.

Thanks for your help Tom.
 
Yes by implementing an identity seek you can use a subquery to search for the Max seed that fits your filter.

What detemines whether an item is unique or from any other item (besides comparing every field)? Dont the items have a corrosponding item number? Also consider adding a quantity field when there is more then one item in the same order - you never want redundent data....
 
I just thought that Microsoft would have some way around this to deal with people like me.

2 points:
Your situation should not exist, because you should not have allowed it to. If you assert that a combination of Style,Description,Color are suitable for uniquely identifying a row in the table, then it should be the primary key.. it then becomes IMPOSSIBLE to insert a row having the same Style,Description,Color, so your situation would never come to exist

MS do have a way of dealing with duplicate rows in terms of flattening them into single rows, and it comes as part of an operation to apply a primary key. If there are duplicate values, you remove them by having the DB perform a grouping operation on all rows.

The following is meant for one time op only. Do not use this on a regular basis:
SELECT INTO table2 DISTINCT * FROM table1
DELETE FROM table1
SELECT INTO table1 * FROM table2 [or is the syntax INSERT INTO table1 SELECT * FROM table2 ? I can't remember]

If only some of the columns are used to determine duplication, your first query must be:

SELECT INTO table2 Size,Description,Color,MAX(Size1),MAX(Size2)... FROM table1 GROUP BY Size,Description,Color

There are other options, such as downloading into a client side datatable, scanning the rows and marking some as deleted, but you must appreciate that the concept of "first row" is very woolly: Databases store data in any order they choose, and are not guaranteed to return rows in the order of addition. As such if there is nothing you can specifically order by, you cannot rely that the return order is the addition order, and you'll have to review the rows manually. Be aware that using a group by query as noted above, you must choose your aggregate operations (MAX, SUM, AVG) carefully so as not to end up with a broken set of data i.e. if you cannot tolerate values from different rows being mixed, don't use MAX, because if your rows were:

Large, Jumper, Red, 4, 1
Large, Jumper, Red, 2, 5

You'd end up with this after the de-dupe:
Large, Jumper, Red, 4, 5


Might not be what you want - it's kidna a bed you made and have to lie in, because of no primary key being set up at the start of the db design phase


You can use the technique in your situation: Rather than trying to remove one row, write a query that groups the rows together (using distinct or group by) and insert the grouped row into another table, then delete both rows, and move the new row back
 
Back
Top