PostgreSQL/VBA: transaction block fail check or process - vba

During a transaction block, if part of it fails or gets interrupted what is the best way to handle this?
I am thinking intermediate queries (see code comments) to confirm that the previous query was successful. Or is there a better way?
Sub SetDataProcessPriorities()
Dim cCon As New ADODB.Connection
Set cCon = Application.Run("Personal.xlsb!ConnectToPg")
Call Application.Run("Personal.xlsb!SendPgQueryOnly", "begin;", cCon)
Call Application.Run("Personal.xlsb!SendPgQueryOnly", "delete from data_proc_pri;", cCon)
'intermediate select query here?
Call Application.Run("Personal.xlsb!SendPgQueryOnly", "insert into data_proc_pri select * from data_proc_pri_store;", cCon)
'intermediate select query here?
Call Application.Run("Personal.xlsb!SendPgQueryOnly", "commit;", cCon)
End Sub
I'm open to a VBA (sorry) or PostgreSQL (or both) focused solution.
Bonus question: What do you call this type of programming? Infrastructure programming?
Personal workbook code if you need it:
Sub SendPgQueryOnly(sSql As String, Optional cCon As ADODB.Connection, Optional sOdbcName As String = "[omitted]")
sCaller = "SendPgQueryOnly"
Dim cnDB As New ADODB.Connection
Dim rsRecords As New ADODB.Recordset
If IsMissing(cCon) Or cCon Is Nothing Then
cnDB.Open sOdbcName
rsRecords.CursorType = 2 'adOpenDynamic
rsRecords.Open sSql, cnDB
Else
rsRecords.CursorType = 2 'adOpenDynamic
rsRecords.Open sSql, cCon 'use the passed connection obj
End If
cleanup:
Set rsRecords = Nothing
Set cnDB = Nothing
End Sub
Function ConnectToPg(Optional sOdbcName As String = "[omitted]") As ADODB.Connection
sCaller = "ConnectToPg"
Dim cnDB As New ADODB.Connection
cnDB.Open sOdbcName
Set ConnectToPg = cnDB
End Function

For transactional control you can use the BeginTrans, CommitTrans, and RollbackTrans Methods on a Connection object
https://msdn.microsoft.com/en-us/library/ms680895(v=vs.85).aspx
Whilst one has a degree of programming style and latitude given the specific problem I guess one could query the database using some Select queries to ensure that the database state was changed as expected; if as expected then commit and if not then rollback.

Related

I receive "Error 3251" retrieving table keys in Access 2013 (ADO VBA) with this piece of code

I'm trying to list a local database relationships with ADO with code.
Code works with SQL Server connection, but not with CurrentProject connection. Code is below.
Any idea?
Sub SeeRelationshipsADO()
Dim conn As ADODB.Connection
Dim catADOX As New ADOX.Catalog 'El catálogo ADOX
Dim tblADOX As ADOX.Table 'Tabla ADOX
Dim KeyADOX As ADOX.key 'Clave ADOX
Dim strRIName As String
Set conn = CurrentProject.Connection
'Seteo el catálogo
Set catADOX.ActiveConnection = conn
Set tblADOX = catADOX.Tables("ST_JLE_Materiales")
For Each KeyADOX In tblADOX.Keys
'Here returns error 3251
Next KeyADOX
Set KeyADOX = Nothing
Set tblADOX = Nothing
Set catADOX = Nothing
End Sub
I got it!
Thanks to JohnyL
It's not possible to do the matter with linked tables and local tables at once

How to return multiple values from table based on specific item that I entered?

I tried to use Tooling_No_AfterUpdate() for both Sub and Function but it prompt me 'Ambiguous name detected' as I know that I can't use the same identifier. Then, I changed the identifier and set it to public function but it doesn't work and prompt me 'User-defined type not defined'.
I'm creating a form for user to enter the tooling number to know the storage location where it can be more than one location. I tried to use ADODB.Recordset to get data from my asset table. So here's what I tried:
Private Function Tooling_No_Enter() As ADODB.Recordset
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
Set Tooling_No_Enter = CurrentProject.Connection.Execute("select FirstName, LastName from Employees")
End Function
Private Sub Tooling_No_AfterUpdate()
Dim strStorage_Location_1 As String
Dim strStorage_Location_2 As String
Dim strStorage_Location_3 As String
Dim strStorage_Location_4 As String
Dim strStorage_Location_5 As String
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
Set rst = Tooling_No_Enter()
Do While Not rst.EOF
strStorage_Location_1 = rst!Storage_Loacation_1
strStorage_Location_2 = rst!Storage_Loacation_2
strStorage_Location_3 = rst!Storage_Loacation_3
strStorage_Location_4 = rst!Storage_Loacation_4
strStorage_Location_5 = rst!Storage_Loacation_5
Debug.Print strStorage_Location_1 + vbCrLf + strStorage_Location_2 + vbCrLf + strStorage_Location_3 + vbCrLf + strStorage_Location_4 + vbCrLf + strStorage_Location_5
rst.MoveNext
Loop
rst.Close
Set rst = Nothing
End Sub
After that, users able to choose the location while the chosen location will be recorded into asset table and transaction table and these are the parts i can't figure it out.
You are using the wrong method to open ADODB recordset. For one thing, Execute is used for action SQL (DELETE, UPDATE, INSERT).
One way to use a recordset object in multiple procedures is to declare recordset variable in module header. Example shows declaring and setting and opening connection and recordset objects which are then referred to in another procedure not shown.
Option Compare Database
Option Explicit
Public strOldLabNum
Dim cn As ADODB.Connection
Dim rsOldSample As ADODB.Recordset
___________________________________________________
Private Sub cbxOldLabNum_AfterUpdate()
Set cn = CurrentProject.Connection
Set rsOldSample = New ADODB.Recordset
strOldLabNum = Me.tbxOldYear & "A-" & Me.cbxOldLabNum
'select old sample info from table zSample
rsOldSample.Open "SELECT * FROM zSample WHERE LabNum='" & strOldLabNum & "';", _
cn, adOpenStatic, adLockPessimistic
End Sub

