Connect to MySQL from Microsoft Data Application Block - database-connection

lI am using the Data Application block for a majority of my data access, specifically using the SqlHelper class to call the ExecuteReader, ExecuteNonQuery, and like methods. Passing the connection string with each database call.
How can I modify this to enable connection to a MySQL database as well.

If you've got the Enterprise Library installed and already know how to connect to SQL Server databases, connecting to MySQL databases is not any harder.
One way to do it is to use ODBC. This is what I did:
Go to MySQL.com and download the latest MySQL ODBC connector. As I write this it's 5.1.5. I used the 64-bit version, as I have 64-bit Vista.
Install the ODBC Connector. I chose to use the no-installer version. I just unzipped it and ran Install.bat at an administrator's command prompt. The MSI version probably works fine, but I did it this way back when I installed the 3.51 connector.
Verify the installation by opening your ODBC control panel and checking the Drivers tab. You should see the MySQL ODBC 5.1 Driver listed there. It seems to even co-exist peacefully with the older 3.51 version if you already have that. Additionally it coexists peacefully with the .NET connector if that is installed too.
At this point you will be doing what you've done to connect to a SQL Server database. All you need to know is what to use for a connection string.
Here's what mine looks like:
Of course you can set "name" to whatever you want.
If this is your only database, you can set it up as the defaultDatabase like this:
Access your data in your code like you always do! Here's a plain text sql example:
public List<Contact> Contact_SelectAll()
{
List<Contact> contactList = new List<Contact>();
Database db = DatabaseFactory.CreateDatabase("MySqlDatabaseTest");
DbCommand dbCommand = db.GetSqlStringCommand("select * from Contact");
using (IDataReader dataReader = db.ExecuteReader(dbCommand))
{
while (dataReader.Read())
{
Contact contact = new Contact();
contact.ID = (int) dataReader["ContactID"];
client.FirstName = dataReader["ContactFName"].ToString();
client.LastName = dataReader["ContactLName"].ToString();
clientList.Add(client);
}
}
return clientList;
}
Another way to do it is to build and use a MySql provider. This guy did that.
I learned how to do this by adapting these instructions for connecting to Access.
Oh, and here are some more MySql Connection String samples.

Related

Trying to access to a DBF file using Advantage OLE DB provider throws an exception when opening a connection

