SSIS Update Table Values from Another Table - sql-server

I want to update TableA with values from TableB on a nightly basis. Right now, I'm trying to do this with SSIS 2005 using a Script Task with the SQL in it. Each time I try to do the update in this manner, I get a time-out error.
Is there a better way to do this in SSIS?
Current information below:
Public Sub Main()
Const Component_Name As String = "Updating TableA Data"
Const Conn_String As String = "Data Source=DB_A;Initial Catalog=TableA;Integrated Security=SSPI;"
Const sql_Emp As String = "Update TableA Set Contract = c.License_No, SEIN = convert(varchar, c.Lic_Exp_Date, 101) " _
& "From Server.DB_B.dbo.TableB c Inner Join TableA b on " _
& "rtrim(ltrim(c.business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14)))) " _
& "Where c.Lic_Exp_Date = (select Max(Lic_Exp_Date) From Server.DB_B.dbo.TableB " _
& "Where rtrim(ltrim(business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))) " _
& "and convert(varchar, c.Lic_Exp_Date, 101) <> convert(varchar, b.SEIN, 101)"
Dim con As SqlConnection = New SqlConnection(Conn_String)
Try
Dts.Log("Opening DB Connection: " & con.ConnectionString, 0, Nothing)
con.Open()
Dim duh As New SqlCommand(sql_Emp, con)
duh.ExecuteNonQuery()
con.Close()
Dts.Log(String.Format(Component_Name), 0, Nothing)
Dts.Events.FireInformation(0, Component_Name, String.Format("TableA Data Updating"), "", 0, True)
Dts.TaskResult = Dts.Results.Success
Catch ex As Exception
Dts.Events.FireError(0, Component_Name, ex.Message, "", 0)
Dts.Log("Exception detected: " & ex.ToString, 0, Nothing)
Dts.TaskResult = Results.Failure
End Try
End Sub

Let's start by cleaning that up a little:
Public Sub Main()
Const Component_Name As String = "Updating TableA Data"
Const Conn_String As String = "Data Source=DB_A;Initial Catalog=TableA;Integrated Security=SSPI;"
Const sql_Emp As String = _
"UPDATE TableA" _
+ " SET Contract = c.License_No, SEIN = convert(varchar, c.Lic_Exp_Date, 101)" _
+ " FROM Server.DB_B.dbo.TableB c" _
+ " INNER JOIN TableA b" _
+ " ON rtrim(ltrim(c.business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))" _
+ " WHERE c.Lic_Exp_Date= (" _
+ " SELECT MAX(Lic_Exp_Date)" _
+ " FROM Server.DB_B.dbo.TableB" _
+ " WHERE rtrim(ltrim(business_lic)) = rtrim(ltrim(cast(b.Account_Key as varchar(14))))" _
+ ") AND convert(varchar, c.Lic_Exp_Date, 101) <> convert(varchar, b.SEIN, 101)"
Try
Using con As New SqlConnection(Conn_String), _
cmds New SqlCommand(sql_Emp, con)
Dts.Log("Opening DB Connection: " & con.ConnectionString, 0, Nothing)
con.Open()
cmd.ExecuteNonQuery()
Dts.Log(String.Format(Component_Name), 0, Nothing)
Dts.Events.FireInformation(0, Component_Name, String.Format("TableA Data Updating"), "", 0, True)
Dts.TaskResult = Dts.Results.Success
End Using
Catch ex As Exception
Dts.Events.FireError(0, Component_Name, ex.Message, "", 0)
Dts.Log("Exception detected: " & ex.ToString, 0, Nothing)
Dts.TaskResult = Results.Failure
End Try
End Sub
Okay, now that I can read it I can start looking at what might be broken. Check back in a few minutes for edits.
Okay, now let's look at that query. I'm missing some data type information, so I'm going to make some assumptions. Please correct any that are wrong:
b.Account_Key is some number type, probably int. Otherwise you wouldn't need to convert to varchar
The Lic_Exp_Date columns really are of type datetime
If those are correct, I think this will do what you want, but do it a lot faster:
UPDATE TableA
SET Contract = c1.License_No, SEIN = DATEADD(dd,0, DATEDIFF(dd,0, c1.Lic_Exp_Date))
FROM TableA b
INNER JOIN Server.DB_B.dbo.TableB c1
ON ISNUMERIC(c1.busines_lic) = 1 AND cast(c1.business_lic AS int) = b.Account_Key
INNER JOIN
(
SELECT business_lic, MAX(Lic_Exp_Date) AS Lic_Exp_Date
FROM Server.DB_B.dbo.TableB
GROUP BY business_lic, License_No
) c2 ON c2.business_lic = c1.business_lic AND c1.Lic_Exp_Date=c2.Lic_Exp_Date
WHERE DATEADD(dd,0, DATEDIFF(dd,0, c1.Lic_Exp_Date)) <> DATEADD(dd,0, DATEDIFF(dd,0, b.SEIN))
Here's what changed:
Turn the correlated subquery into a join. A join will be much faster, however the query optimizer might have been doing this for you already
Eliminate the need to call a number of per-row functions - should also help you match up with indexes better.
Use an integer comparison rather than string for your main join
Use date functions rather than convert to strings to remove the time portion, which should be much faster and in turn allow me to:
Use date comparisons rather than string comparisons in your join

