SSL connection string for Azure PostgreSQL - correct syntax - vba

I have a Microsoft Excel workbook which I connect to a PostgreSQL db. I have had this working with the db on localhost for some time.
I have now moved my db to Azure PostgreSQL. I have successfully reconfigured my queries/connections to pull data into the spreadsheet (by setting up a DSN in 'ODBC Data sources 64 bit') with SSL set to require.
The workbook includes some vba to write data back to the database. I am getting the error:
Runtime error: '-2147467259 (80004005)': FATAL: SSL connection is
required. Please specify SSL options and retry.
The error throws on the dbConnPublic.Open sqlConnString line
The relevant parts of the code look like this:
Sub WriteRowToDB()
' Define connectivity
Dim dbConnPublic As New ADODB.Connection
Dim sqlConnString As String
sqlConnString = OpenConnection()
dbConnPublic.Open sqlConnString
End Sub
Public Function OpenConnection() As String
'Define connection objects and terms
Dim sqlConnString As String
Dim myDriver As String: myDriver = "{PostgreSQL ANSI(x64)}"
Dim myServer As String: myServer = "djm-main-01.postgres.database.azure.com"
Dim myDatabase As String: myDatabase = "postgres"
Dim myUserName As String: myUserName = "djmmain01admin#djm-main-01"
Dim myPassword As String: myPassword = "[my password]" ' this replaced by the real password
' Open connection
sqlConnString = "Driver={PostgreSQL ANSI(x64)};" & _
"DSN=postgres;" & _
"Server=" & myServer & ";" & _
"Port=5432;" & _
"UID=" & myUserName & ";" & _
"PWD=" & myPassword & ";" & _
"Database=" & myDatabase & ";" & _
"ssl=true;READONLY=0;PROTOCOL=6.4;FAKEOIDINDEX=0;SHOWOIDCOLUMN=0;ROWVERSIONING=0;SHOWSYSTEMTABLES=1"
OpenConnection = sqlConnString
End Function
I have tried every combination of ssl=true, ssl=required, sslmode=required, using two parameters and three, some with caps, some lowercase, some mixed. cannot find anything that makes a difference. Also not sure if this syntax is Azure, PostgreSQL or ADODB.
Note that I can also successfully connect to the Azure db using DBeaver and command line psql from Windows, using SSL.

Hi anyone who is watching. So I worked this out.
Actually very simple, the required parameter is ssmode=require. It is case sensitive. I must have somehow missed this from my permutations. And therefore assume that the syntax is determined by the PostgreSQL ODBC driver.
This resource helped:
https://www.connectionstrings.com/
Additional gotcha to watch out for : when the password is included in the connection string, then any non-alphanumerics need to be url encoded which I wasn't thinking about,so my system generated password with an exclamation mark had to be converted to %21. I got the encoded password from the User DSN at HKEY_CURRENT_USER\Software\ODBC\ODBC.INI\
However I have now changed the password so that it does not use non-alphanumerics.
Hope this is useful.

Related

Getting an ODBC Connection error in VB.NET when trying to connect to Teradata

First time questioner, be gentle
I'm trying to connect to a Teradata database using ODBC. When the code was originally written it worked. We have since upgraded the ODBC drivers for Teradata.
I tried connecting using VBA (Excel) as we still have some old code lying around
VBA code (simplified)
private FConnection as New ADODB.Connection
sub DBConnect(DSNName as string, UserName as string, Password as string)
Set FConnection = New ADODB.Connection
FConnection.Open DSNName, UserName, Password
This works with no issues. It also works if I use
FConnection.Open "DSN=" & DSNName & ";UID=" & UserName & ";PWD=" & Password & ";"
So I know the ODBC connection is not an issue.
Trying the same with VB.NET
Dim FConnection As Odbc.OdbcConnection
try
FConnection = New Odbc.OdbcConnection()
FConnection.ConnectionString = "DSN=" & DSNName & ";UID=" & UserName & ";PWD=" & Password & ";"
FConnection.Open()
Catch ex As Odbc.OdbcException
MessageBox.Show(ex.Message)
End Try
This results in
ERROR [08001] [Teradata][socket error] (439) WSA E HostUnreach: The Teradata server can't currently be reached over this network
I've tried a number of variations on the Connection string but nothing.
EDIT: I tried using Teradata.net instead of ODBC, but all variations of that end up with a Socket Exception in System.Net.Dns.GetAddrInfo
Pinging the server name works without issue