I have an ASP.NET MVC application which is trying to open below OLE DB connection:
string conString = #"Provider=Advantage OLE DB Provider;Data Source=" + dbfFilePath + ";Extended Properties=dBASE IV;";
using (dBaseConnection = new OleDbConnection(conString))
{
dBaseConnection.Open();
// Some stuff
}
I have installed below package from here.
I am using this provider in order to access a dbf file (specified on the dbfFilePath variable) and then later add some information into it. When I perform the Open command on the above code snippet I get below exception message:
Error 6420: The 'Discovery' process for the Advantage Database Server failed. Unable to connect to the Advantage Database Server. axServerConnect AdsConnect.
Previously I was using VFPOLEDB.4 provider and it was working ok when reading and modifying the dbf file. The problem is that it is only available in 32-bit (there is no version in 64-bit) and now I need it to be in 64-bit so I decided to use Advantage OLE DB provider that is available in 64-bit and as far as I know it does the same as VFPOLEDB.
What am I doing wrong?
UPDATE 2020/11/16:
If I add some parameters to connection string:
string conString = #"Provider=Advantage OLE DB Provider;Data Source=" + dbfFilePath + ";ServerType=ADS_LOCAL_SERVER;TableType=ADS_VFP;Extended Properties=dBASE IV;";
Then when opening connection I get below exception:
Error 7077: The Advantage Data Dictionary cannot be opened. axServerConnect AdsConnect
UPDATE 2020/11/20:
var dbfFilePath =#"C:\MyApp\Temp"; // using c:\MyApp\Temp\myTable.dbf does not work (below open command fails)
string conString = #"Provider=Advantage OLE DB Provider;Data Source=" + dbfFilePath + ";ServerType=ADS_LOCAL_SERVER; TableType=ADS_VFP;";
using (dBaseConnection = new OleDbConnection(conString))
{
dBaseConnection.Open();
OleDbCommand insertCommand = dBaseConnection.CreateCommand();
insertCommand.CommandText = "INSERT INTO [myTable] VALUES (2,100)";
insertCommand.ExecuteNonQuery();
}
Note: [myTable] has the same name that the dbf file within C:\MyApp\Temp.
Now open command works but when performing insertCommand.ExecuteNonQuery() it gets stuck (it does nothing).
UPDATE 2020/11/27:
Ok,I think I have detected what is happening. It works ok when using Advantage OLE DB provider in 32-bit, however, using Advantage OLE DB provider in 64-bit is not working. In both cases I use it on Windows Server 2012 R2 Standard 64-Bit and Advantage OLE DB provider is version 11.10.
I have checked this using LINQPad 5, and it works but when performing
insertCommand.ExecuteNonQuery()
... and before doing the insert to the dbf file below warning modal window appears waiting for you to click on 'Accept' button. Once you click on the button, insert is done in dbf file correctly.
So, I guess that when running my web application (ASP.NET MVC app) in production environment this warning modal windows does not appear but in fact, it is waiting for you to click on the button to proceed inserting data in the dbf file but as this warning window is not visible (it is not shown) I can click on that button and consequently ExecuteNonQuery never ends (it stalls) and it stays waiting for you to click that button indefinitely.
How can I solve this error? can I modify ads.ini in some way in order to avoid this waring message to appear so application can work?
I see you removed the VFP tag which I think most relevant to this question :)
I again tested that with these codes as a sample and it worked without a glitch:
void Main()
{
string dbfFilesPath = #"C:\PROGRAM FILES (X86)\MICROSOFT VISUAL FOXPRO 9\SAMPLES\Data";
string conString = $#"Provider=Advantage OLE DB Provider;Data Source={dbfFilesPath};ServerType=ADS_LOCAL_SERVER;TableType=ADS_VFP;";
DataTable t = new DataTable();
using (OleDbConnection cn = new OleDbConnection(conString))
using (OleDbCommand cmd = new OleDbCommand($#"insert into Customer
(cust_id, company, contact)
values
(?,?,?)", cn))
{
cmd.Parameters.Add("#cId", OleDbType.VarChar);
cmd.Parameters.Add("#company", OleDbType.VarChar);
cmd.Parameters.Add("#contact", OleDbType.VarChar);
cn.Open();
for (int i = 0; i < 10; i++)
{
cmd.Parameters["#cId"].Value = $"XYZ#{i}";
cmd.Parameters["#company"].Value = $"Company XYZ#{i}";
cmd.Parameters["#contact"].Value = $"Contact XYZ#{i}";
cmd.ExecuteNonQuery();
}
t.Load(new OleDbCommand($"select * from Customer order by cust_id desc", cn).ExecuteReader());
cn.Close();
}
t.Dump(); // tested in LinqPad AnyCPU version
}
Here is the partial result I got:
XYZ#9 Company XYZ#9 Contact XYZ#9 0.0000
XYZ#8 Company XYZ#8 Contact XYZ#8 0.0000
XYZ#7 Company XYZ#7 Contact XYZ#7 0.0000
XYZ#6 Company XYZ#6 Contact XYZ#6 0.0000
XYZ#5 Company XYZ#5 Contact XYZ#5 0.0000
XYZ#4 Company XYZ#4 Contact XYZ#4 0.0000
XYZ#3 Company XYZ#3 Contact XYZ#3 0.0000
XYZ#2 Company XYZ#2 Contact XYZ#2 0.0000
XYZ#1 Company XYZ#1 Contact XYZ#1 0.0000
XYZ#0 Company XYZ#0 Contact XYZ#0 0.0000
XXXXXX Linked Server Company 0.0000
WOLZA Wolski Zajazd Zbyszek Piestrzeniewicz Owner ul. Filtrowa 68 Warszawa 01-012 Poland (26) 642-7012 (26) 642-7012 3694
WINCA Wenna Wines Vladimir Yakovski Owner 0.0000
WILMK Wilman Kala Matti Karttunen Owner/Marketing Assistant Keskuskatu 45 Helsinki 21240 Finland 90-224 8858 90-224 8858 4400
WHITC White Clover Markets Karl Jablonski Owner 305 - 14th Ave. S., Suite 3B Seattle WA 98128 USA (206) 555-4112 (206) 555-4115 38900
WELLI Wellington Importadora Paula Parente Sales Manager Rua do Mercado, 12 Resende SP 08737-363 Brazil (14) 555-8122 3600
WARTH Wartian Herkku Pirkko Koskitalo Accounting Manager Torikatu 38 Oulu 90110 Finland 981-443655 981-443655 24200
As it is not working for you, I think it might have to do with:
Access rights. You say, you use with ASP.Net MVC, I wonder if the 'connecting account' has only read access? In IIS, basic settings as I remember there were a setting for connect as. You might at least set it to connect by an account that has full rights to that directory.
Sharing. The file might be in use shared elsewhere and for some reason your insert is waiting trying to get lock?
SET NULL ON ? Another slight possibility. You might need to execute this first, on the same connection. If there are fields that you are not supplying a value in insert but "not null" in table structure would otherwise cause it to fail.
You might start testing the same file from say within LinqPad running with administrator rights to eliminate the access rights stuff alltogether (if data directory is under program files or program files (x86), then it is a problem by itself.
I would expect an immediate error message, but who knows maybe driver is waiting for a timeout in case of write access failure?
Some ideas (the way I do it:)
Instead of trying to use VFP data with 64 bits access, you might create a server that runs in 32 bits IIS Application pool (or use its own web serving) and handles the data access via REST API (or WCF). I use 32 bits ASP.Net MVC application(s) since years with success using VFOLEDB itself.
If you think of REST API path, you might either use ASP.Net core (which is fast unlike the pre core) or use something else, say Go for building it. Go and Iris framework, for an example is an excellent fit to build a REST API server for your data over night (unlikely you would think Go, but if you do, remember to compile with x86 architecture).

How to enable wirecompression on Firebird 3.0

I work with Firebird and Delphi, I want to implement access via internet with wirecompression;
But I am unable to activate it.
I have followed the steps inside this document for the new parameter(one of the few I was able to find)
How to enable WireCompression on Firebird 3.0 using FireDAC
In the tests I use
Windows server 2012 R2
Firebird : Firebird-3.0.4.33054_0_Win32(32 bits)
Also copied to executable folder.
fbclient.dll
zlib1.dll (idem server and client)
created firebird.conf with wirecompression=true.
and I am giving wirecompression=true inside the Firedac of the application.
Why am I unable to activate the P15:CZ compression ?
Sending connection info for the example:
================================
Connection definition parameters
================================
DriverID=FB
Database=miservidor001:C:\sysdat\C100\gestdat03.fdb
User_Name=SYSDBA
PassWord=*****
WireCompression=true
================================
FireDAC info
================================
Tool = RAD Studio 10.2
FireDAC = 16.0.0 (Build 88974)
Platform = Windows 32 bit
Defines = FireDAC_NOLOCALE_META;FireDAC_MONITOR
================================
Client info
================================
Loading driver FB ...
Brand = Firebird
Client version = 300049900
Client DLL name = C:\APPS\WC01\fbclient.dll
================================
Session info
================================
Current catalog =
Current schema =
Server version = WI-V3.0.4.33054 Firebird 3.0
WI-V3.0.4.33054 Firebird 3.0/tcp (WIN-2012LAGO003)/P15:C
WI-V3.0.4.33054 Firebird 3.0/tcp (nucleo)/P15:C'
NOTE: I don't know Delphi nor FireDAC, this answer is based on the general behavior of Firebird and my experience with maintaining its JDBC driver (Jaybird). So it is possible that there is a better answer specifically for FireDAC/Delphi.
Enabling or disabling wire compression is entirely determined by the client, not by the server. This means that configuration of the server is not necessary nor has it any effect, except in cases where the server itself acts as a client, for example with execute statement ... on external datasource.
To be able to use wire compression, you need three things:
fbclient.dll
zlib1.dll (in the same location as fbclient.dll, or on the search path)
A configuration to enable wire compression for the client
Point 3 is likely your problem: I'm not sure if FireDAC has a connection property WireCompression that actually enables wire compression.
I know of two ways to enable wire compression for the client:
Create a firebird.conf in the same directory as the fbclient.dll used by your application. In this configuration file, put the requested configuration options (one per line):
WireCompression = true
# maybe other config lines (eg AuthClient, WireCrypt, etc)
Instead of creating a firebird.conf file, pass the configuration (with linebreaks separating config options) in the isc_dpb_config (int 87) database parameter item.
The value is the same as the content of the firebird.conf file in the previous option. This may run into size issues if the client is using the old database parameter buffer format (where strings are max 255 bytes) and you want to pass (a lot) more config options.
Option 1 is probably the simplest and will work for all frameworks. Option 2 depends on whether or not the framework or driver exposes the database parameter buffer or if it has a connection property that maps to isc_dpb_config.
For example in Java using Jaybird, you can enable compression (only when using native connections) using:
Properties props = new Properties();
props.setProperty("user", "sysdba");
props.setProperty("password", "masterkey");
props.setProperty("config", "WireCompression=true");
try (var connection = DriverManager.getConnection(
"jdbc:firebirdsql:native:localhost:D:/data/db/fb3/fb3testdatabase.fdb", props)) {
FirebirdConnection fbCon = connection.unwrap(FirebirdConnection.class);
FbDatabase fbDatabase = fbCon.getFbDatabase();
System.out.println(fbDatabase.getServerVersion());
} catch (SQLException e) {
e.printStackTrace();
}
This prints out WI-V3.0.4.33054 Firebird 3.0,WI-V3.0.4.33054 Firebird 3.0/tcp (host)/P15:CZ,WI-V3.0.4.33054 Firebird 3.0/tcp (host)/P15:CZ (note this is <server version>,<server protocol info>,<client protocol info>). The Z in P15:CZ means that the connection is zlib compressed (the C that the connection is encrypted).
Here, the config property is an alias for isc_dpb_config.
Mark's answer is the best (and probably the only) source of information about this problem in the entire internet. Good luck finding anything on Delphi, FireDAC or Firebird documentation about what he said.
Based on his answer, here is what you need to use Firebird wire compression with FireDAC:
You need Delphi Rio 10.3.1 (Update 1) or later. Only in this version the config low level parameter (see below) was added to FireDAC.
You must pass WireCompression=true to the low level config connection parameter. This is NOT TFDConnection.Params (high level).
To accomplish this you need to set the IBAdvanced property of TFDPhysFBConnectionDefParams to config=WireCompression=true (yeah! Go figure it!)
Code:
FDConnection1.DriverName := '​FB';
with FDConnection1.Params as TFDPhysFBConnectionDefParams do
begin
Server := '...';
Database := '...';
UserName := '...';
Password := '...';
IBAdvanced := 'config=WireCompression=true';
end;
FDConnection1.Connected := True;
Using a connection definition file:
[FB_Demo]
DriverID=FB
Server=...
Database=...
User_Name=...
Password=...
IBAdvanced=config=WireCompression=true
You need zlib1.dll in the same path of your fbclient.dll. The catch here is that Firebird distribution DOES NOT have the 32-bit version of zlib1.dll in its C:\Program Files\Firebird\Firebird_3_0\WOW64 folder. So:
If your application is 64-bit you are probably fine. Just use both fbclient.dll and zlib1.dll from your C:\Program Files\Firebird\Firebird_3_0 folder.
If your application is 32-bit you have to download the 32-bit version of zlib1.dll from the 32-bit Firebird distribution. Use it together with the fbclient.dll you find in your C:\Program Files\Firebird\Firebird_3_0\WOW64 (which contains 32-bit libraries).
In Firebird 3.0.4 or later you can use the WIRE_COMPRESSED context variable to check if the connection was established as you expected:
SELECT
RDB$GET_CONTEXT('SYSTEM', 'WIRE_COMPRESSED') wire_compressed
FROM
rdb$database
This will return TRUE if the current connection is compressed.

Is this a bug: stored procedure runs fine without parameters, causes error when parameters are added?

I have a stored procedure created in MySQL DB. This database is accessed as linked server through Microsoft SQL Server 2012 using Microsoft SQL Server Management Studio. The provider selected while creating linked server is "Microsoft OLE DB Provider for ODBC Drivers".
When I run following as text from Report builder 3.0 it runs fine and fetch data.
EXEC('CALL storedProcedureName(''string1'', ''string2'', ''string3'')') AT LinkedServerName;
But when I try to replace string1, string2, string3 with parameter name parameter1, parameter2, parameter3 as:
EXEC('CALL storedProcedureName(#parameter1, #parameter2, #parameter3)') AT LinkedServerName;
I get error:
Could not execute statement on remote server 'LinkedServerName'.
(Microsoft SQL Server, Error: 7215)
And when I try:
EXEC('CALL storedProcedureName('#parameter1', '#parameter2', '#parameter3')') AT LinkedServerName;
I get the prompt to enter values for parameter1, parameter2, parameter3. But when I enter the values and click ok, I get error:
Incorrect syntax near '#parameter1'. (Microsoft SQL Server, Error: 102)
Question: Am I missing something in syntax or is this a bug?
The linked server has:
"RPC" and "RPC out" set to True.
And the OLEDB provider has:
Enabled allow inprocess
Enabled dynamic parameter
I believe you have to call it like the below. So params become strings wrapped in single quotes:
EXEC('CALL storedProcedureName('''+#parameter1+''', '''+#parameter2+''', '''+#parameter3+''')') AT LinkedServerName;
I know this is an older question but the accepted answer is open to SQL Injection and I think it's important to offer a more secure method.
You really want to use a parameterized query
EXEC('CALL storedProcedureName(?,?,?)',#parameter1, #parameter2, #parameter3) AT LinkedServerName;
I know this works for oracle and it should work for MySql as well.

Open ucanaccess/jackcess database in wildfly using iso-8859-1

I have a connection to an MS Access 2000 database defined in wildfly 9.0.2. Works fine. Using the commandline UCanAccess, I run it with -Dfile.encoding=ISO-8859 in order to have national characters (Norwegian) displayed correctly, on Ubuntu. On OS X the commandline displays national characters correctly without any jre-option. However the Wildlfy instance is also running on OS X, and does not display national characters correct (currently they're just written to console in a simple test) Using UcanAccess-driver in any java-based sql client like DBeaver or SQLSquirrel "just works" when it comes to character set. However, querying the database via JPA and wildfly, the national characters are replaced with '?'.
So, there is a way to specify a praticular "opener" on the jdbc-url for Jackcess:
......mdb;jackcessOpener=ucaextension.JackcessWithCharsetISO88591Opener
where the "opener" looks like this:
public class JackcessWithCharsetISO88591Opener implements JackcessOpenerInterface {
public Database open(File f, String pwd) throws IOException {
DatabaseBuilder db = new DatabaseBuilder(f);
db.setCharset(Charset.forName("ISO-8859-1"));
try {
db.setReadOnly(false);
return db.open();
} catch (IOException e) {
db.setReadOnly(true);
return db.open();
}
}
}
(yes, the exception handling should at least issue a warning.)
So I packaged this as a jar-file (maven), removed the old connection, driver and module definitions in wildfly. Then I added this jar-file, along with the others for the ucanaccess module (ucanaccess itself, hsqldb etc), recreated the driver and connection, now with the opener-parameter, and re-reployed the war using it. But wildfly complains:
Caused by: java.lang.ClassNotFoundException: ucaextension.JackcessWithCharsetISO88591Opener from [Module "com.ucanaccess:main" from local module loader #1060b431 (finder: local module finder #612679d6 (roots: /Users/jonmartinsolaas/Local/wildfly-9.0.2.Final/modules,/Users/jonmartinsolaas/Local/wildfly-9.0.2.Final/modules/system/layers/base))]
So clearly the url-parameter has been picked up, but the class is not found, even though it is deployed along with the other jars for the driver. The class is actually in the jar-file. But do I need to reference it from any other MANIFEST.INF classpath in the other jars or something?
The case, it seems, is that various consoles doesn't show the national characters. That, and the fact that I actually have to specify charset running on the ubuntu commandline, led me to believe there was a problem, and actually displaying data in the browser and not in the logging console showed just that. No need for a jackcess "opener" for a specific character set.

What is the tADOConnection.ConnectionString in Delphi to access the Interbase server

I have a WindowsXPSP3 op system, on it a DelphiXE and InterbaseXE installed.
I created a database in IB and it works OK through the IBConsole and ISQL and connection testing also works through TCP/IP localhost:3050.
Now I try to access it from Delphi.
I did:
var AC:tADOConnection;
...
AC:=tADOConnection(Self);
AC.ConnectionString:=
AC.Open;
I tried all possible version I could google for the ConnectionString, but all generated an error. I used various Provider= versions, etc., but none works.
Could someone provide me with a simple working ConnectionString? Do I need to install any ADO driver or similar additionally?
Thanks,
Zsolt
There are two ways to easily create a valid connection string
a.1) Click on the small button in the object inspector right of the connection string property.
a.2) Create your connection, test it, press OK
or
b.1) Create an empty file e.g. 'TEST.UDL'. Use Notepad.EXE for example.
b.2) Double click on the file in the explorer. This will open the connection string editor
b.3) Create your connection, test it. Press OK
b.4) Your file now contains the connection string which you may copy&past in your application
Another benefit of the second method is that you can even use the file as a connection string. This makes life alot easier if you have to configure your connection from time to time (Just double click on the UDL if you have to change the connection properties). Here's how a valid connection string for a file looks like:
FILE NAME=<Full path to your UDL file>

Resources