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.
Related
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 :)
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
}
Can anyone please provide advice on how to enlist in an MVCC session from SSIS?
Reading from an Ingres DB, we have a requirement to enable MVCC and specify the isolation level from within an SSIS 2008 R2 package.
An existing application exists over this database, that DOES NOT use MVCC, and hence it is not appropriate to simply enable MVCC on the existing DBMS. The reason we want our reads to enlist in MVCC is to ensure we do not cause locks and break this existing application (as is currently periodically happening when we do not use MVCC to perform these reads).
DB version is Ingres II 10.0.0 (su9.us5/132)
ADO.NET driver version is Ingres.Client.IngresConnection, Ingres.Client, Version=2.1.0.0 driver,
We have a similar requirement to do so programmatically from within Tibco BusinessWorks, and interactively via eg SQL Squirrel, and meet this need by issuing the following commands via direct SQL execution (via JDBC):
SET LOCKMODE SESSION WHERE LEVEL = MVCC;
SET SESSION ISOLATION LEVEL READ COMMITTED;
In SSIS we can set the session isolation level using the IsolationLevel property of the task/sequence. But I can find no means of issuing the MVCC command directly.
I have attempted to issue the command via an Exceute SQL Task step, but I encounter the following error:
Syntax error on line 1. Last symbol read was: 'SET LOCKMODE'
What I've tried, to no avail:
With or without the terminating ;
Execute step placed within or outside of a sequence
Enabled the DelayValidation property, at both the sequence and step level
Various TransactionOption settings at the sequence and task level (in case they mattered!)
Setting the lockmode via a windows environment variable ING_SET = "SET LOCKMODE SESSION WHERE LEVEL = MVCC". But my testing shows this is not honoured by the ADO.NET driver we're using in SSIS (nor, incidentally, is it honoured by the JDBC driver we use for SQL Squirrel or Tibco). I believe this is probably an ODBC feature.
Issuing the command from within an ADO.NET source step within a dataflow. Same syntax error.
[UPDATE] Had also tried wrapping the SET ... commands in an Ingres procedure, but this resulted in syntax errors suggesting the SET ... command is not valid anywhere within a procedure.
Can anyone please provide advice on how to enlist in an MVCC session from SSIS?
At this stage (I believe) we're constrained to the ADO.NET driver, but if there's no other option that to go with ODBC then so be it.
Answering my own question here.
Two possible approaches were conceived.
1. Use a Script Component (within a Data Flow step)
From within a script component, I was able to issue the SET ... commands directly via ADO.NET.
The problem with this approach was that I wasn't able to retain the connection on which these commands had been run, for subsequent (or parallel, within the same dataflow) ADO.NET source components.
Attempting to work via a specific connection via transactions was no good, because these commands must be issued outside of an ongoing transaction.
So ultimately I had to also issue the source select from within this component, which even then is less than ideal as the subsequent destination insert operation could then not enlist in the same transaction as the source select.
The solution using this approach ended up being:
- Using MVCC, copy the data from a source view, into a temp staging table on the source system.
- Then using a transaction, read from the source staging table into the destination system.
Code looks something like this (NB had to explicitly add a reference to Ingres .NET Data Provider\v2.1\Ingres.Client.dll
/* Microsoft SQL Server Integration Services Script Component
* Write scripts using Microsoft Visual C# 2008.
* ScriptMain is the entry point class of the script.*/
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
using Ingres.Client;
using System.Collections.Generic;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
private bool debug = true;
private IDTSConnectionManager100 cm;
private IngresConnection conn;
public override void AcquireConnections(object Transaction)
{
// The connection manager used here must be configured in the Script Component editor's "Connection Managers" page.
// "Connection" is the (default) strongly typed name for the first connection added.
// In this case, it needs to be a reference to the xxxxx connection manager (by convention it should be "xxxxx_ADONET").
cm = this.Connections.Connection;
conn = (IngresConnection)cm.AcquireConnection(Transaction);
}
public override void PreExecute()
{
debugMessage("PreExecute", "Started");
base.PreExecute();
string viewName = Variables.vViewName;
IngresCommand cmdSetSessionLockMode = conn.CreateCommand();
IngresCommand cmdSetSessionIsolationLevel = conn.CreateCommand();
IngresCommand cmdReaderQuery = conn.CreateCommand();
List<string> sqlCommandStrings = new List<string>();
if (Variables.vUseIngresMVCC)
{
sqlCommandStrings.Add("SET LOCKMODE SESSION WHERE LEVEL = MVCC");
}
sqlCommandStrings.Add("SET SESSION ISOLATION LEVEL READ COMMITTED");
sqlCommandStrings.Add(String.Format("MODIFY {0}_STAGING TO TRUNCATED", viewName));
sqlCommandStrings.Add(String.Format("INSERT INTO {0}_STAGING SELECT * FROM {0}", viewName));
foreach (string sqlCommandString in sqlCommandStrings)
{
debugMessage("PreExecute", "Executing: '{0}'", sqlCommandString);
IngresCommand command = conn.CreateCommand();
command.CommandText = sqlCommandString;
int rowsAffected = command.ExecuteNonQuery();
string rowsAffectedString = rowsAffected >= 0 ? rowsAffected.ToString() : "No";
debugMessage("PreExecute", "Command executed OK, {0} rows affected.", rowsAffectedString);
}
debugMessage("PreExecute", "Finished");
}
public override void CreateNewOutputRows()
{
// SSIS requires that we output at least one row from this source script.
Output0Buffer.AddRow();
Output0Buffer.CompletedOK = true;
}
public override void PostExecute()
{
base.PostExecute();
// NB While it is "best practice" to release the connection here, doing so with an Ingres connection will cause a COM exception.
// This exception kills the SSIS BIDS designer such that you'll be unable to edit this code through that tool.
// Re-enable the following line at your own peril.
//cm.ReleaseConnection(conn);
}
private void debugMessage(string method, string messageFormat, params object[] messageArgs)
{
if (this.debug)
{
string message = string.Format(messageFormat, messageArgs);
string description = string.Format("{0}: {1}", method, message);
bool fireAgain = true;
this.ComponentMetaData.FireInformation(0, this.ComponentMetaData.Name, description, "", 0, ref fireAgain);
}
}
}
Answering my own question here.
Two possible approaches were conceived.
2. Set up a dedicated MVCC-enabled process of the Ingres DBMS over the existing database, and connect via this
This is the approach we're currently pursuing (as it is supported, and ideally transparent). I will update with details once they are known.
I have two databases with the same schema inside a Sql 2008 R2 Server, of which names are Database1 and Database2. I connected and performed queries on the Database1, and then changed to Database2 to fetch my entities using the following code
this.ConnectionString = "Server=TestServer; Database=Database2;Trusted_Connection=true";
using (IDataAccessAdapter adapter = new DataAccessAdapter(this.ConnectionString))
{
var entities = new EntityCollection<T>();
adapter.FetchEntityCollection(entities, null);
return entities;
}
(The connection string was set before executing the code).
I debugged the application and looked at the value of the connection string, it pointed to the Database2.
However, when I executed the above code, the result was return from the Database1. And if I looked at SQL Profiler, the statement was executed against Database1.
So, could anyone know what was going on? Why the query was executed against the Database1, not Database2.
PS: If I used the above connection string with plain ADO.NET, I was able to retrieve data from Database2.
Thanks in advance.
I have figured out what was going on. The reason was: by default LLBL Gen Pro uses fully qualified names like [database1].[dbo].[Customer] to access database objects, and the catalog is specified when generating entities. So you can't access objects just by changing the connection string.
Hence, to change to another database you have to override the default catalogue by using following code
var adapter= new DataAccessAdapter(ConnectionString, false,
CatalogNameUsage.ForceName, DbName)
{CommandTimeOut = TenMinutesTimeOut};
More information can be found at the following link
I'm trying to get my MVC3 application to use MySql database instead of Sql Server 2008. I have created the associated database and objects in Mysql. And Updated the connection string in my web.config file to reference MySql.Data.MySqlClient.
When I run my application and try to login, I am getting the error
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
I have a custom MembershipProvider and within the validation process I have the following
using (MyContext context= new MyContext())
{
--some checks here
---
if (verificationSucceeded)
{
user.passwordFailuresSinceLastSuccess = 0;
}
else
{
int failures = user.passwordFailuresSinceLastSuccess;
if (failures != -1)
{
user.passwordFailuresSinceLastSuccess += 1;
user.lastPasswordFailureDate = DateTime.UtcNow;
}
}
context.SaveChanges(); ----THIS IS WHERE IT FALLS OVER
-- some other code here
}
The above code works perfectly well with Sql Server 2008, but is falling over only with MySql. Any idea how I can resolve this please?
I do not have any triggers defined on the underlying table btw. The application is MVC3 with EF Code First.
Thanks,
If anybody else is having this issue, the problem was with the Guid as I though. To get over this, add the following to your connection string
Old Guids=true
So for example, my connection string looks like this now.
<add name="MyDB" connectionString="Server=localhost; Database=mydatabase; Uid=user; Pwd=mypass; Old Guids=true;" providerName="MySql.Data.MySqlClient" />