JDBC setQueryTimeout not working? - sql-server-2008

I'm querying MSSQL 2008 server thourgh JAVA, using the JDBC driver.
I do something like this:
PreparedStatement stmt = ...;
...
stmt.setQueryTimeout(60);
stmt.executeQuery();
I see that when there's a load on the SQL server, the statement doesn't get cancelled even though the timeout has passed.
Does anyone have a clue about this?
Thanks.

The timing for setQueryTimeout is not precise at all
The exception relies on the server acknowledging the cancel command
So, YMMV unfortunately...
References: (can't find anything better, sorry)
http://social.msdn.microsoft.com/Forums/en-US/sqldataaccess/thread/06bea9b9-78cb-4d1b-8c12-5f06ed991cac/
http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-jdbc/1017/setQueryTimeout-not-work

Related

Is there a conflict in MSQL & MySQL/PDO connections? [duplicate]

This is my PHP SQL statement and it's returning false while var dumping
$sql = $dbh->prepare('INSERT INTO users(full_name, e_mail, username, password) VALUES (:fullname, :email, :username, :password)');
$result = $sql->execute(array(
':fullname' => $_GET['fullname'],
':email' => $_GET['email'],
':username' => $_GET['username'],
':password' => $password_hash));
TL;DR
Always have set PDO::ATTR_ERRMODE to PDO::ERRMODE_EXCEPTION in your PDO connection code. It will let the database tell you what the actual problem is, be it with query, server, database or whatever. Also, make sure you can see PHP errors in general.
Always replace every PHP variable in the SQL query with a question mark, and execute the query using prepared statement. It will help to avoid syntax errors of all sorts.
Explanation
Sometimes your PDO code produces an error like Call to a member function execute() or similar. Or even without any error but the query doesn't work all the same. It means that your query failed to execute.
Every time a query fails, MySQL has an error message that explains the reason. Unfortunately, by default such errors are not transferred to PHP, and all you have is a silence or a cryptic error message mentioned above. Hence it is very important to configure PHP and PDO to report you MySQL errors. And once you get the error message, it will be a no-brainer to fix the issue.
In order to get the detailed information about the problem, either put the following line in your code right after connect
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
(where $dbh is the name of your PDO instance variable) or - better - add this parameter as a connection option. After that all database errors will be translated into PDO exceptions which, if left alone, would act just as regular PHP errors.
After getting the error message, you have to read and comprehend it. It sounds too obvious, but learners often overlook the meaning of the error message. Yet most of time it explains the problem pretty straightforward:
Say, if it says that a particular table doesn't exist, you have to check spelling, typos, letter case. Also you have to make sure that your PHP script connects to a correct database
Or, if it says there is an error in the SQL syntax, then you have to examine your SQL. And the problem spot is right before the query part cited in the error message.
You have to also trust the error message. If it says that number of tokens doesn't match the number of bound variables then it is so. Same goes for absent tables or columns. Given the choice, whether it's your own mistake or the error message is wrong, always stick to the former. Again it sounds condescending, but hundreds of questions on this very site prove this advice extremely useful.
Note that in order to see PDO errors, you have to be able to see PHP errors in general. To do so, you have to configure PHP depends on the site environment:
on a development server it is very handy to have errors right on the screen, for which displaying errors have to be turned on:
error_reporting(E_ALL);
ini_set('display_errors',1);
while on a live site, all errors have to be logged, but never shown to the client. For this, configure PHP this way:
error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
Note that error_reporting should be set to E_ALL all the time.
Also note that despite the common delusion, no try-catch have to be used for the error reporting. PHP will report you PDO errors already, and in a way better form. An uncaught exception is very good for development, yet if you want to show a customized error page, still don't use try catch for this, but just set a custom error handler. In a nutshell, you don't have to treat PDO errors as something special but regard them as any other error in your code.
P.S.
Sometimes there is no error but no results either. Then it means, there is no data to match your criteria. So you have to admit this fact, even if you can swear the data and the criteria are all right. They are not. You have to check them again. I've short answer that would help you to pinpoint the matching issue, Having issue with matching rows in the database using PDO. Just follow this instruction, and the linked tutorial step by step and either have your problem solved or have an answerable question for Stack Overflow.
Some time ago I had the same problem of not seeing any error messages from mysql. After a research it turned out that the problem has got nothing to do with PHP itself, but with mysql server configuration. The default value of the variable lc_messages_dir pointed to non existing directory. After adding a line in mysqld.cnf, then restarted the mysql server, and finally I was able to see the error messages. For me the following was the right one:
lc_messages_dir=/usr/share/mysql
It is described in the mysql reference manual: https://dev.mysql.com/doc/refman/5.7/en/error-message-language.html

How to Close a Connection When Using Jupyter SQL Magic?

I'm using SQL Magic to connect to a db2 instance. However, I can't seem to find the syntax anywhere on how to close the connection when I'm done querying the database.
you cannot explicitly close a connection using Jupyter SQL Magic. In fact, that is one of the shortcoming of using Jupyter SQL Magic to connect to DB2. You need to close your session to close the Db2 connection. Hope this helps.
This probably isn't very useful, and to the extent it is it's probably not guaranteed to work in the future. But if you need a really hackish way to close the connection, I was able to do it this way (for a postgres db, I assume it's similar for db2):
In[87]: connections = %sql -l
Out[87]: {'postgresql://ngd#node1:5432/graph': <sql.connection.Connection at 0x7effdbcf6b38>}
In[88]: conn = connections['postgresql://ngd#node1:5432/graph']
In[89]: conn.session.close()
In[90]: %sql SELECT 1
...
StatementError: (sqlalchemy.exc.ResourceClosedError) This Connection is closed
[SQL: SELECT 1]
[parameters: [{'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__s ... (123202 characters truncated) ... stgresql://ngd#node1:5432/graph']", '_i28': "conn = connections['postgresql://ngd#node1:5432/graph']\nconn.session.close()", '_i29': '%sql SELECT 1'}]]
A big problem is--if you want to reconnect, that doesn't seem to work. Even after running %reload_ext sql, and trying to connect again, it still thinks the connection is closed when you try to use it. So unless someone knows how to fix that behavior, this is only useful for disconnecting if you don't want to re-connect again (to the same db with the same params) before restarting the kernel.
You can also restart the kernel.
This is the most simple way I've found to close all connections at the end of the session. You must restart the kernel to be able to re-establish the connection.
connections = %sql -l
[c.session.close() for c in connections.values()]
sorry for being to late but I've just started with working with SQL Magic and got annoyed with the constant errors appearing. It's a bit of a awkward patch but this helped me use it.
def multiline_qry(qry):
try:
%sql {qry}
except Exception as ex:
if str(type(ex).__name__) != 'ResourceClosedError':
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print (message)
qry = '''DROP TABLE IF EXISTS EMPLOYEE;
CREATE TABLE EMPLOYEE(firstname varchar(50),lastname varchar(50));
INSERT INTO EMPLOYEE VALUES('Tom','Mitchell'),('Jack','Ryan');
'''
multiline_qry(qry)
log out the notebook first if you want to close the connection.

Using both Hive and MySql JDBC drivers

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
}

Calling MySQL stored procedure in ROR 4

There are few example out there but non of them are very clarified (or on old version).
I want to call MySQL procedure and check the return status (in rails 4.2). The most common method I saw is to call result = ActiveRecord::Base.connection.execute("call example_proc()"), but in some places people wrote there is prepared method result = ActiveRecord::Base.connection.execute_procedure("Stored Procedure Name", arg1, arg2) (however it didn't compiled).
So what is the correct way to call and get the status for MySQL procedure?
Edit:
And how to send parameters safly, where the first parameter is integer, second string and third boolean?
Rails 4 ActiveRecord::Base doesn't support execute_procedure method, though result = ActiveRecord::Base.connection still works. ie
result = ActiveRecord::Base.connection.execute("call example_proc('#{arg1}','#{arg2}')")
You can try Vishnu approach below
or
You can also try
ActiveRecord::Base.connections.exec_query("call example_proc('#{arg1}','#{arg2}')")
here is the document
In general, you should be able to call stored procedures in a regular where or select method for a given model:
YourModel.where("YOUR_PROC(?, ?)", var1, var2)
As for your comment "Bottom line I want the most correct approach with procedure validation afterwards (for warnings and errors)", I guess it always depends on what you actually want to implement and how readable you want your code to be.
For example, if you want to return rows of YourModel attributes, then it probably would be better if you use the above statement with where method. On the other hand, if you write some sql adapter then you might want to go down to the ActiveRecord::Base.connection.execute level.
BTW, there is something about stored proc performance that should be mentioned here. In several databases, database does stored proc optimization on the first run of the stored proc. However, the parameters that you pass to that first run might not be those that will be running on it more frequently later on. As a result, your stored-proc might be auto-optimized in a "none-optimal" way for your case. It may or may not happen this way, but it is something that you should consider while using stored procs with dynamic params.
I believe you have tried many other solutions and got some or other errors mostly "out of sync" or "closed connection" errors. These errors occur every SECOND time you try to execute the queries. We need to workaround like the connection is new every time to overcome this. Here is my solution that didn't throw any errors.
#checkout a connection for Model
conn = ModelName.connection_pool.checkout
#use the new connection to execute the query
#records = conn.execute("call proc_name('params')")
#checkout the connection
ModelName.connection_pool.checkin(conn)
The other approaches failed for me, possibly because ActiveRecord connections are automatically handled to checkout and checking for each thread. When our method tries to checkout a connection just to execute the SP, it might conflict since there will be an active connection just when the method started.
So the idea is to manually #checkout a connection for the model instead of for thread/function from the pool and #checkin once the work is done. This worked great for me.

Autohotkey close database connection

I have made a script using the following library;
http://www.autohotkey.com/board/topic/72629-mysql-library-functions/
to connect to my non-local database. However I'm issuing some max_user_connections problems and I think this is due to the fact that I never close the database connection.
I can't seem to find a way to do that using this library but I am not certain, maybe theres a way to close any connection to the internet or any database or whatever that would work build-in in AHK?
Script:
hi() {
mysql := new mysql
db := mysql.connect("x","x","x","x") ; host,user,password,database
if db =
return
sql =
(
UPDATE something
SET yo = yo+1
WHERE id = 1
)
result := mysql.query(db, sql)
}
Thanks in advance
The DLL of the AHK script has the mysql_close function, but it's not coded into the AHK library.
You can technically manually call the DLL just like the AHK and see if it'll work.
Since I also need to connect to a MySQL DB via AHK, I'll update this answer when a full solution is available.