The better way would be an Execute SQL task.

Related

Values are missing only when select records in Excel VBA script

*edit
I didn't find any solution so I separate the sql queries and it works(ugly but works) if anyone have a good solution i'd like to see
.....................................................................................................................................................
When I select records in SQL Server Management Studio I get some values that when I select with the same query in Excel VBA script I don't get some of them
Sub GetData()
Dim conn As New Connection, rec As New Recordset
Dim comm As New Command
Set comm.ActiveConnection = conn
conNum = "123"
comm.CommandText = _
"SELECT A.xyz, A.style, A.color, " & _
"B.vessel_name, B.location, B.importnum_id, A.warehouse, " & _
"A.qty1, A.qty2, A.qty " & _
"FROM Wf20.dbo.A A, Wf20.dbo.B B " & _
"WHERE '" & conNum & "' = A.xyz AND " & _
"B.fileno = A.fileno AND " & _
"A.importnum_id = B.importnum_id"
Debug.Print comm.CommandText
rec.Open comm
Do While Not rec.EOF
If rec("qty") > 0 Then
SomeFunc rec
End If
rec.MoveNext
Loop
End Sub
Sub SomeFunc(recS As Recordset)
rec("style") ' same as sql manager
rec("color") ' same as sql manager
rec("qty") ' same as sql manager
rec("qty1") ' same as sql manager
rec("importnum_id") ' empty just here
rec("warehouse") ' empty just here
End Sub
Does anyone have any idea why can it happen?
*after debug I found that without the If qty > 0 there was more values not empty (there is only one record in the db in my case and the qty is bigger than 0) now I'm really confused

Pass date range in rdlc report vb.net