VB.net Receiving error BC30201: Expression expected

Im using this to declare a connection to a SQL
Public CONN As New SqlConnection("Data Source=" & My.Settings.SrvName & ";Initial Catalog=" & My.Settings.Catalog & ";Persist Security Info=" & True & ";User ID=" & My.Settings.USER & ";Password=" & My.Settings.PASSWRD & ";Integratedsecurity=" & My.Settings.InterSec & ";Connection Timeout=" & My.Settings.CnnTimeOut &)
but on the Closing ')' Im getting the error BC30201: Expression expected, this same method Ihave use in other proyects and works, can anyone tell me where my error?, please help.
Thanks.
This is a fine example of why lots of string concatenation is a bad idea. Your code is hard to read - even for you, obviously - and so it's error prone. With all those & operators in there, you haven't noticed that you have one you don't need at the end, This:
& My.Settings.CnnTimeOut &)
should be this:
& My.Settings.CnnTimeOut)
You should avoid using multiple & operators in one line and instead use the String.Format method or string interpolation. In this case, don't use any of those options. You should be using a SqlConnectionStringBuilder, e.g.
Dim builder As New SqlConnectionStringBuilder With {.DataSource = My.Settings.SrvName,
.InitialCatalog = My.Settings.Catalog}
Using connection As New SqlConnection(builder.ConnectionString)
'...
End Using
Notice that I have created the connection with a Using statement, which is what you should be doing too. Don't use a single, common connection. You can use a single connection string builder to generate the connection string, but you should then create, use and destroy connection objects where and when you need them.
Note that you can set as many properties of the connection string builder as you need to when you create it. I have just set two here for brevity.

VBA Connection String to Connect SQL server with SSL Certificate

I am using VBA connection string to connect SQL server in my VB script.It was running smoothly earlier.
Recently server team installed SSL certificate in that in which my macro is not running now and stating SSL Security error as like below snapshot.
Can anyone help me to fix the issue.
Thanks in advance!!!
Regards,
I would concatenate the values required for the connection string before you open it, instead of on cnSrc.Open.
I work with VBA and use ADO to query SQL server daily and I use the following format for my connection strings:
Provider=SQLOLEDB.1;User ID=UserName;Password=Password;Data Source=SeverName;Initial Catalog=DataBaseName
You can use the code below to test:
Private Sub TestConnection()
Dim cnSrc As ADODB.Connection
Dim CONNECTION_STRING As String
Dim cnServer As String, cndb As String, cnUser As String, cnPwd As String
cnServer = "SeverName"
cndb = "DataBaseName"
cnUser = "UserName"
cnPwd = "Password"
CONNECTION_STRING = "Provider=SQLOLEDB.1;User ID=" & cnUser & ";Password=" & cnPwd & ";" & _
"Data Source=" & cnServer & ";Initial Catalog=" & cndb
On Error GoTo CleanFail
Set cnSrc = New ADODB.Connection
cnSrc.Open CONNECTION_STRING
'bit wise comparison to check the connection's state
Debug.Assert (cnSrc.State And adStateOpen) = adStateOpen 'Debug.Assert pauses execution if false
CleanExit:
'close the connection
If Not cnSrc Is Nothing Then: If (cnSrc.State And adStateOpen) = adStateOpen Then cnSrc.Close
Set cnSrc = Nothing
Exit Sub
CleanFail:
Resume CleanExit
End Sub

How do I turn a QueryTable Connection into an ADODB connection?

