Multiple ODBC Sources with 1 DSN (The Painless Way)

If your SQL DB (i.e. Sqlite or DuckDb) has multiple tables you want to connect with AmiBroker, here is a step-by-step tutorial.

Short Answer: Clone your own Plug-in from AmiBroker's ODBC/SQL Universal Data Plug-in. Each plug-in profile connects to 1 table from DB.

Long Answer:

The Problem...as pointed out by @bigalgator in this post.

The ODBC connection settings are stored in the Windows registry. By default there can only be one connection.

The Solution...use Visual Studio to change the Plugin name from C++ source code.

Step 1) Check AmiBroker's page for the ODBC/SQL plugins (Version 1.7.0).

Open the solution file C:\Downloads\ODBCSrc\ODBC.sln in Visual Studio

Step 2) Change the source code to clone the Plugin DLL file

  • From Plugin.cpp change the PLUGIN_NAME, PLUGIN_NAME_AFL to any name you like. PLUGIN_ID PINCODE change last value, for example ( 'O', 'D', 'B', '1' )

  • From ODBC.cpp change the value in SetRegistryKey, for example "TJP1"

Step 3 Change Properties for Build to create the DLL file

Step 4 Copy DLL file to AmiBroker path

  • After hitting build the DLL file is located at C:\Downloads\ODBCSrc\x64\Release
  • Copy DLL to C:\Program Files\AmiBroker\Plugins
  • In AmiBroker's File > Database Settings > Data Source, you will now see your cloned plugin profiles.

Step 5 Apply DSN Info

These steps worked for me, and I hope they work for you also!

2 Likes

And here I am, having endured a lot of pain initially, writing a very unique data plugin.

This is on a lighter note, from your topic title: "The painless way" :smiley:

As you can see everyone has different definition of pain :slight_smile:

3 Likes

Everyone posting on this forum is going through some kind of pain and looking for a cure. I benefited greatly from other's pain. Thus, I want others to enjoy a painless way if they ever face the same problem.

Btw, @Tomasz is a selfless guy for posting the plug-in source code :slight_smile:

2 Likes

@Wealthero Thanks for sharing.

I'm using custom query to connect to multiple tables of tickers (each ticker has its separate table),

Now for this solution, If I have multiple cloned plugins I didn't get how to use it if I want to replace custom query solution
How do you connect to multiple plugins at once? What am I missing here ?

Yes, Tomasz is an inspiration!

I have not yet seen odbc plugin, because it was contrary to my plugin design.
QT was a good starting point.

It is possible without major changes that you can choose your connection strings from single plugin dll. I will have a look.
Are you using the same connection string and different sql tables, or a completely different connection string?
Because the tables are supposed to be populated in the "Table name" dropdown

I have 2 tables in the same DuckDb (SQL) database. One table has US stocks and the other Greater China Stocks (HK, TW, CN). Thus, I have 1 DSN and 2 tables.

On AmiBroker, I have 2 databases, which connects to 2 tables of the same DSN.

Without renaming / cloning the plugin, if I change the ODBC Table Name in the GCN database, the US database will change also. This is becuase:

The ODBC connection settings are stored in the Windows registry. By default there can only be one connection.

By cloning the 2 custom plugins using the methods above, I added these in the registry.

One table tie to 1 plugin. This is a windows registry thing.

P.S. While I have 2 tables with 1 DSN name. If you have 2 DSN (or 2 SQL database each with 1 table). The clone plugin method should work also.

If I have all markets on 1 table and 1 db. The default ODBC plugin will work just fine without needing to clone plugin.

1 Like

I sorted this long back.
see the ws_rtd plugin settings storage in main documentation, link in my profile/or wsrtd forum topic.

Back in the day Tomasz used TJP/settings, I modified mine to
TJP/DB_Name/settings so I can keep a profile per unique DB_NAME

by doing so, if we use same DB_NAME in different physical location, they would still use the same set of settings.
Best of both.

So you need to extract db_name from Notify and store. then modify
AfxGetApp()->WriteProfileString(), same while reading

2 Likes

@Wealthero

Replace your plugin.cpp and global.cpp files from repo and build.
Now you should see multiple profiles as
TJP/ODBC_DBNAME/

as always, backup your AB before testing plugins.

Now you dont need to clone plugins, just one is enough. rename conflicting dll files to .bak

2 Likes

Now I got it, I have this issue slightly different
I have the columns of my intraday db, and daily db have one different column name for date between both the dbs

I asked chatgpt and made custom sql statement, I slightly know how it works it has [COALESCE] and nested queries :grin:
Previously when I switch dbs from intra and daily it was causing the issue you described..

But now using this solution, after creating the last dll as you suggested @nsm51

While switching between two ODBC databases one for intra and one for daily, I need to open configure without doing anything and then flush DB cache as well otherwise the old data is there.

AB is super efficient, no need to switch DB. just keep 2 AB instances open, one intra and one daily.
I dont even restart AB for weeks or a month, until windows forces me to restart after an update.

If you like such work and find it useful, you can sponsor development on my github. thanks.

1 Like

Thanks @nsm51 for your support.

1 Like

Thank you! Quite nifty solution :slightly_smiling_face:

1 Like

I had one problem here if anyone can suggest, sometimes I need to import some ascii quotes from amiquote like GC=F for gold, it is imported fine
But ODBC from time to time give exception that the table isn't available in DB
I'm using custom query and tried to exclude the symbol from the query as well

and  name !='GC=F'

Do I need to update the plugin code ?
I think I could use some additional check here

	catch( CDBException *e )
	{	 
		CString strFormatted;

		strFormatted.Format(_T("ODBC driver returned following exception:\n\n%d\n%s\n%s"), e->m_nRetCode, e->m_strError, e->m_strStateNativeOrigin);
		AfxMessageBox( strFormatted );

		e->Delete();

No plugin dabbling required.
you should mark all such symbols as use only local database=Yes.

AB will exclude them from plugin calls.
It is under General category of Symbol information window.

2 Likes

Thanks @nsm51 ,works marvel