Need help
I am using sql server 2016, visual studio 2017
In my report i am unable to pass date range, when report is loading its showing all records from beginning to till date, where am mistake pls help!!
Below code is am made in 1 function and calling on button click
Dim strSQL As String = "", strSQLID As String = "", strSQLOrderBy As String = ""
Dim query As String = " select o.InvoiceDate,o.RegistrationNo,o.PatientName,o.TransactionStatus,o.gender,o.company,o.Visittype,o.Doctor,o.Specialisation,"
query &= " o.departmentName,o.Address,o.CityName,o.StateName,o.MobileNo,o.ServiceName"
query &= " from DRT_VW_OPVISIT o "
query &= " inner join employee e on o.DoctorId=e.ID "
'query &= " where e.ID in ('') "
query &= " where convert(varchar,o.InvoiceDate,111) between '" + DateTimePicker1.Text + " ' and '" + DateTimePicker2.Text + "' "
query &= " and o.TransactionStatus='Active' "
'query &= " order by InvoiceDate desc "
If Trim(strID) <> "" Then strSQLID = strSQLID & " And e.ID In (" + strID + ")"
strSQLOrderBy = " order by o.InvoiceDate desc "
conn = GetConnect()
conn.Open()
query = query & strSQLID & strSQLOrderBy
Dim cmd As SqlCommand = New SqlCommand(query, conn)
MsgBox(query)
cmd.Parameters.AddWithValue("DateTimePicker1", Me.DateTimePicker1.Value)
cmd.Parameters.AddWithValue("DateTimePicker2", Me.DateTimePicker2.Value)
Dim sda1 As SqlDataAdapter = New SqlDataAdapter(cmd)
Dim ds1 As New DataSet1
Dim dt2 As DataTable = New DataTable()
sda1.Fill(dt2)
With RepDoctorWiseVisit.ReportViewer1.LocalReport
.ReportPath = "D:\VB Project 2021\RepDepartmentWisePrice\RepDepartmentWisePrice\Report3.rdlc"
.DataSources.Clear()
.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", dt2))
End With
RepDoctorWiseVisit.Show()
RepDoctorWiseVisit.ReportViewer1.RefreshReport()
Return dt2
```
You've got a number of different things in your sample code that will cause you some issue. You need to do some reading on using Sql Parameters in your TSQL commands. As pointed out by Larnu, security is an issue but the real benefit to you as a developer is it is a million times easier to debug.
I've also made an assumption here DRT_VW_OPVISIT.InvoiceDate is a DateTime column in your DB.
Anyway, try this for a start
Also, just a note. If it is a Date Time, you will in all likelihood need to adjust for the time component
Dim strSQL As String = "", strSQLID As String = "", strSQLOrderBy As String = ""
Dim query As String = " select o.InvoiceDate,o.RegistrationNo,o.PatientName,o.TransactionStatus,o.gender,o.company,o.Visittype,o.Doctor,o.Specialisation,"
query &= " o.departmentName,o.Address,o.CityName,o.StateName,o.MobileNo,o.ServiceName"
query &= " from DRT_VW_OPVISIT o "
query &= " inner join employee e on o.DoctorId=e.ID "
query &= " where o.InvoiceDate between #DateTimePicker1 and #DateTimePicker2 "
query &= " and o.TransactionStatus='Active' "
If Trim(strID) <> "" Then strSQLID = strSQLID & " And e.ID In (" + strID + ")"
strSQLOrderBy = " order by o.InvoiceDate desc "
conn = GetConnect()
conn.Open()
query = query & strSQLID & strSQLOrderBy
Dim cmd As SqlCommand = New SqlCommand(query, conn)
MsgBox(query)
cmd.Parameters.Add("#DateTimePicker1", SqlDbType.DateTime).Value = Me.DateTimePicker1.Value
cmd.Parameters.Add("#DateTimePicker2", SqlDbType.DateTime).Value = Me.DateTimePicker2.Value
Dim sda1 As SqlDataAdapter = New SqlDataAdapter(cmd)
Dim ds1 As New DataSet1
Dim dt2 As DataTable = New DataTable()
sda1.Fill(dt2)
With RepDoctorWiseVisit.ReportViewer1.LocalReport
.ReportPath = "D:\VB Project 2021\RepDepartmentWisePrice\RepDepartmentWisePrice\Report3.rdlc"
.DataSources.Clear()
.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", dt2))
End With
RepDoctorWiseVisit.Show()
RepDoctorWiseVisit.ReportViewer1.RefreshReport()
Return dt2
I Will also warn you, there are a number of other improvements you can make, things like wrapping your connection in a "Using" block will keep that clean. And don't get me started on the hard coded report path.
I'm not saying this is a complete answer, but hopefuly I've given you the info to go get what you need yourself

vb.net - using a CTE Query in VB.net?

I have a working SQL Query with a CTE and I need that query in my vb.net application, but the problem is I get an error that states:
"Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'"
and the code is like this:
Dim da As New OleDbDataAdapter
Dim ds As New DataSet
Dim dt As New DataTable
Dim sqlcmd As String = (";WITH q AS
(
SELECT a.*
FROM SampleData AS a
WHERE EXISTS (SELECT 1
FROM SampleData AS b
WHERE a.Name = b.Name
AND a.Account= b.Account
AND a.Amount = -b.Amount)
)
DELETE FROM q OUTPUT DELETED.* INTO SampleData2")
If connDB.State = ConnectionState.Closed Then
connDB.Open()
End If
Try
ds.Tables.Add(dt)
da = New OleDbDataAdapter(sqlcmd, connDB)
da.Fill(dt)
Any help on this? I can't find any solution to this.
Here is my function that works with a simple CTE, use this function to test your expression, just replace your CTE in it and see, you might need fix your query.
Public Sub RecursiveData()
Dim connectionString As String = "Initial Catalog=DBName;Data Source=ServerName;uid=user;password=mypassword;Connection Timeout=50000"
Dim cteQuery As String = ";WITH cte " & vbCrLf &
" AS(SELECT 1 AS n " & vbCrLf &
" UNION ALL " & vbCrLf &
" SELECT n + 1 " & vbCrLf &
" FROM cte " & vbCrLf &
" WHERE n <50 " & vbCrLf &
" ) " & vbCrLf &
" SELECT n " & vbCrLf &
" FROM cte where n <= 5; "
Using _con As New SqlConnection(connectionString)
Using _cmd As New SqlCommand(cteQuery, _con)
_con.Open()
Using rdr As SqlDataReader = _cmd.ExecuteReader()
While rdr.Read()
Console.WriteLine(rdr.GetValue(0).ToString())
End While
rdr.Close()
End Using
_con.Close()
End Using
End Using
End Sub

Error comparing datetime in SQL Server

I'm currently writing this program that the user will input the start date and end date. Then the program will retrieve the records from the database where the startdate in db will be >= user input start date and enddate in db will be <= user input end date.
Dim dateStr As DateTime = dtpStart.Value
Dim dateEnd As DateTime = dtpEnd.Value
MsgBox(dateStr)
con.ConnectionString = "Data Source=MKZSA065\SQLSERVER2008R2,1499;Initial Catalog=inv"
con.Open()
MsgBox("server connected")
cmd.Connection = con
'cmd.CommandText = "Select column_name as 'Columnname', data_type as'Datatype' from information_schema.columns where table_name = 'inv.dbo.InOutTransaction' AND column_name = 'inv.dbo.InOutTransaction.startDate'"
'cmd.CommandText = "Select inv.dbo.InOutTransaction.refNo, inv.dbo.Case_Status.deployedBy, CONVERT(varchar(10), inv.dbo.InOutTransaction.startDate, 120) as startDate, CONVERT(varchar(10), inv.dbo.InOutTransaction.endDate, 120) as endDate, inv.dbo.InOutTransaction.item FROM inv.dbo.InOutTransaction inner join inv.dbo.Case_Status ON inv.dbo.InOutTransaction.refNo = inv.dbo.Case_Status.refNo WHERE inv.dbo.InOutTransaction.refNo LIKE 'L%' AND inv.dbo.InOutTransaction.status LIKE 'Out'"
cmd.CommandText = "Select inv.dbo.InOutTransaction.refNo, inv.dbo.Case_Status.deployedBy, CONVERT(varchar(10),inv.dbo.InOutTransaction.startDate,120) as startDate, CONVERT(varchar(10),inv.dbo.InOutTransaction.endDate,120) as endDate, inv.dbo.InOutTransaction.item from inv.dbo.InOutTransaction inner join inv.dbo.Case_Status ON inv.dbo.InOutTransaction.refNo = inv.dbo.Case_Status.refNo WHERE inv.dbo.InOutTransaction.refNo LIKE 'L%' AND inv.dbo.InOutTransaction.status LIKE '%Out%' AND inv.dbo.InOutTransaction.startDate >= '" & dateStr & "' AND inv.dbo.InOutTransaction.endDate <= '" & dateEnd & "'"
Dim lrd As SqlDataReader
Dim li As ListViewItem
lrd = cmd.ExecuteReader()
Dim num As Integer = 1
While lrd.Read()
ListView1.BeginUpdate()
li = ListView1.Items.Add(num.ToString)
li.SubItems.Add(lrd("refNo").ToString)
li.SubItems.Add(lrd("deployedBy").ToString)
li.SubItems.Add(lrd("startDate").ToString)
li.SubItems.Add(lrd("endDate").ToString)
li.SubItems.Add(lrd("item").ToString)
'li.SubItems.Add(lrd("column_name").ToString)
'li.SubItems.Add(lrd("data_type").ToString)
num += 1
ListView1.EndUpdate()
ListView1.EnsureVisible(ListView1.Items.Count - 1)
End While
There was an error
Conversion failed when converting datetime from character string
How and what should I do :(
USE PARAMETERISED QUERIES
Sorry to yell, but I cannot stress enough how important this is, not just to resolve your error, but for performance, and security of your application in general.
So instead of
"inv.dbo.InOutTransaction.startDate >= '" & dateStr & "' AND inv.dbo.InOutTransaction.endDate <= '" & dateEnd & "'"
You need to use
"inv.dbo.InOutTransaction.startDate >= #StartDate AND inv.dbo.InOutTransaction.endDate <= #EndDate"
Then add the parameters to your SqlCommand:
cmd.Parameters.Add("#StartDate", SqlDbType.DateTime).Value = dateStr
cmd.Parameters.Add("#EndDate", SqlDbType.DateTime).Value = dateEnd
This means that there is no need for any implicit conversions, your SqlCommand is expecting two date parameters, and you pass two DateTime objects. All of a sudden the format of the dates, and cultural variations is irrelevant. Furthermore, it means that SQL Server can make use of cached plans and does not need to recompile the query for every different start and end date values passed.
As an aside, it is a good idea to use Using when dealing with IDisposable objects, especially with unmanaged objects like these. So you might end up with something like:
Dim dateStr As DateTime = dtpStart.Value
Dim dateEnd As DateTime = dtpEnd.Value
Dim sql as String = "Select inv.dbo.InOutTransaction.refNo, " & _
" inv.dbo.Case_Status.deployedBy, " & _
" CONVERT(varchar(10), " & _
" inv.dbo.InOutTransaction.startDate,120) as startDate, " & _
" CONVERT(varchar(10),inv.dbo.InOutTransaction.endDate,120) as endDate, " & _
" inv.dbo.InOutTransaction.item " & _
"from inv.dbo.InOutTransaction "
" inner join inv.dbo.Case_Status " & _
" ON inv.dbo.InOutTransaction.refNo = inv.dbo.Case_Status.refNo " & _
"WHERE inv.dbo.InOutTransaction.refNo LIKE 'L%' " & _
"AND inv.dbo.InOutTransaction.status LIKE '%Out%' " & _
"AND inv.dbo.InOutTransaction.startDate >= #StartDate " & _
"AND inv.dbo.InOutTransaction.endDate <= #EndDate"
Using con As new SqlConnection("Data Source=MKZSA065\SQLSERVER2008R2,1499;Initial Catalog=inv;User ID=inv_admin;Password=inv_admin123")
Using cmd As New SqlCommand(sql, con)
con.Open()
cmd.Parameters.Add("#StartDate", SqlDbType.DateTime).Value = dateStr
cmd.Parameters.Add("#EndDate", SqlDbType.DateTime).Value = dateEnd
Using lrd As SqlDataReader = cmd.ExecuteReader()
Dim num As Integer = 1
Dim li As ListViewItem
While lrd.Read()
ListView1.BeginUpdate()
li = ListView1.Items.Add(num.ToString)
li.SubItems.Add(lrd("refNo").ToString)
li.SubItems.Add(lrd("deployedBy").ToString)
li.SubItems.Add(lrd("startDate").ToString)
li.SubItems.Add(lrd("endDate").ToString)
li.SubItems.Add(lrd("item").ToString)
'li.SubItems.Add(lrd("column_name").ToString)
'li.SubItems.Add(lrd("data_type").ToString)
num += 1
ListView1.EndUpdate()
ListView1.EnsureVisible(ListView1.Items.Count - 1)
End While
End Using
End Using
Please forgive my vb.Net if it is littered with errors, I haven't used it in a long time so am rusty to say the least, hopefully it is good enough to get the point across though
I would imagine the the datestr is in a local format.
Use the format YYYYMMDD as that is consistent regardless of DATEFORMAT settings.

Access SQL - UPDATE ODBC table with JOIN without linking the ODBC table in Access

Running MS Access 2010 and SQL Server 2008 SP1
I need to figure out how to successfully run DoCmd.RunSQL on an UPDATE query where the table being updated is an un-linked ODBC SQL Server table.
Here is what I tried, but I get ERROR 3135: SYNTAX ERROR IN JOIN OPERATION. I know this is correct form for an UPDATE with a JOIN in Access:
unsuccessful variation 1:
UPDATE [ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl]
INNER JOIN [myTbl]
ON ([ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl].[CDL] = [myTbl].[CDL])
AND ([ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl].[Archive ID] = [myTbl].[Archive ID])
AND ([ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl].[TimeInserted] = [myTbl].[TimeInserted])
and ([ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl].[Exported] = [myTbl].[Exported])
SET [ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl].[RecordStatus] = [myTbl].[RecordStatus]
WHERE Nz([ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl].[RecordStatus],'0') <> [myTbl].[RecordStatus]
unsuccessful variation 2:
UPDATE [ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl] as a
INNER JOIN [myTbl] as b
ON a.[CDL] = b.[CDL]
AND a.[Archive ID] = b.[Archive ID]
AND a.[TimeInserted] = b.[TimeInserted]
and a.[Exported] = b.[Exported]
SET a.[RecordStatus] = b.[RecordStatus]
WHERE Nz(a.[RecordStatus],'0') <> b.[RecordStatus]
I am able to sucessfully SELECT records with similar query conditions:
SELECT a.*
FROM [ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl] as a
INNER JOIN [myTbl] as b
ON a.[CDL] = b.[CDL]
AND a.[Archive ID] = b.[Archive ID]
AND a.[TimeInserted] = b.[TimeInserted]
and a.[Exported] = b.[Exported]
WHERE Nz(a.[RecordStatus],'0') <> b.[RecordStatus]
I am able to successfully INSERT records using the schema/table convention being used in the UPDATE queries:
INSERT INTO [ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl]
SELECT a.* FROM [myTbl] AS a WHERE a.[RecordStatus] IS NULL;
EDIT - for those curious, here is how I am executing the SQL statement from VBA:
Function fn_UpdateSQLServer()
Dim sTblNm As String
Dim sTypExprt As String
Dim sCnxnStr As String, vStTime As Variant
Dim db As Database, tbldef As DAO.TableDef
On Error GoTo ExportTbls_Error
sTypExprt = "ODBC Database" 'Export Type
sCnxnStr = "ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword" 'Create the connection string
vStTime = Timer
Application.Echo False, "Visual Basic code is executing."
Set db = CurrentDb()
'need a reference to Microsoft DAO 3.x library
DoCmd.SetWarnings False
For Each tbldef In db.TableDefs
' UPDATE
If (tbldef.Name = "myTbl") Then
'Debug.Print tbldef.Name
sTblNm = tbldef.Name
sSQL2 = " UPDATE [ODBC;DSN=MyDSNname;UID=MyUserID;PWD=MyPassword].[myTbl] as a " _
& " INNER JOIN [myTbl] as b " _
& " ON a.[CDL] = b.[CDL] " _
& " AND a.[Archive ID] = b.[Archive ID] " _
& " AND a.[TimeInserted] = b.[TimeInserted] " _
& " and a.[Exported] = b.[Exported] " _
& " SET a.[RecordStatus] = b.[RecordStatus] " _
& " WHERE Nz(a.[RecordStatus],'0') <> b.[RecordStatus] "
Debug.Print sSQL2
DoCmd.RunSQL (sSQL2)
End If
Next tbldef
DoCmd.SetWarnings True
MsgBox ("Done! Time taken= " & Timer & vStTime)
On Error GoTo 0
SmoothExit_ExportTbls:
Set db = Nothing
Application.Echo True
Exit Function
ExportTbls_Error:
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure ExportTblsODST"
Resume SmoothExit_ExportTbls
End Function
Ok - I figured it out. The update queries shown in my OP were written correctly; however, they only work if the SQL Server table has a primary key. As soon as I defined one, I was able to execute the VBA/SQL successfully.

Resources