I'm trying to update an old excel sheet that uses QueryTables to connect to a Microsoft SQL Server.
The following is working:
With ActiveSheet.QueryTables.Add(Connection:= _
"ODBC;DSN=[dbname];UID=[name];PWD=[pass];APP=Microsoft Office 2003;WSID=[machine name];DATABASE=[dbname];AutoTranslate=No;QuotedId=No;AnsiNPW=No" _
, Destination:=Range("A20"))
.CommandText = Array("[a valid query]")
There are some more sophisticated things I want to be able to do with the information this QueryTable is getting, but I keep getting the following error:
Run-time error '-2147467259 (80004005)': [DBNETLIB][ConnectionOpen (Invalid Instance()).]Invalid connection.
with the following code:
Private SqlConn As ADODB.Connection
Private Sub InitiateSqlConn(Optional User As String, Optional Pass As String, Optional Server As String, Optional DB As String)
If SqlConn Is Nothing Then
Dim strConn As String
Set SqlConn = New ADODB.Connection
If IsNull(User) Or IsEmpty(User) Or User = "" Then
User = "[user]"
End If
If IsNull(Pass) Or IsEmpty(Pass) Or Pass = "" Then
Pass = "[pass]"
End If
If IsNull(Server) Or IsEmpty(Server) Or Server = "" Then
Server = "[ServerName]"
End If
If IsNull(DB) Or IsEmpty(DB) Or DB = "" Then
DB = "[DBName]"
End If
strConn = "Provider=SQLOLEDB;Data Source=" & Server & ";Initial Catalog=" & DB & ";"
SqlConn.Open "Provider=SQLOLEDB;Data Source=[SeverName];Initial Catalog=[DBName];Trusted_connection=yes;", "[User]", "[Pass]"
End If
End Sub
Public Sub QueryInto(QR As String, ByRef RS As ADODB.Recordset, Optional User As String, Optional Pass As String, Optional Server As String, Optional DB As String)
InitiateSqlCon User, Pass, Server, DB
RS.Open QR, SqlConn
End Sub
I have also tried:
SqlConn.Open "Driver={SQL Server};Server=[SeverName];Database=[DBName];UID=[User];PWD=[Pass];"
And I get the following error:
Run-time error '-2147467259 (80004005)': [Microsoft][ODBC SQL Server Driver][DBNETLIB]Invalid connection.
Errors always occur on SqlConn.Open.
How do I get the connection that is established with the QueryTable to be established as an ADODB.Connection object ?
This one will fail because you are appending extra text after the "Trusted_connection" parameter. If you use a trusted connection, you don't need a username or password, and the syntax is different for SQLOLEDB than with {SQLServer} (it should be Integrated Security=SSPI;.
SqlConn.Open "Provider=SQLOLEDB;Data Source=[SeverName];Initial Catalog=[DBName];Trusted_connection=yes;", "[User]", "[Pass]"
You also need to build the Data Source and Initial Catalog into the string instead of Data Source=[SeverName] and Initial Catalog=[DBName].
This one will fail because you aren't using any security parameters:
strConn = "Provider=SQLOLEDB;Data Source=" & Server & ";Initial Catalog=" & DB & ";"
This one fails because for the same reason as the first. You need to build the actual parameters into the connection string.
SqlConn.Open "Driver={SQL Server};Server=[SeverName];Database=[DBName];UID=[User];PWD=[Pass];"
It should look something more like this:
Private Sub InitiateSqlConn(Optional User As String, Optional Pass As String)
If SqlConn Is Nothing Then
Dim strConn As String
Dim Server As String
Dim DB As String
'These can't be optional. They are required.
Server = "TheActualNameOfTheServerHere"
DB = "TheActualNameOfTheDatabaseHere"
Set SqlConn = New ADODB.Connection
If User = vbNullString Or Pass = vbNullString Then
'No credentials. Try a trusted connection.
strConn = "Provider=SQLOLEDB;Data Source=" & Server & _
";Initial Catalog=" & DB & ";Integrated Security=SSPI;"
Else
'Credentials.
strConn = "Provider=SQLOLEDB;Data Source=" & Server & _
";Initial Catalog=" & DB & ";User Id=" & User & _
"; Password=" & Pass & ";"
End If
SqlConn.Open strConn
End If
End Sub
Note that the Server and DB parameter cannot be optional. They are in fact required and must be valid in order to connect. You can also skip the null and empty checks for optional string parameters unless you're doing something really strange. They will default to vbNullString if nothing is passed.

