I need to update a record in a table if the record allready exists, but if it does not exist, I need to insert the record. Is there a 1-step SQL way of doing this?
I can easily perform the 2 step approach, of using a dLookup to determine if it exists, and based on that do either the Insert or Update, I'm just trying to work smarter, not harder :P
Other Info: Access 2003, Split frontend/Backend, both Access.
Table consists of a Primary Key made up of 3 columns, ID_EvalNode, ID_ObsType, ID_Bidder and 3 extra info fields, ID_User, dt_DateChanged, ID_Status. 28 35046
The only thing I can think of is to use a single ADO recordset that first looks for your existing record. Then using that same recordset, perform an Update or AddNew / Update depending.
ADezii 8,834
Recognized Expert Expert
I do not see this as a 1-Step SQL Based Process since it does involve Conditional Branching. The only was that I can possibly see this happening is via the EXISTS SQL Predicate in a Sub-Query in conjunction with IIf(). I'll call in the 'SQL Gang' on this one.
NeoPa 32,561
Recognized Expert Moderator MVP @TheSmileyOne
Since you ask - No. There's not.
Unfortunate I know, but I've never come across anything in SQL that supports this concept, though clearly the requirement for it is very real.
Then that answers my question just fine :)
As I wrote in the initial post, im perfectly capable of "working arond it", but every now and then when you do another work-around in another project, you stop and wonder if there is a smarter way of doing it.
NeoPa 32,561
Recognized Expert Moderator MVP
It was a very sensible question, and well phrased (unambiguous). I have no doubt you're more than capable of handling the job without this feature, should that be required (which seems to be the case). No further explanation is necessary.
ADezii 8,834
Recognized Expert Expert
It's nice knowing 'Who to Call', thanks.
NeoPa 32,561
Recognized Expert Moderator MVP
ok thinking about this again the ADO approach could work. Since you are doing an action (Update, Delete) either way. Just build your ADODB recordset then update the record it returns using a dynamic cursor. If it errors that means that there is no record to update in which case just handle that error to run an AddNew.
NeoPa 32,561
Recognized Expert Moderator MVP
I expect that would work, but as a non-SQL based approach I doubt it would fit the bill.
but as a non-SQL based approach
I don't understand what you mean by "non-SQL"... oh- you mean you want to avoid any type of VBA manipulation?..... the recordset is really nothing more than a glorified query object as you know. Doubt if it would take any extra system resources to run it as opposed to a srtaight SQL.
NeoPa 32,561
Recognized Expert Moderator MVP
Actually, I'm referring back to the OP's original request - for a SQL based solution.
In fact, using data manipulation within recordset code is generally orders of magnitude slower than straight SQL, but in this case that's beside the point really. It's only that the OP specifically requested a SQL based approach.
Ahhh totally get it : ) you are correct. It is, though perhaps a good alternative to consider because it only makes a single call as opposed to a two step: 1) check for record 2) run action query.
the OP's original intent was to 'work smarter' afterall...
Well this is the code I went with in the end: - Public Sub setStatus(lngNode As Long, lngBidder As Long, lngObsType As Long, lngNewStatus As Long)
-
Dim strSQL As String
-
'Does record allready exist?
-
If DCount("ID_Status", "tbl_EvalNodeStatus", "ID_EvalNode=" & lngNode & " AND ID_Bidder=" & lngBidder & " AND ID_ObsType=" & lngObsType) > 0 Then
-
'Doupdate
-
strSQL = "UPDATE tbl_EvalNodeStatus SET " & _
-
"ID_Status = " & lngNewStatus & "," & _
-
"ID_User = UserID()," & _
-
"dt_Changed = Now() " & _
-
"WHERE ((" & _
-
"(ID_Bidder)=" & lngBidder & ") AND (" & _
-
"(ID_EvalNode)=" & lngNode & ") AND (" & _
-
"(ID_ObsType)=" & lngObsType & "));"
-
Else
-
strSQL = "INSERT INTO tbl_EvalNodeStatus ( ID_Bidder, ID_EvalNode, ID_ObsType, ID_Status, ID_User, dt_Changed )" & _
-
" SELECT " & _
-
lngBidder & " AS IDBidder," & _
-
lngNode & " AS IDEvalNode," & _
-
lngObsType & " AS IDObsType," & _
-
lngNewStatus & " AS IDStatus, " & _
-
"Userid() AS idUser, " & _
-
"Now() AS dtWhen;"
-
-
End If
-
-
'Now perform update/insert
-
DoCmd.SetWarnings (False)
-
DoCmd.RunSQL strSQL
-
DoCmd.SetWarnings (True)
-
-
End Sub
And for yarborough, I have on a few occasions found it an order of magnitude faster working with DAO recordsets over ADO. Whether this was specific to the tasks I was doing at the time or if its a general thing I don't know. Haven't bothered me enough to make me research it yet. :)
yes - this seems to be the most intuitive way to approach it... a slightly different approach may be to skip the DLookUp and just run the queries. If the first one errors it will run the second Afterall you know you are going to fire an action query you just don't know which one. But doing this it doesn't matter. (it's basically a Try Catch) -
On Error Goto AddNewRecord
-
-
'TRY THIS FIRST
-
strSQL = "UPDATE tbl_EvalNodeStatus SET " & _
-
"ID_Status = " & lngNewStatus & "," & _
-
"ID_User = UserID()," & _
-
"dt_Changed = Now() " & _
-
"WHERE ((" & _
-
"(ID_Bidder)=" & lngBidder & ") AND (" & _
-
"(ID_EvalNode)=" & lngNode & ") AND (" & _
-
"(ID_ObsType)=" & lngObsType & "));"
-
DoCmd.SetWarnings (False)
-
DoCmd.RunSQL strSQL
-
DoCmd.SetWarnings (True)
-
Exit Sub
-
-
'FIRE THIS ONE IF THE FIRST ONE ERRORS (NO RECORD)
-
AddNewRecord:
-
strSQL = "INSERT INTO tbl_EvalNodeStatus ( ID_Bidder, ID_EvalNode, ID_ObsType, ID_Status, ID_User, dt_Changed )" & _
-
" SELECT " & _
-
lngBidder & " AS IDBidder," & _
-
lngNode & " AS IDEvalNode," & _
-
lngObsType & " AS IDObsType," & _
-
lngNewStatus & " AS IDStatus, " & _
-
"Userid() AS idUser, " & _
-
"Now() AS dtWhen;"
-
-
DoCmd.SetWarnings (False)
-
DoCmd.RunSQL strSQL
-
DoCmd.SetWarnings (True)
-
-
ADezii 8,834
Recognized Expert Expert
I think that a Variation on yarbrough40's approach in Post #9 may be more effective. - Perform an outright Insert on the Table.
- Trap the specific Error (Duplication on the Primary Key) that may occur should the Composite Primary Key already exist.
- Update the existing Record, only if the Error occurs, otherwise the Insert will be successful.
- This would have the advantage of occasionally being a 1-Step Process of Insertion when the Composite Key does not exist and avoids the use of DCount().
YES ADezii !!! well said....
ADezii 8,834
Recognized Expert Expert
Guess great minds just think alike! (LOL)
The update first, and Insert on error would not work. The update would run fine enough, just not change anything. (IE. no error).
ADezii makes a good point though.
ADezii 8,834
Recognized Expert Expert
Since the Topic was brought up (ADO vs DAO), I'm going to go off on a slight Tangent here, mention a few simple points, and hope NeoPa doesn't holler at me! (LOL) - DAO provides greater functionality, generally better performance, is simpler to implement, and tends to be more efficient when working with Jet-based data.
- ADO is a more 'modern' approach, and is more efficient than DAO when working with Server Data in code. Use ADO if you want to fill Recordsets with Server Data or to execute Server Commands.
- Did HE see me?
NeoPa 32,561
Recognized Expert Moderator MVP @ADezii
I think what you were looking for is Fools seldom differ!
Just kidding of course, but how could you expect me to pass that one up. Just not reasonable :D
In this case, I suspect you are either overlooking, or are unaware of, the impact of interrupting a SQL process. Allowed to work at full speed, a SQL process can make use of many very powerful optimisations. When a SQL process that is dealing with numbers of records allows VBA processes to run within itself (generally true when processing through a recordset), these benefits are lost (or at least overshadowed by the delays introduced). VBA is a semi-compiled (partially interpreted) system that is frankly not the fastest system invented for code. It generally doesn't need to be. Forms and reports processing (EG handling events) clearly doesn't require super-fast execution. When you allow it to get in the way of a SQL process however (Forget smaller numbers. We're talking hundreds, thousands, millions of records here) the inefficiencies introduced on a per record basis are multiplied many-fold (x record numbers), hence it is always important to be careful of introducing recordset processing into large datasets.
All that said, it does appear that the actual process in this case (determined by Smiley's code example) is actually only a single record at a time anyway. Personally, I'd still go for the simple approach, but with a single record the processing difference would never be noticed, so a little extra complication can't hurt. @ADezii
No. I was looking the other way at the time.
ADezii 8,834
Recognized Expert Expert
I was looking at it from a perspective of an always 2-Step Process (DCount()/UPDATE or INSERT) vs an occasional 1-Step Process (INSERT ONLY), which would probably be more frequent due to the nature of the 3-Field Composite Key and the likelihood of duplication. Don't really think that you can argue with that logic.
NeoPa 32,561
Recognized Expert Moderator MVP @ADezii
Oh, that's easy! It's just more complicated than necessary.
I've already allowed that, in the circumstances, it hardly matters, but KISS is always an axiom worth following when there is no appreciable benefit from clever coding.
ADezii 8,834
Recognized Expert Expert
Sorry, I'll still take efficiency over simplicity, any day.
nico5038 3,080
Recognized Expert Specialist
As stated, the one step approach won't be possible.
The most efficient way will be to remove all "update rows" on forehand using a DELETE query with a "WHERE EXISTS" and execute an INSERT to add all rows from the source.
This will save the effort of comparing/testing whether a row needs an update and by using two straight forwards queries the process will be a lot faster as the VBA appraoch as no code and no SQL-interpretation needs to be executed.
Nic;o)
NeoPa 32,561
Recognized Expert Moderator MVP @ADezii
I'm afraid I wasn't clear. The VBA approach is less efficient. It is just that it is by such a small margin when only one record is being processed (as appears to be the case in this instance) that it doesn't really matter.
If there's one benefit the VBA approach has over the straightforward SQL it is that it is very explicit as to what it's doing, for when someone comes to maintain it later.
It's funny how I remembered this post as I sit here at work doing my daily grind. It never occurred to me before now but as it turns out I do have a solution for this: It's not a single query but it IS a single statement that fits the bill. I simply fire a delete statement followed by the insert every time (no need for an update since the delete/insert combo would wipe out any existing record if it exists.
The only way this may not be effective is if there is some unique data in the original record that needs to be maintained for some reason. - DELETE FROM Table1 WHERE Col1 = 'A';INSERT INTO Table1(Col1,Col1)VALUES('B',1);
----as I just hit save on this, I read nico5038's post above who I believe is saying about the same thing.
ADezii 8,834
Recognized Expert Expert
Sorry, but I still agree on the Attempt to ADD/Error Trap approach. It involves no Conditional Branching, no Deletions, no Lookups, and the Error Trap can be as sophisticated as you wish. I'm now putting on my Flak Jacket! (LOL). -
Dim db As DAO.Database
-
Dim rst As DAO.Recordset
-
-
Set db = CurrentDb
-
Set rst = db.OpenRecordset("tblTest", dbOpenDynaset, dbAppendOnly)
-
-
With rst
-
.AddNew
-
![Field1] = 1
-
![Field2] = 2
-
![Field3] = 3
-
.Update
-
End With
-
-
Exit_Add_Record:
-
If Not rst Is Nothing Then
-
rst.Close
-
Set rst = Nothing
-
End If
-
Exit Sub
-
-
Err_Add_Record:
-
'Check the State of the Error Number
-
Select Case Err.Number
-
Case 3022 'Duplicate PK
-
MsgBox "Primary Key Violation"
-
Case Else 'Some other Error
-
MsgBox Err.Description
-
End Select
-
Resume Exit_Add_Record
NeoPa 32,561
Recognized Expert Moderator MVP
I recently came across (triggered by a question here on Bytes strangely enough) the idea of an UPSERT (or similar) statement being introduced into SQL ( Wikipedia - UPSERT).
Various good solutions have already been proposed within the thread, but I suspect, from reading the OP, that the simple matter of whether or not the facility exists was all Smiley was after. My earlier ramblings on performance and efficiency were related to a discussion on updates to a whole recordset (Therefore not directly related to this thread - though hopefully interesting to any that stumble across it).
Sign in to post your reply or Sign up for a free account.
Similar topics |
by: Karen Middleton |
last post by:
In MS Access I can do in one SQL statement a update if exists else a
insert.
Assuming my source staging table is called - SOURCE and my target
table is called - DEST and both of them have the same structure as
follows
Keycolumns
==========
Material
|
by: oldandgrey |
last post by:
I'm looking at producing an application that will allow multiple users to
order multiple items/ parts from what would effectively be an online store.
These users could be ordering several hundred items/ parts at a time, each
item/ part ordered representing one box or several hundred.
Each part record will require the "total stock" to be...
|
by: toedipper |
last post by:
Hello,
PHP4 and MySql
I have the code below, a mixture of handcoded and Dreamweaver genaratd
php code. Basically it's an update record form - I load the values from
a db and bind text boxes etc. This works ok. But I also have an update
action - if a user changes any of the text box values then he can click
update and the code should...
|
by: James P. |
last post by:
Hello there,
I have a bound-form using Navigator so that the user can move back and
forth to update record in the form. Every time a record was modified
and the user clicks the Navigator to either move backward or forward
to the next record, a message is popped up asking the user to confirm
the change. If the user clicks "Yes", the record...
|
by: Tinius |
last post by:
I am trying to update a field of type IMAGE.
I am able to do this by deleting the record and then INSERTing a new record
as shown below in the commented section.
But I really want to do this with an UPDATE command as shown below in the
un-commented code. I assume this is possible.
The image is passed as a byte array called 'content'. I...
| |
by: Daniel |
last post by:
Does someone know how to update record in ASP.NET ?
Because i face a problem after updating the record in SQLServer database.
The problem is :
I do update to a record's field called DateIn.
After updating the whole DateIn column field will also same value as the updated value ?
Does any one know why ??
Your help will be appreciated.
...
|
by: Agnes |
last post by:
Binding Manager (update problem) by agnescheng
I use binding Manager to bind the textbox, I got a problem on update record.
E.g Me.txtUserId.Text = "PETER"
bm.current.item("userid") = Me.txtUserId.Text.
if ds.haschanges() then
....................
.....acceptchanges()
messagebox.show("Save is completed")
end if................
I found...
|
by: Kosal |
last post by:
Dear Sir/Madam
I would like to Update record to last record in database that unkown last record
please advice.
thanks
Best Regard
|
by: dreamy |
last post by:
i have 2 tables,
1. account
-id,
-accounttypeid,
-name
2. accounttype
-accounttypeid,
-type.
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
| |
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...
| | |