I allow myself to post my problem, having been looking for the solution for more than two hours, without finding the least solution.
Context: I want to connect to an Access database thanks to the PHP PDO. For that, I have the following code:
public function connect () {
$this->dsn = 'odbc:Driver={Microsoft Access Driver (*.mdb)};charset=UTF-8;Dbq='.$this->dbway.';Uid=;Pwd=;';
$this->user = '';
$this->password = '';
try {
$this->pdo = new PDO($this->dsn, $this->user, $this->password);
die("'eee");
}catch (\PDOException $e) {
die('Error : ' . $e->getMessage());
}
}
$this->dbway = absolute path to the .mdb database
When i try this, i've this response :
Error : : SQLSTATE[IM002] SQLDriverConnect: 0 [Microsoft][Gestionnaire de pilotes ODBC] Source de donnΘes introuvable et nom de pilote non spΘcifiΘ
Obviously, I tried to find the solution by searching the internet before.
I checked in the administration of ODBC data sources, in the "system data sources", I have:
Name: Microsoft Access Driver
Platform: 32 bits
Driver: Microsoft Access Driver (* .mdb)
So I tried to add the same thing in the user odbc data sources, without success.
I also tried to add the Microsoft Access Driver (* .mdb, * .accdb), which always returns the same error.
Moreover, I checked in php.ini and phpForApache.ini that extension = php_odbc.dll and extension = php_pdo_odbc.dll are really active in PHP extensions, and that's the case
I admit I do not know where to look, and where my concern might come from.
Knowing that the database is present, and that in the ODBC data sources, I see the driver in question, I do not understand why I still can not conquer me.
Thanks to those who will take the time to read me,
have a good day :)
Related
I'm trying to connect to a test database I created for far too long and I finally decided to come for help. I am using F#, Visual Studio Community 2017 and MySQL Database. The server is local (Wamp).
I have this for now:
#r "\...\packages\SQLProvider.1.1.8\lib\FSharp.Data.SqlProvider.dll"
open FSharp.Data.Sql
open FSharp.Data.Sql.Providers
open System.Collections.Generic
open System
[<Literal>]
let connString = "Server=localhost; Database=test1; Uid=root"
let resPath = __SOURCE_DIRECTORY__ + #"..\packages\MySql.Data.8.0.8-dmr\lib\net452"
type sql = SqlDataProvider<
Common.DatabaseProviderTypes.MYSQL,
connString,
ResolutionPath = resPath,
UseOptionTypes = true>
let db = sql.GetDataContext()
And I can't make it work.. 'resPath' gives the error "This is not a valid constant expression or custom attribute value". If I insert a literal '[]' in front of it (see it below), it gives another error: "Strong name validation failed. (Exception from HRESULT: 0x8013141A)".
let [<Literal>] resPath = __SOURCE_DIRECTORY__ + #"..\packages\MySql.Data.8.0.8-dmr\lib\net452"
After connection with the db I want to add information in it and analyze the data of it using F# still.
I don't know what else should I try. All packages are updated, I installed everything through the NuGet package manager and they are all in the references.. I appreciate any ideas / suggestions.
Thank a lot.
SqlDataProvider is a type provider, which means that it contains code that runs at compile time so that it can generate types for you to use at compile time. All parameters to type providers have to be constants that are known at compile time. This is why resPath needs to be a "literal" (effectively the same thing as a compile time constant).
__SOURCE_DIRECTORY__ doesn't have a trailing backslash so you need to add that:
let [<Literal>] resPath = __SOURCE_DIRECTORY__ + #"\..\packages\MySql.Data.8.0.8-dmr\lib\net452"
With this in place I was able to reproduce your Strong name validation failed error. Switching to v6.9.9 (marked as the current version) of MySql.Data fixed that for me.
TL;DR:
Is it problematic to use both Hive and MySql JDBC together?
I'm working on an application that performs several SQL queries using the MySql JDBC driver and afterwards it also send another Hive query using Hive JDBC.
Now whats happening is that the MySql queries are working properly, when the code tries to execute the Hive query it throws this exception:
com.mysql.cj.core.exceptions.WrongArgumentException: Connector/J cannot handle a database URL of type 'jdbc:hive2:'.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.cj.core.exceptions.ExceptionFactory.createException(ExceptionFactory.java:54)
at com.mysql.cj.core.conf.url.ConnectionUrl$Type.fromValue(ConnectionUrl.java:149)
at com.mysql.cj.core.conf.url.ConnectionUrl.getConnectionUrlInstance(ConnectionUrl.java:193)
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:195)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at company.services.HiveV2Provider.createConnection(HiveProvider.scala:105)
at company.services.HiveProvider$class.loanConnection(HiveProvider.scala:66)
Now after this exception is thrown the query is executed properly.
My guess is that since I'm loading both the MySql and Hive drivers, the MySql driver is trying to run this query first but when it encounters the Hive URL it throws this exception and then the Hive driver sees it and executes the query properly
This is how I execute the MySql code:
val query = ... // query is created here
var mysqlConn: Connection = null
var stmt: Statement = null
try {
Class.forName("com.mysql.jdbc.Driver")
mysqlConn = DriverManager.getConnection(mysqlAddress, username, password)
stmt = mysqlConn.createStatement()
val rs = stmt.executeQuery(query)
val returnVal = someResultSetHandlingFunction(rs)
rs.close()
returnVal
} catch {
case NonFatal(e) =>
logWarning(s"Failed to execute query on: $mysqlAddress", e)
throw e
} finally {
if (mysqlConn != null) {
mysqlConn.close()
}
}
My Hive code looks the same only with a driver name of: org.apache.hive.jdbc.HiveDriver (and it communicates with jdbc:hive2://someurl)
Versions:
Hive is hive-jdbc-1.1.0-cdh5.7.1
MySql is mysql-connector-java 6.0.4
Does anybody know if there's any way to avoid receiving this exception? Is it problematic to load 2 different JDBC drivers? Reading in other somewhat similar questions I get the impression that this should not be a problem
Just a few clarifications:
I know its probably not the best thing to use JDBC directly but I'm checking something and JDBC is fine for this task
I'm using Scala but I don't think it matters for this issue
Thanks in advance
I almost forgot to answer my question
So the issue is probably related to this bug. Back when I was facing this issue I didn't notice it was just a stack trace print and not an actual failure so it was less problematic than I expected.
Anyway, I then saw that in some specific versions this issue was fixed as you can see here so I just changed my mysql version to 5.1.9 (because I didn't need the higher version for anything specific) and the stack trace failure was gone.
I'll be happy if to hear if someone has a more elegant solution to this
Cheers
I was facing the same issue with MS SQL Server JDBC Driver. The same error was logged but everything worked fine.
According to this Microsoft page:
In the JDBC API 4.0, the DriverManager.getConnection method is
enhanced to load JDBC drivers automatically. Therefore, applications
do not need to call the Class.forName method to register or load the
driver when using the sqljdbc4.jar, sqljdbc41.jar, or sqljdbc42.jar
class library.
So I tried removing the Class.forName and just called DriverManager.getConnection. Things are just working and I'm not getting the annoying error anymore.
I believe the Driver itself must include a "META-INF/services/java.sql.Driver" file that registers itself as a valid JDBC driver, so not necessarily it will work for you, but to SQL Server Driver users it's the way to go.
BTW: I noticed that DriverManager.getConnection takes significant more time (6 or 7 seconds) to load the Drive the first time it's called. Subsequent calls are OK. Depending on your application it may be an issue.
Class.forName("com.mysql.jdbc.Driver")
will register your JDBC driver in the DriverManager. Then you put hive connection uri in
DriverManager.getConnection(mysqlAddress, username, password)
Exception is expected in this case.
Why don't you delegate the call to particular JDBC driver after checking uri like:
if (uri.contains("hive")){
//call Hive JDBC
}
else if (uri.contains("mysql")){
//call Mysql JDBC
}
I am trying to connect to an access .accdb database using a 32 activeX object in CVI 9.0.1. I am able to connect just fine to a .mdb file, but when I try .accdb the function goes through just fine, but connectFlag returns a 0 indicating it failed to connect to the file. I am able to use the exact same code in WindowsXP, and it works just fine for both .accdb and .mdb files. I have verified that the access drivers do exist in C:\Windows\SysWOW64\odbcad32.exe
Microsoft Accees Driver (*.mdb, *.accdb) version 14.00.7010.1000
I am also able to connect to the same database on my windows 7 machine using Visual Studio 2010. I also downloaded a trial of CVI SqlTool Kit, and was able to connect to the .accdb database using a DSN. I have also downloaded a copy of CVI 2013 thinking maybe my version only running in 32-bit and not able to see the SysWOW64 folder, however I got the same results in CVI 2013.
I have included the code below....
HRESULT result = 0;
ERRORINFO errorStruct;
char * dbPtr = NULL;
char * SQLptr = NULL;
char * record = NULL;
VBOOL connectFlag;
CAObjHandle databaseObj = 0;
// database connection strings
char dbLocation[] = "DSN=test" ;
char dbLocation[] = "c:\\obsoleteparts.mdb" ;
char dbLocation[] = "c:\\serialnumbers.accdb" ;
char sqlStr[]= "SELECT tblSerialNumbers.serialNumber FROM(tblSerialNumbers) WHERE tblSerialNumbers.prefix='05-' ORDER BY tblSerialNumbers.serialNumber DESC";
prjAxDatabaseObj__Recordset rsObj;
dbPtr = dbLocation;
SQLptr = sqlStr;
errorTxt[0] = 0;
result = prjAxDatabase_New_axDatabase (NULL, 1, LOCALE_NEUTRAL, 0,&databaseObj );
result = prjAxDatabase__axDatabaseConnect (databaseObj, &errorStruct, &dbPtr, &connectFlag);
CA_DisplayErrorInfo (databaseObj,"error",result,&errorStruct)
Code runs just fine, does not display an error, result shows that the operation was a success, however the connectFlag returns a 0 meaning it did not connect. Any suggestions would be much appreciated thanks.
-Justin
Regarding my comment above, I used the following connect strings (when not using DSNs) for all CVI versions:
//giAmsIndex = DBConnect ("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\dev\\DB\\New_AMS_Index.accdb");
//giAmsData = DBConnect (""Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\dev\\DB\\New_AMS_000");
and the following when using DSNs:
hAmsIndex = DBConnect ("DSN=New_AMS_Index");
hAmsData = DBConnect ("DSN=New_AMS_000");
But as I said in the comment, your problem description suggests UAC issues having to do with MS Access.
I have to do some maintenance on a software that was delivered to a customer.
This software is using database and in order to do some debugging session on my computer, I had to install SQL server 2008 R2 and the two database (MyData and MyRecord) that are used by this software.
I had some troubles doing the setting (login, mapping of the database to sa user) but I managed to go over those issues.
Now I am trying to run the software but it crashes during initialization when it tries to open a recordset.
At first I do the following to connect to the database :
::CoInitialize(NULL);
try
{
HRESULT hr = pConnection.CreateInstance("ADODB.Connection");
if (SUCCEEDED(hr))
{
pConnection->ConnectionTimeout = 0;
CString strConnect;
strConnect.Format(_T("Data Source=MyRecord;uid=sa;pwd=sa123456;"));
hr = pConnection->Open((_bstr_t)strConnect,"","", -1);
}
}
with pConnection defined as :
_ConnectionPtr pConnection;
After that, I am trying to read some data from the database "MyRecord" with the following code :
CString sqlQuery = _T("select * from 通道1设置参数表");
try
{
pRecordset.CreateInstance(_uuidof(Recordset));
pRecordset->Open(_bstr_t(sqlQuery ),pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
}
catch(_com_error *e)
{
AfxMessageBox(e->Description());
}
with pRecordSet defined as :
_RecordsetPtr pRecordset;
When the line "pRecordset->Open(...)" is run, the software crashes in the function Recordset15::Open(...) of the msado15.tli file.
In this Recordset15::Open function, the raw_Open(...) function returns DB_E_NOTABLE.
However, I am sure that the table dbo.通道1设置参数表 exists in MyRecord database.
The error is :
I don't know if the problem lies in the SQL server configuration or in the code.
This code works perfectly well on the customer's PC so I would go with a configuration problem.
Thanks in advance !!
In the ODBC connector for this database, the setting "Change the default database to" was not set to the MyRecord database.
I have ticked the check-box, selected the database and now it is working correctly.
Your catch statement should be catch(_com_error & e)
MFC often throws exceptions by pointers, however _com_error is a reference.
I am not able to call setNull on PreparedStatement using MS Access (sun.jdbc.odbc.JdbcOdbcDriver)
preparedStatement.setNull(index, sqltype).
Is there a workaround for this? For LONGBINARY data type, I tried the following calls, neither worked.
setNull(index, java.sql.Types.VARBINARY)
setNull(index, java.sql.Types.BINARY)
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]Invalid SQL data type
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6957)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114)
at sun.jdbc.odbc.JdbcOdbc.SQLBindInParameterNull(JdbcOdbc.java:986)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.setNull(JdbcOdbcPreparedStatement.java:363)
The answer that I have observed to work "quite well" for binding null to most data types with JDBC 4.1, Java 7, MS Access 2013 and the JDBC-ODBC bridge is this one, which I've built into jOOQ:
switch (sqlType) {
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
case Types.BLOB:
stmt.setNull(nextIndex(), Types.VARCHAR);
break;
default:
stmt.setString(nextIndex(), null);
break;
}
I just tested this and for an OLE Object (LONGBINARY) field in an Access 2010 database I found that all five of these variations allowed me to specify a null value as the parameter to a PreparedStatement using vanilla JDBC/ODBC Driver={Microsoft Access Driver (*.mdb, *.accdb)}:
s.setNull(4, java.sql.Types.LONGNVARCHAR);
s.setNull(4, java.sql.Types.LONGVARCHAR);
s.setNull(4, java.sql.Types.NCHAR);
s.setNull(4, java.sql.Types.NVARCHAR);
s.setNull(4, java.sql.Types.VARCHAR);
It is particularly interesting that
s.setNull(4, java.sql.Types.LONGVARBINARY);
does not work, considering that when we retrieve an OLE Object from an Access database what we get is a java.sql.Types.LONGVARBINARY according to a ResultSetMetaData object:
String SQL;
SQL = "SELECT Photo FROM City WHERE City_ID = 12";
s = conn.createStatement();
s.executeQuery(SQL);
ResultSet rs = s.getResultSet();
ResultSetMetaData rsmd = rs.getMetaData();
String accessTypeName = rsmd.getColumnTypeName(1);
int javaType = rsmd.getColumnType(1);
String javaTypeName = (
javaType == java.sql.Types.LONGVARBINARY
? "java.sql.Types.LONGVARBINARY"
: "some other Type"
);
System.out.println(String.format("The database-specific type name for this column is '%s'", accessTypeName));
System.out.println(String.format("The SQL type for this column is: %d (%s)", javaType, javaTypeName));
That returns:
The database-specific type name for this column is 'LONGBINARY'
The SQL type for this column is: -4 (java.sql.Types.LONGVARBINARY)
The Wikipedia article on ODBC includes a history suggesting that after an earlier effort ("SQL/CLI") became part of the ISO SQL standard, Microsoft essentially forked their own version and eventually came up with ODBC. If that is the case, then early efforts to conform to an "ODBC 'standard'" may have faced the same difficulties as those trying to conform to Microsoft's RTF document "standard": the "standard" was whatever Microsoft implemented and was subject to change at Microsoft's sole discretion.
However, Microsoft's 1995 ODBC White Paper, available via the download link here, consistently refers to the "OLE Object" datatype as mapping to "*BINARY" or "raw" types (or, in the case of SQL Server, to the now-deprecated IMAGE datatype). So, the CHAR/BINARY discrepancy doesn't appear to be a case of some early ODBC quirk that just got perpetuated.
Certainly this mystery is not new. A forum thread here from ~11 years ago suggests that this issue arose when something changed after JDK 1.4 was released.
And finally, Oracle has stated that the JDBC-ODBC Bridge "will be removed in JDK 8" (ref: here). So, if there hasn't been an "official" explanation (or a fix, for that matter), it is becoming increasingly unlikely that any will be forthcoming.
I saw a similar error once when I was sending a SQL query with 2 conditions in the where clause. One of the conditions needed to be quoted. It was a number in varchar format. The MSSQL server required that the condition be quoted or else I saw the error You got in your question.