Possible to query As400 DB2 via VB.Net without a PRG?

After spending a few days researching and trying to figure this out solo, I could really use some help.
I'm trying to query the As400's database directly from .Net without the use of a As400 program file. I have very little support other than "go ahead and try" from the As400 administrators (I'm being told what I'm attempting hasn't been done here before).
I'd really like to use CWBX. The code below successfully connects, but I could really use a pointer in the right direction on how to build a query:
Dim As400 As New AS400System
Dim AsProgram As New cwbx.Program
Dim AsCommand As New cwbx.Command
Dim strQuery As String
As400.Define("AS400")
As400.UserID = ""
As400.Password = ""
As400.IPAddress = ""
As400.Connect(cwbcoServiceEnum.cwbcoServiceRemoteCmd)
If As400.IsConnected(cwbcoServiceEnum.cwbcoServiceRemoteCmd) = 1 Then
MsgBox("Valid Connection")
Else
MsgBox("Invalid Connection")
Exit Sub
End If
'-----------------------------------------------------------------------------------------
'Trying to figure out first if this syntax is correct, and if so... where/how to call it??
'-----------------------------------------------------------------------------------------
strQuery = "SELECT * FROM Library.File WHERE FILEFIELD='Criteria'"
' ---
AsProgram.LibraryName = ""
AsProgram.ProgramName = "" '?
AsProgram.system = As400
'Assuming this will end up being a program call?
'AsProgram.Call()
As400.Disconnect(cwbcoServiceEnum.cwbcoServiceRemoteCmd)
I'm very open to any other methods/suggestions. I've looked for guides from IBM's site as well as MSDN and neither actually do direct querying without the use of an As400 program file. Is this even possible?
Here is a simple console app that will retrieve all the records from one table and display the row count.
Imports System.Data.OleDb
Module Module1
Sub Main()
Dim cmd As New OleDbCommand
Dim table As String = "YOUR TABLE"
cmd.CommandText = "SELECT * FROM " & table
Dim ip As String = "YOUR AS/400 IP GOES HERE"
Dim user As String = "YOUR USER ID"
Dim pass As String = "YOUR PASSWORD"
Dim defaultLib As String = "YOUR LIBRARY"
Dim connstring As String = "Provider=IBMDA400;" & _
"Data Source=" & ip & ";" & _
"Force Translate=0;" & _
"Default Collection=" & defaultLib & ";" & _
"User ID=" & user & ";" & _
"Password=" & pass
cmd.Connection = New OleDbConnection(connstring)
cmd.Connection.Open()
Dim dr As OleDbDataReader = cmd.ExecuteReader
Dim dt As New DataTable
dt.Load(dr)
Console.WriteLine(dt.Rows.Count)
Console.WriteLine("Press ENTER to close...")
Console.ReadLine()
End Sub
End Module
The remotecmd service is basically a Rexcd daemon. Not sure why you're messing with that when you want to simple query a DB table. The integrated DB in IBM i is accessible via ODBC, OLEDB, JBDC and most importantly for you a ADO.NET provider.
http://www-03.ibm.com/systems/power/software/i/access/windows/dotnet.html
All of the above mentioned drivers are available in the IBM i Access software. Note that while some of the IBM i Access features are chargeable, ex 5250 emulation, and you must have bought a license; the data access providers are not.
Included in the IBM i Access package is a collection of documentation known as the "Programmers Toolkit"
An example using the .NET data provider from that toolkit:
Public Sub Example()
Dim cn As iDB2Connection = New iDB2Connection("DataSource=mySystemi;")
Dim da As New iDB2DataAdapter("select * from mylib.mytable", cn)
End Sub
Lastly note that the (free) .NET provider doesn't support Microsoft's Entity Framework (EF). If you need EF support, you'll have to pay for DB2 Connect
http://www-03.ibm.com/software/products/en/db2-connect-family