Access VBA: If value run two queries, if not run one - sql

I have and insert and update query.
I want to create a button that runs either the insert query or both the update and insert query.
On the form:
if cbx = values x, y or z, run insert and update.
if cbx does not = values x, y or z run only insert.
So far I have:
IF (Cbx=X OR Cbx =Y or cbx =Z) Then
Currentdb.execute("updateQuery")
Currentdb.execute("inserQuery")
ELSEIF (Cbx<>X OR Cbx <>Y or cbx <>Z) THEN
CurrentDB.execute("insertQuery")
ElSE
end if
When I run it the table get stuck in what seem like a continuous write/edit loop.
SQL
UPDATE
tbsurveypersonnel
SET tbsurveypersonnel.removedDate = DATE()
WHERE
(
(
(
tbsurveypersonnel.[sr]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![sr]
)
AND
(
(
tbsurveypersonnel.[role]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![role]
)
)
;
INSERT INTO tbsurveypersonnel
(
sr
, lfname
, role
, aDate
)
VALUES
(
(
(
tbsurveypersonnel.[sr]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![sr]
)
, ((tbsurveypersonnel.[lfname])=[Forms]![fatbSurveyPersonnelSetRoles]![lfname])
)
,
(
(
tbsurveypersonnel.[role]
)
=[Forms]![fatbSurveyPersonnelSetRoles]![role]
)
), DATE()
final
Private Sub AssignRole_Click()
Dim strSql As String
Dim strlSQL2 As String
strSql = "UPDATE tbsurveypersonnel SET tbsurveypersonnel.removedDate = Now() " & vbCrLf & _
"WHERE removedDate is Null and (((tbsurveypersonnel.[sr])=[Forms]![fatbSurveyPersonnelSetRoles]![sr]) AND ((tbsurveypersonnel.[role])=[Forms]![fatbSurveyPersonnelSetRoles]![role]));"
strSQL2 = "INSERT INTO tbsurveypersonnel ( sr, lfname, role, assigndate ) " & vbCrLf & _
"SELECT [forms].[fatbSurveyPersonnelSetRoles].[sr] AS Expr1, [forms].[fatbSurveyPersonnelSetRoles].[lfName] AS Expr2, [forms].[fatbSurveyPersonnelSetRoles].[role] AS Expr3, Now() AS Expr4;"
If (Me.role = 1 Or Me.role = 2 Or Me.role = 3) Then
DoCmd.RunSQL strSql
DoCmd.RunSQL strSQL2
Else
DoCmd.RunSQL strSQL2
End If
DoCmd.RunCommand acCmdSaveRecord
DoCmd.Requery
End Sub

Answers the original question:
if cbx = values x, y or z, run insert and update.
So you want this:
IF (Cbx=X OR Cbx=Y OR cbx=Z) Then
Currentdb.execute("updateQuery")
Currentdb.execute("inserQuery")
ELSE
CurrentDB.execute("insertQuery")
end if

Avoid multiple calls toCurrentDbas everytime you create a copy (Instance, not Reference!) of the Database (DbEngine(0)(0) usually), what is usually not wanted and can raise errors.
Better store the instance in a variable or expand its scope.
With CurrentDb
If (Cbx=X Or Cbx=Y Or Cbx=Z) Then
.Execute("updateQuery", dbFailOnError)
End If
.Execute("insertQuery", dbFailOnError)
End With
AsinsertQueryis always executed, it is sufficent to just check ifupdateQueryneeds to be executed.

You don't need to ask the same question again.
If 'this criteria is met
Then
'Do some code
Else
'Do something else
End If
So in practice:
IF (Cbx<>X OR Cbx <>Y or cbx <>Z) Then
Currentdb.execute("updateQuery")
Currentdb.execute("inserQuery")
ELSE
CurrentDB.execute("insertQuery")
END IF

Related

MS Access VBA multiple list box search form

I have a requirement to allow a user to search between two dates on a form and filter the data down further using multiple list boxes
Currently I allow the user to search between a from and to date... And also filter by products from a listbox.
If no products are selected in the list box, only display the results of the query between the two dates.
If the selection critera of the listbox is not empty, build the query WHERE with IN clause and then concanenate it to the SELECT statement, then execute the query to give desired results.
My question is... How would I do this for another four or five multi value list boxes? For example: Suppliers, Depots, Countries, Varieties etc etc
SearchAllReject is simply a function to query from and to date with no product filters.
Here is the code I already have:
Dim SQLAllReject As String
Dim strDateFrom As String
Dim strDateTo As String
Dim strFirstDate As Date
Dim strSecondDate As Date
Dim strINPRODUCT As String
Dim strWHERE As String
Dim strSTRING As String
Dim i As Integer
If Len(Me.txtDate.Value & vbNullString) = 0 Then
MsgBox ("Please input date from")
Exit Sub
ElseIf Len(Me.txtDateTo.Value & vbNullString) = 0 Then
MsgBox ("Please input date to")
Exit Sub
End If
strDateFrom = txtDate.Value
strDateTo = txtDateTo.Value
strFirstDate = Format(CDate(strDateFrom), "mm/dd/yyyy")
strSecondDate = Format(CDate(strDateTo), "mm/dd/yyyy")
For i = 0 To lstProduct.ListCount - 1
If lstProduct.Selected(i) Then
strINPRODUCT = strINPRODUCT & "'" & lstProduct.Column(1, i) & "',"
End If
Next i
If Len(strINPRODUCT & vbNullString) = 0 Then
SearchAllReject
Else
strWHEREPRODUCT = "AND dbo_busobj_file_rejections_load_temp5.Tesco_Product_Name IN " & _
"(" & Left(strINPRODUCT, Len(strINPRODUCT) - 1) & "))"
SQLAllReject = "SELECT dbo_busobj_file_rejections_load_temp5.Reject_Date AS [Date], " & _
"dbo_busobj_file_rejections_load_temp5.Depot_Number AS [Depot No], " & _
"dbo_busobj_file_rejections_load_temp5.Depot_Name AS [Depot], dbo_busobj_file_rejections_load_temp5.Tesco_Product_Name AS [Product]," & _
"dbo_busobj_file_rejections_load_temp5.Tesco_Brand_Name AS [Brand], dbo_busobj_file_rejections_load_temp5.Tesco_Packsize AS [Packsize], " & _
"dbo_busobj_file_rejections_load_temp5.TPNB, dbo_busobj_file_rejections_load_temp5.EAN, " & _
"dbo_busobj_file_rejections_load_temp5.Tesco_Country_of_Origin AS [Country], " & _
"dbo_busobj_file_rejections_load_temp5.Tesco_Variety AS [Variety], dbo_busobj_file_rejections_load_temp5.Tesco_Producer AS [Producer], " & _
"dbo_busobj_file_rejections_load_temp5.reject_qty AS [Quantity], dbo_busobj_file_rejections_load_temp5.batch_code AS [Batch Code], " & _
"dbo_busobj_file_rejections_load_temp5.site AS [Site], dbo_busobj_file_rejections_load_temp5.Tesco_Comment AS [Comment], " & _
"dbo_busobj_file_rejections_load_temp5.Tesco_Reason AS [Reason] " & _
"FROM dbo_busobj_file_rejections_load_temp5 " & _
"WHERE (((dbo_busobj_file_rejections_load_temp5.Reject_Date) Between #" & strFirstDate & "# And #" & strSecondDate & "#) "
strSTRING = SQLAllReject & strWHEREPRODUCT
Debug.Print strSTRING
Me.lstDeleteReject.RowSource = strSTRING
Me.lstDeleteReject.Requery
Consider building an entity-attribute table of all possible listbox values and use a saved SQL query which avoids any messy concatenation of SQL in VBA. A parameterized query using QueryDef is used to update the selected options of table of all list box values.
Table (myListBoxValues) (built once and updated with new values/categories)
Category|Value |Selected
--------|----------|--------
Product |Product A | 1
Product |Product B | 1
Product |Product C | 1
...
Country |USA | 1
Country |Canada | 1
Country |Japan | 1
Above can be populated with multiple append queries using SELECT DISTINCT:
INSERT INTO myListBoxValues ([Category], [Value], [Selected])
SELECT DISTINCT 'Product', Tesco_Product_Name, 1
FROM dbo_busobj_file_rejections_load_temp5 b
NOTE: It is very important to default all Selected to 1 for VBA purposes. See further below. Also, if you have a mix of number and string, consider using TextValue and NumberValue columns and adjust in SQL IN clauses. Save above query as a new object and place the named object behind target: lstDeleteReject.
SQL (built once, adjust form name)
Notice the form date values are directly incorporated into WHERE clause without any date formatting conversion or concatenation needs. Also, table alias is used to avoid long name repetition.
SELECT b.Reject_Date AS [Date],
b.Depot_Number AS [Depot No],
b.Depot_Name AS [Depot], b.Tesco_Product_Name AS [Product],
b.Tesco_Brand_Name AS [Brand], b.Tesco_Packsize AS [Packsize],
b.TPNB, b.EAN,
b.Tesco_Country_of_Origin AS [Country],
b.Tesco_Variety AS [Variety], b.Tesco_Producer AS [Producer],
b.reject_qty AS [Quantity], b.batch_code AS [Batch Code],
b.site AS [Site], b.Tesco_Comment AS [Comment],
b.Tesco_Reason AS [Reason]
FROM dbo_busobj_file_rejections_load_temp5 AS b
WHERE b.Reject_Date BETWEEN Forms!myFormName!txtDate
AND Forms!myFormName!txtDateTo
AND b.Tesco_Product_Name IN (
SELECT [Value] FROM myListBoxValues
WHERE [Category] = 'Product' AND [Selected] = 1
)
AND b.site IN (
SELECT [Value] FROM myListBoxValues
WHERE [Category] = 'Site' AND [Selected] = 1
)
AND b.Tesco_Producer IN (
SELECT [Value] FROM myListBoxValues
WHERE [Category] = 'Producer' AND [Selected] = 1
)
AND b.Depot_Name IN (
SELECT [Value] FROM myListBoxValues
WHERE [Category] = 'Depot' AND [Selected] = 1
)
AND b.Tesco_Country_of_Origin IN (
SELECT [Value] FROM myListBoxValues
WHERE [Category] = 'Country' AND [Selected] = 1
)
VBA (adjust list box names to actuals)
Dim qdef As QueryDef
Dim lstname As Variant
Dim sql As String
Dim i As Integer
sql = "PARAMETERS paramValue TEXT, paramCateg INTEGER; " _
& "UPDATE myListBoxes SET [Selected] = 0 " _
& "WHERE [Value] = paramValue AND [Category] = paramCateg"
Set qdef = CurrentDb.CreateQueryDef("", sql)
' ITERATE THROUGH ALL LISTBOXES BY NAME
For Each lstname in Array("lstProduct", "lstSite", "lstProducer", "lstDepot", "lstCountry")
For i = 0 To Me.Controls(lstname).ListCount - 1
' UPDATE IF AT LEAST ONE ITEM IS SELECTED
If Me.Controls(lstname).ItemsSelected.Count > 0
' UPDATE [SELECTED] COLUMN TO ZERO IF VALUES ARE NOT SELECTED
If Me.Controls(lstname).Selected(i) = False Then
qdef!paramValue = Me.Controls(lstname).Value
qdef!paramCategory = Replace(lstName, "lst", "")
qdef.Execute
End If
End If
Next i
Next lstname
Set qdef = Nothing
' REQUERY LISTBOX
Me.lstDeleteReject.Requery
' RESET ALL SELECTED BACK TO 1
CurrentDb.Execute "UPDATE myListBoxValues SET [Selected] = 1"
As you can see, much better readability and maintainability. Also, if users do not select any option, the date range filters are still applied and using your universal table of all list box values, all values will be selected to returns all non-NULL values.

Dynamic Calculated Field in VBA Access

I'm trying to add a field into an existing table. The field is calculated using two variables 'myPrice', which is the price of a record at a certain date, and 'previousPrice', which is the price of the same part from the first record, only a from the month previous. I'm using a loop to iterate through the entire recordset of prices, thereby altering the two variables each time. My code is as follows:
Function priceDifference()
Dim currentPrice As Currency
Dim previousPrice As Currency
Dim recordDate As Date
Dim previousDate As Date
Dim dbsASSP As DAO.Database
Dim priceTable As DAO.TableDef
Dim diffFld As DAO.Field2
Dim rstCurrentPrice As DAO.Recordset
Dim rstPreviousPrice As DAO.Recordset
Dim PN As String
Set dbsASSP = CurrentDb
strSQL = "SELECT * FROM qryPrice"
Set rstCurrentPrice = dbsASSP.OpenRecordset(strSQL, dbOpenDynaset)
Set priceTable = dbsASSP.TableDefs("tblPrice")
Set diffFld = priceTable.CreateField("Difference", dbCurrency)
If Not (rstCurrentPrice.EOF) Then
rstCurrentPrice.MoveFirst
Do Until rstCurrentPrice.EOF = True
PN = rstCurrentPrice![P/N]
recordDate = rstCurrentPrice![myDate]
previousDate = Format(DateAdd("m", -1, recordDate), "M 1 YYYY")
myPrice = rstCurrentPrice!Price
strPreviousSQL = "SELECT * FROM qryPrice WHERE [MyDate] = #" & previousDate & "# AND [Type] = 'Net Price' AND [P/N] = " & PN & ""
Set rstPreviousPrice = dbsASSP.OpenRecordset(strPreviousSQL, dbOpenDynaset)
myCodeName = rstCurrentPrice!CodeName
If DCount("[P/N]", "qryPrice", "[MyDate] = #" & previousDate & "# And [P/N] = " & PN) <> 0 Then
previousPrice = rstPreviousPrice!Price
Else
previousPrice = myPrice
End If
rstCurrentPrice.MoveNext
Loop
Else
MsgBox "Finished looping through records."
End If
diffFld.Expression = myPrice - previousPrice
rstCurrentPrice.Close
rstPreviousPrice.Close
priceTable.Fields.Append diffFld
End Function
Syntactically, it works. The calculated field, however, does not give me the correct values and I cannot figure out why, although I imagine it has something to do with the dynamic formula.
Any help is appreciated. Thanks!!
Your code can't work as you append a number to the field instead of a formula, but you should avoid calculated fields
Use a query:
SELECT
nPrice.[P/N],
nPrice.Price,
nPrice.MyDate,
oPrice.MyDate,
nPrice.Price-Nz(oPrice.Price,nPrice.Price) AS diff
FROM (
SELECT
[P/N],
Price,
MyDate,
Format(DateAdd("m",-1,MyDate),"yyyymm") as previousMonthYear
FROM
tblPrice) AS nPrice
LEFT JOIN (
SELECT
[P/N],
Price,
MyDate,
Format(MyDate,"yyyymm") AS monthYear
FROM
tblPrice) AS oPrice
ON
nPrice.[P/N] = oPrice.[P/N]
AND nPrice.previousMonthYear = oPrice.monthYear
This calculates the difference dynamic and you don't need to store it.
I assume there is max one price per month, otherwise you need to filter the subqueries or just calculate the difference to the last price before.
If the query is too slow ([P/N] and MyDate need an index) , you can still use it to update a field the table tblPrice, but this has to be updated every time a price is updated or inserted in tblPrice
I think you can avoid your code loop by using this query
SELECT A.qryPrice, A.MyDate, B.qryPrice, B.MyDate
FROM qryPrice A LEFT OUTER JOIN qryPrice B
ON A.[P/N] = B.[P/N]
AND B.MyDate = DATEADD(month, -1, A.MyDate)

Merge query from datagridview to database not executing sql, vb.net

I'm having a problem executing a merge query from to update or insert values from a DataGridView table into a sql server database table. Here is my code below, it doesn't give me any errors or stoppages, however I recently noticed that it has been creating completely rows in my database table dbo.schedule which contain all NULL values even that key location, could someone please help me? I'm not very familiar with merge queries in sql so please point out issues with my syntax:
Dim query As String = String.Empty
query &= "DECLARE #TaskID nvarchar(8), #Task nvarchar(50), #Start_date datetime, #Due_date datetime, #Complete bit, #Task_Manager nvarchar(8), #JRID nvarchar(10), #Entered_By char(50), #Time_Entered datetime;"
query &= "MERGE INTO schedule USING (VALUES (#TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered)) AS t(TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered) "
query &= "ON schedule.TaskID = #TaskID WHEN MATCHED THEN"
query &= " UPDATE SET schedule.TaskID = t.TaskID, schedule.Task=t.Task, schedule.start_date=t.start_date, schedule.due_date=t.due_date, schedule.complete=t.complete, schedule.task_manager=t.task_manager, "
query &= "schedule.JRID=t.JRID, schedule.Entered_by=t.Entered_by, schedule.Time_Entered=t.Time_Entered"
query &= " WHEN NOT MATCHED THEN INSERT (TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered)"
query &= " VALUES (#TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered);"
Using conn As New SqlConnection(dbLocations(0, 1))
Using comm As New SqlCommand()
With comm
For Each row As DataGridViewRow In MainSchedule.DataGridView1.Rows
If Not (row.Cells(0).Value = Nothing) Then
.Parameters.Clear()
.Connection = conn
.CommandType = CommandType.Text
.CommandText = query
insertcommand.Parameters.AddWithValue("#TaskID", TNn)
insertcommand.Parameters.AddWithValue("#Complete", "False")
insertcommand.Parameters.AddWithValue("#Task", row.Cells(0).Value)
insertcommand.Parameters.AddWithValue("#Start_date", row.Cells(1).Value)
insertcommand.Parameters.AddWithValue("#Due_Date", row.Cells(2).Value)
insertcommand.Parameters.AddWithValue("#JRID", txtJRID.Text)
insertcommand.Parameters.AddWithValue("#Task_Manager", row.Cells(3).Value)
insertcommand.Parameters.AddWithValue("#Entered_By", GetUserName())
insertcommand.Parameters.AddWithValue("#Time_Entered", Now)
NextTask()
End If
Next
End With
conn.Open()
comm.ExecuteNonQuery()
End Using
End Using
I figured it out in case anyone is wondering, here is my new code:
Connexion.Open()
Dim query As String = String.Empty
Dim keypos = 0
query &= "UPDATE schedule SET Task = #Task, Complete = #Complete, Start_date = #Start_date, "
query &= "Due_date = #Due_date, JRID = #JRID, Task_Manager = #Task_Manager, Entered_By = #Entered_By, Time_Entered = #Time_Entered "
query &= "WHERE TaskID = #TaskID "
query &= "IF ##ROWCOUNT = 0 INSERT INTO schedule ( TaskID, Task, start_date, Due_Date, Complete, Task_Manager, JRID, Entered_By, Time_Entered)"
query &= " VALUES ( #TaskID, #Task, #start_date, #Due_Date, #Complete, #Task_Manager, #JRID, #Entered_By, #Time_Entered);"
For Each row As DataGridViewRow In MainSchedule.DataGridView1.Rows
If Not (row.Cells(0).Value = Nothing) Then
insertcommand.Parameters.Clear()
insertcommand.CommandText = query
insertcommand.Parameters.AddWithValue("#TaskID", row.Cells(0).Value)
insertcommand.Parameters.AddWithValue("#Complete", "False")
insertcommand.Parameters.AddWithValue("#Task", row.Cells(1).Value)
insertcommand.Parameters.AddWithValue("#Start_date", row.Cells(2).Value)
insertcommand.Parameters.AddWithValue("#Due_Date", row.Cells(3).Value)
insertcommand.Parameters.AddWithValue("#JRID", txtJRID.Text)
insertcommand.Parameters.AddWithValue("#Task_Manager", row.Cells(4).Value)
insertcommand.Parameters.AddWithValue("#Entered_By", GetUserName())
insertcommand.Parameters.AddWithValue("#Time_Entered", Now)
insertcommand.ExecuteNonQuery()
End If
keypos = keypos + 1
Next
Connexion.Close()

how to use an in clause to check if a column is a certain string or not when referencing 3 tables

I have this SQL statement and it joining 2 tables...
SELECT TRIDENT.Maintenance.RCFAs.*, TRIDENT.Maintenance.Equipment.EquipmentName
FROM TRIDENT.Maintenance.RCFAs
LEFT JOIN TRIDENT.Maintenance.Equipment
ON TRIDENT.Maintenance.Equipment.EquipmentId = TRIDENT.Maintenance.RCFAs.EquipmentId
WHERE 1 = 1
Now I have to reference a third table because I have a dropdown by the name of components that we will use to lookup stuff on the table named TRIDENT.Maintenance.RCFAXrefComponents. So if "bolts" is selected from the dropdown it will look up the YEAR and RCFAID which makes a unqiue key for both RCFAXrefComponents and RCFAs and checks if there are any rows in RCFAs that had "bolts" in the component column when looking up that YEAR and RCFAId. A coworker suggested I use an IN clause to check if the YEAR and RCFAId is in that RCFAXrefComponents. He said it might be tricky, but I'm a little lost on how to do this.
Below is the RCFAs table that I want to grab the YEAR and RCFAId values together and lookup on the other to see if that bolt is also there. Then it should bring up the line item on RCFAs table to output to user
this is RCFAXrefComponents table below
Public Shared Function GetRCFAList(rcfaNumber As Integer?, description As String,
failureType As String, equipmentDescription As String, componentSelection As String) As List(Of RCFA)
Dim sql = "SELECT r.*, e.EquipmentName FROM TRIDENT.Maintenance.RCFAs AS r LEFT JOIN TRIDENT.Maintenance.Equipment AS e ON e.EquipmentId = r.EquipmentId JOIN TRIDENT. Maintenance.RCFAXrefComponents AS c ON c.Year = r.Year AND c.RCFAId = r.RCFAId WHERE"
If failureType <> "" Then
sql += " AND RCFAs.FailureType = '" & failureType.ToUpper & "'"
End If
If description <> "" Then
sql += " AND RCFAs.ShortDesc LIKE '%" & description.ToUpper & "%'"
End If
If equipmentDescription <> "" Then
sql += " AND Equipment.EquipmentName LIKE '%" & equipmentDescription.ToUpper & "%'"
End If
If componentSelection <> "" Then
sql += " c.ComponentId = '%" & componentSelection.ToUpper & "%'"
End If
Dim dbConn As New Trident.Core.DBConnection
Dim ds = dbConn.FillDataSet(sql)
Dim tmpList As New List(Of RCFA)
For Each dr As DataRow In ds.Tables(0).Rows
tmpList.Add(New RCFA(New Trident.Objects.Maintenance.RCFA.RCFA(dr)))
Next
Return tmpList
End Function
Just use a simple JOIN with the RFCAXrefComponents table, and a WHERE clause that filters the component ID.
SELECT r.*, e.EquipmentName
FROM TRIDENT.Maintenance.RCFAs AS r
LEFT JOIN TRIDENT.Maintenance.Equipment AS e
ON e.EquipmentId = r.EquipmentId
JOIN TRIDENT.Maintenance.RCFAXrefComponents AS c
ON c.Year = r.Year
AND c.RCFAId = r.RCFAId
WHERE c.ComponentID = 'BOLTS'
I may be confused but it sounds like you need to use EXISTS.
SELECT r.*,
e.EquipmentName
FROM TRIDENT.Maintenance.RCFAs r
LEFT JOIN TRIDENT.Maintenance.Equipment e ON e.EquipmentId = r.EquipmentId
WHERE EXISTS ( SELECT 1
FROM TRIDENT.Maintenance.RCFAXrefComponents c
WHERE c.Year = r.Year
AND c.RCFAId = r.RCFAId
AND c.ComponentId LIKE '%BOLTS%' )
you may not need the c.ComponentId LIKE '%BOLTS%' you might just want c.ComponentId = 'BOLTS'

How to determine if sql INSERTED or UPDATED?

Say I have a function like this:
Private Function addNicheMerge(ByVal tyNicheMergePOLE As typeNicheMergePOLE) As Integer Implements IGenie.addNicheMerge
Dim objParameterValues As New clsParameterValues
Dim objCon As DbConnection
Dim paramValues() As DbParameter
Dim iConnectionBLL As DataAccessLayer.Connection.iConnectionBLL
iConnectionBLL = New clsConnectionBLL()
Dim intCount As Integer
Try
tyAcornCollision = New typeAcornCollision
objParameterValues = New clsParameterValues
objCon = iConnectionBLL.getDatabaseTypeByDescription("GENIE2")
Using objCon
Dim strSQL As String
strSQL = "If NOT Exists (SELECT * FROM dbNicheMergeLog WHERE MasterID=#MasterID AND ChildID = #ChildID) "
strSQL = strSQL & "INSERT INTO dbNicheMergeLog (MasterID, ChildID, DateAdded, GenieUpdated, done, CheckedByUser, MergeTypeID, Usercode, LastUpdated) VALUES (#MasterID, #ChildID, getDate(), 0, 0, #CheckedByUser, #MergeTypeID, '', " & _ "GetDate()) Else Update dbNicheMergeLog SET LastUpdated = getdate() WHERE MasterID=#MasterID AND ChildID = #ChildID"
objParameterValues.AssignParameterValues("#MasterID", tyNicheMergePOLE.MasterID, 1)
objParameterValues.AssignParameterValues("#ChildID", tyNicheMergePOLE.ChildID, 1)
objParameterValues.AssignParameterValues("#MergeTypeID", tyNicheMergePOLE.MergeTypeID, 1)
objParameterValues.AssignParameterValues("#CheckedByUser", 0, 1)
paramValues = objParameterValues.getParameterValues
intCount = clsDatabaseHelper.ExecuteNonQuery(objCon, CommandType.Text, strSQL, paramValues)
Return intCount
End Using
Catch ex As Exception
Return -2
Finally
' If objCon.State = ConnectionState.Open Then
' objCon.Close()
' End If
objCon = Nothing
End Try
End Function
Is there a way to determine whether an insertion or update took place?
if you are using sql server, you could use an output clause to determine if an update happened
Update dbNicheMergeLog SET LastUpdated =
getdate() WHERE MasterID=#MasterID AND
ChildID = #ChildID
OUTPUT count(*)
Then in vb use
dim updateCount as int = Convert.ToInt32(clsDatabaseHelper.ExecuteScalar())
Try this SQL:
WITH new (
MasterID
,ChildID
,DateAdded
,GenieUpdated
,done
,CheckedByUser
,MergeTypeID
,Usercode
,LastUpdated
)
AS(
SELECT
#MasterID
,#ChildID
,getDate()
,0
,0
,#CheckedByUser
,#MergeTypeID
,''
,getdate()
)
MERGE INTO dbNicheMergeLog t
USING new
ON t.MasterID = new.MasterID
AND t.ChildID = new.ChildID
WHEN NOT MATCHED BY TARGET THEN
INSERT (
MasterID
,ChildID
,DateAdded
,GenieUpdated
,done
,CheckedByUser
,MergeTypeID
,Usercode
,LastUpdated
)
VALUES (
new.MasterID
,new.ChildID
,new.DateAdded
,new.GenieUpdated
,new.done
,new.CheckedByUser
,new.MergeTypeID
,new.Usercode
,new.LastUpdated
)
OUTPUT $action as Action
;
You can use
Output deleted.*
in your update query to get the results that were lost on update, something like this:
Create Table #abctest(
Id int identity,Name varchar(200))
Insert into #abctest(Name)
Values('abcd'),('bcde'),('cdef'),('defg'),('efgh'),('fghi')
Update #abctest Set Name='xyz' OUTPUT Deleted.* Where Id=2
The above query will give you an output
Id Name
2 bcde