VBA Access Return Values When Calling a Function In Another Database

I am trying to call a function in a module in Database B from a form in Database A.
I realize that in VBA, you can get a return value for a function by specifying a return type and using 'Set' to set a variable (which the same name as the function), which returns the value.
I have tried to call a function in Database B, using both db.Execute (which should return a Variant) and by connecting to Database B and doing rst.Open (to return a recordset.)
Neither approach seems to return a value to the form in Database A.
Does anyone have sample code demonstrating this?
If you want to return a recordset from a table that is not in the current database then you need to set the ADODB.Connection variable to the path of the new database. An example of that is:
Public Sub rdstALTDB()
Dim conn As ADODB.Connection
Dim fPath as String
Dim rsTest As ADODB.Recordset
Set conn = New ADODB.Connection
fPath = C:/Test/TestDb.accdb 'location of the alternate database
conn.Open "Provider = Microsoft.ACE.OLEDB.12.0; Data Source = " & fPath
Set rsTest = New ADODB.Recordset
rsTest.Open "Test", conn
'Do Something With the recordset
rsTest.Close
Set rsTest = Nothing
End Sub
Hope this helps.

VBA LOOP in ORACLE SQL

I was trying to write a VBA to run a query assigned to MySQL only when the HCR_DM.HCR_DM_FACT table is fully loaded. I'm using the count of distinct source in that table to decide if it is fully loaded.
When I was running the Macro below, I got an error message for the Do While line, saying that Object doesn't support this property or method.
I'm quite new to VBA, and I couldn't figure out what need to be adjusted. Can some one help me with this?
Thanks!
Const CNSTR = "Provider = OraOLEDB.Oracle; Data Source =CSDPRO; ODBC;DRIVER={Oracle ODBC Driver};SERVER=CSDPRO;User ID=HCR_SANDBOX;password=******"
Sub FillWithSQLData(strSQL As String, wkSht As String)
' Given a SQL query and worksheet, fills the worksheet with a data dump of the SQL query results
' Define variables
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sql_count As String
' Set variables
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Connect to SQL Server
With cn
.ConnectionString = CNSTR
.Open
End With
' Query SQL Server and return results as a data dump in cell A2 of the specified worksheet
With rs
.ActiveConnection = cn
sql_count = "select count( distinct a.src_table) from hcr_dm.hcr_dm_fact a"
Set rf = cn.Execute(sql_count)
Do While rf.Fields.Value = 8
.Open strSQL
Loop
Worksheets(wkSht).Range("A2").CopyFromRecordset rs
.Close
End With
' Close connection
cn.Close
Set rs = Nothing
Set Conn = Nothing
End Sub
Sub Refresh()
' Define SQL query
Dim mySQL As String
mySQL = "select a.oracle_fin_company_id || ' - ' || a.oracle_fin_company_desc as COMPANY " & _
"From hcr_dm.legal_entity_summary a " & _
"where a.Company_Header = 'Filed'"
' Choose worksheet where results should be displayed
Dim myWkSht As String
myWkSht = "Sheet1"
' Call connection sub
Call FillWithSQLData(mySQL, myWkSht)
End Sub
You're not selecting a field. The lines
Set rf = cn.Execute(sql_count)
Do While rf.Fields.Value = 8
Should probably be
Set rs = cn.Execute(sql_count)
Do While rs.Fields(0).Value = 8
Also, note the typo in that you declared rs but you're filling rf with the Recordset.
I recommend you use the Option Explicit statement to help find these. You can read more about it here.

VBA/SQL openrecordset(strSQL) Error 3001

I am trying to run a query on a database server (Oracle 10g) using VBA/Excel and to display the results in a excel table. I have created the ODBC connection (read-only) and tested the connection. I works fine if I import data as a data source in excel (I am able to filter through a query as well) However my VBA code is giving me Error 3001
Sub Test()
Dim cnn As ADODB.Connection
Dim canConnect As Boolean
Dim rs As Recordset
Dim strSQL As String
Set cnn = New ADODB.Connection
cnn.Open "DSN=blah;Uid=blah;Pwd=blah"
strSQL = "select job_start_dttm, job_end_dttm from c_job"
Set rs = cnn.openrecordset(strSQL)
ActiveCell = rs(0)
End Sub
I get Error 3001 - Arguemnts are of worng type, are out of acceptable range, or are in confilct with one another
The query itself runs fine in SQL developer. Thanks
edit: The error is on "Set rs = cnn.openrecordset(strSQL)" line
Try:
Sub Test()
Dim cnn As New ADODB.Connection
Dim canConnect As Boolean
Dim rs As New ADODB.Recordset
Dim strSQL As String
cnn.Open "DSN=blah;Uid=blah;Pwd=blah"
strSQL = "select job_start_dttm, job_end_dttm from c_job"
rs.Open strSQL, cnn
ActiveCell = rs(0)
End Sub
You seem to be mixing up a little DAO with your ADODB. You could have used Execute, but the above should suit.
Try qualifying the type name of rs with the ADODB prefix to make sure it is not being defined as the built-in Access Recordset object type instead.
Dim rs As ADODB.Recordset
Edit:
You will also need to use the ADO .Execute command instead of the DAO .OpenRecordset:
Set rs = cnn.Execute("...")