Finding MySQL status statistics in Java App - java

In my Java app, I want to query the MySQL status statistics. I'm adding some simple monitoring (mostly writing alerts when certain settings reach certain thresholds).
In any case, I can't get it working using standard JDBC code. I want something like this:
ResultSet s = DBUtil.executeQuery("SHOW STATUS LIKE '%conn%'");
But this isn't working from what I see in the debugger. Any solutions?

Thanks for the link to the documentation. It helped clear up some confusion.
For the record, here's how I navigated the ResultSet properly to find the values I wanted...
String sql = "SHOW GLOBAL STATUS LIKE '%conn%'";
ResultSet rs = null;
try
{
rs = DBUtil.executeQuery(stmt, sql);
while (rs != null && rs.next())
{
if (StringUtils.equals(rs.getString(1), "Max_used_connections"))
return rs.getString(2);
}
}
catch (Exception e)
{
throw e;
}

Related

Willena sqlite jdbc cannot open SqlCipher db

I am trying to figure out how to encrypt a sqlite database in non-android java.
It does not seem to be super straight forward, but I Willena jdbc crypt which does seem to be able to create an encrypted database, but I simply cannot figure out how to access a SQLCipher 4 encrypted database with it.
Here is my code.
String path = "jdbc:sqlite:C:\\Users\\User1\\Desktop\\testServer232.db";
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection(path+"?cipher=sqlcipher&key=a");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
statement.executeUpdate("drop table if exists person");
statement.executeUpdate("create table person (id integer, name string)");
statement.executeUpdate("insert into person values(3, 'leo1')");
statement.executeUpdate("insert into person values(4, 'yui1')");
ResultSet rs = statement.executeQuery("select * from person");
while(rs.next())
{
// read the result set
System.out.println("name = " + rs.getString("name"));
System.out.println("id = " + rs.getInt("id"));
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
try
{
if(connection != null)
connection.close();
}
catch(SQLException e)
{
// connection close failed.
System.err.println(e.getMessage());
}
}
This code does work, but I don't think that it produces a SqlCipher 4 encrypted database. When I try to open it with DB browser for Sqlite, it does not allow me access when I put the password = a.
Where am I going wrong?
Ok, so I ended up finding the creator of the repository. And he solved it easily and answered really fast.
Here is the solution:
Here are a few things that could be tested:
Use version 3.31.1
Try to do the database connection using "jdbc:sqlite:file:C:\Users\User1\Desktop\test.db?cipher=sqlcipher&key=password123"as URI (notice the added "file:").
Try to add the legacy parameter for SQLCipher as available here (https://github.com/Willena/sqlite-jdbc-crypt#aes-256-bit-cbc---sha1sha256sha512-hmac-sqlcipher). The URI will become something like this: "cipher=sqlcipher&key=password123&legacy=4"
This is now working for me. I recommend that others use it if they are interested in an easy way to do sqlcipher version 4 similarly to how it is done in an android project.

MySql Connector SQL Statement does not return any values under java

I am using mySQL Connector in java and I need to write this long query where I join tables and return stocks of particular user. User_ID would be supplied by the java program hence i got ? and passed into the database. However I assume due to syntax error in java it does not return any values to program and simply fails. Query works perfectly in database.
String a = jTextField_User_Name.getText();
PreparedStatement ps = null;
String queryretrive = "SELECT DISTINCT Stock_Name FROM stockname,users,stock,userstock WHERE 'users.ID' = ? AND users.ID = userstock.User_ID AND userstock.Stock_ID = stock.Stock_ID AND stock.Stock_ID = stockname.Stock_ID";
ResultSet rs;
try {
ps = MyConnector.getConnection().prepareStatement(queryretrive);
ps.setString(1,a);
rs = ps.executeQuery();
if(rs.next())
{
System.out.println(rs.getString("Stock_Name"));
}else{
JOptionPane.showMessageDialog(null, "Error");
}
} catch (SQLException ex) {
Logger.getLogger(LoginForm.class.getName()).log(Level.SEVERE, null, ex);
}
Thanks.
WHERE 'users.ID' = ? AND users.ID =
Obviously, the second reference to users.ID doesn't need to be quoted, so why did you attempt to quote the first one?
Anyway, in MySQL " and ' are used to quote string literals and ` (backtick) is used to quote identifiers. If ANSI_QUOTES SQL mode is enabled, then " is used to quote identifiers, like other DBMS dialects do.
If you do need to quote, you need to quote each part separately, so the correct quoting would be `users`.`ID` or "users"."ID".
The fact that ' sometimes work for quoting identifiers is just weird lenient behavior and shouldn't be used, since it easily confused with string literals. Don't even know how MySQL decides whether it's a string literal or an identifier, so it's best to never do it.
this query is not long but this is hard to understand without your data model and code example.
if this is working in MySQLWorkBench should works from java. If this is not working from java you have poor error handling, or you haven't set properly parameter.
'users.ID' may be just users.ID
remove try/catch for testing purpose or handle this catch.
BTW.
With java/mysql ALWAYS handle finally to free connection, something like :
finally
{
try {if (rs != null) rs.close();} catch(Exception e) {}
try {if (statement != null) statement.close();} catch(Exception e) {}
}

SQL using XMLAGG function is not retrieving results while executing in Java

I have been trying to execute an Oracle SQL query using java program through JDBC connectivity.
In the SQL query, I am using XMLAGG function.
Below is the sample of the query that is similar to what I use:
SELECT XMLAGG(XMLELEMENT(E,ename||',')).EXTRACT('//text()') "Result" FROM `employee_names`
The result is supposed to be as shown below:
Result
-------------------------------------------------------------------
SMITH,ALLEN,WARD,JONES,MARTIN,BLAKE,CLARK,SCOTT,KING,TURNER,ADAMS
When I execute this query using a Java program, I am getting null for that column value.
If anyone faced similar issue and resolved it, please let me know the solution.
Thanks
Marshal
XMLAGG returns an aggregated XML document. Did your program use xdb6.jar to parse the document? If not, then retrieval would have hit into XMLParseException when XML document is retrieved as string.
The best workaround would be to use getstringval() method of XMLAGG to retrieve the values as string.
So, your updated query string will look like the following:
String qry = "SELECT XMLAGG(XMLELEMENT(E,ename||',')).EXTRACT('//text()').getstringval()" +
" FROM employee_names";
Following sample program worked fine at my end:
import java.sql.*;
public class XMLAggTest {
public static void main(String[] args) {
try {
Connection con=null;
Class.forName("oracle.jdbc.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:hr/hr#myhost:1521:bct01");
if(con != null)
{
String upq="SELECT XMLAGG(XMLELEMENT(E,first_name||',')).EXTRACT('//text()').getstringval()" +
" FROM employees";
PreparedStatement pStat;
try {
pStat = con.prepareStatement(upq);
ResultSet rSet = pStat.executeQuery();
while(rSet.next()){
System.out.println(rSet.getString(1));
}
rSet = null;
} catch (SQLException e) {
e.printStackTrace();
}
pStat = null;
}
con.close();
} catch(Exception e){e.printStackTrace();}
}
}

Unable to figure out JDBC ClassNotFoundException (JTDS driver)

So a little background on my problem: I am trying to copy over a table on an Microsoft SQL system from an Oracle database. Besides giving password and user access to the table I cannot edit or do anything to the MSSQL database.
I successfully used the Oracle SQL Developer to connect and view the tables I want (using a third party JDBC driver), but I want to set up an automated copy-over into my Oracle database so I am attempting to use the same driver in some stored java code.
I have a java function that all it should do is go and count the number of entries in the table. So far my code looks like:
public static String getCount() {
Statement stmt = null;
Connection conn = null;
int rowCount = 0;
String message = "";
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
}
catch(ClassNotFoundException e) {
System.err.println("Error loading driver: " + e);
message = message + e + " -ER1 \n";
}
try {
conn = DriverManager.getConnection("jdbc:jtds:sqlserver://site.school.edu:2000/ACCESS", "user", "password");
stmt = conn.createStatement();
String strSelect = "select 1 as field;";
ResultSet rset = stmt.executeQuery(strSelect);
while (rset.next()) {
++rowCount;
}
}
catch(SQLException ex) {
ex.printStackTrace();
message = message + ex.getSQLState() + " -ER2";
}
finally {
try {
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch(SQLException ex) {
ex.printStackTrace();
message = message + ex.getSQLState() + "-ER3";
}
}
return message;
}
Which is being calling from a stored function :
CREATE OR REPLACE function Schema.java_testMessage return varchar2
as language java
name 'ConnectAndQuery.getCount() return java.lang.String';
Which I am calling from a script in TOAD:
set serveroutput on;
declare
words varchar2(400);
begin
words := KSL_ADMIN.java_testMessage;
dbms_output.put_line(words);
end;
However the result is that I'm getting:
java.lang.ClassNotFoundException: net/sourceforge/jtds/jdbc/Driver -ER1
08001 -ER2
PL/SQL procedure successfully completed.
I have the jar file within the class path, I can't think of any reason it shouldn't have the nessecary permissions to see the jar, and as far as I can tell I have everything spelled correctly.
Please help me figure out what I am doing wrong. Or if there is perhaps an easier way to go about connecting an Oracle DB to an MSSQL DB without really installing anything. Any knowledge on this is welcome as I am pretty new to a lot of this.
Oracle has its own internal java virtual machine and it does not use the system classpath. If you need external libraries you must “load” them into the internal JVM. You can do this using Oracle's loadjava tool.
See the Oracle's loadjava documentation (http://docs.oracle.com/cd/B28359_01/java.111/b31225/cheleven.htm#JJDEV10060)

DSRA9110E: ResultSet is closed

We have a Java class which loops through a result set, which contains Store information, and then starts processing ascii files for each respective stores. For each store to process the ascii file takes around 5 minutes. The issue we encountered is after it processes the first store's ascii file and then fetches the next result set, we get a SQLException saying "DSRA9110E: ResultSet is closed".
Our code basically looks like this.
private void startProcess() throws Exception {
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement("SELECT STORE_CODE FROM STORE");
rs = pstmt.executeQuery();
while (rs != null && rs.next()) {
System.out.println("Processing store " + rs.getString("STORE_CODE"));
try {
processStoreSalesFile();
} catch (Exception e) {
conn.rollBack();
e.printStackTrace();
}
if (rs != null) {
System.out.println("ResultSet is not null");
}
}
} finally {
if (rs != null) {
rs.close();
rs = null;
}
if (pstmt != null) {
pstmt.close();
pstmt = null;
}
}
}
When the error occurs, I do see the system printline "ResultSet is not null". But when it gets the next ResultSet, it says ResultSet is closed.
I have tried to comment out the code which calls processStoreSalesFile() and we didn't get this error and it is able to fetch the next ResultSet without throwing any exceptions.
The next attempt I tried is to uncomment the call to the method processStoreSalesFile() and then remove any ascii files from the file system so that the program will have nothing to process. And no exceptions thrown also.
Our setup is WebSphere-Informix. We have another setup WebSphere-Oracle and that didn't have any problems.
The thing I am suspecting is the ResultSet has timedout or it just didn't want to wait for the process to finish and closed by itself.
Update 1:
Inside the processStoreSalesFile() method, there's a conn.commit() call to commit the records. Is it when a commit is called, the ResultSet will be closed? At the WAS admin console, I've already added the data source property resultSetHoldability with the value '1'. But still the ResultSet is closed.
I hope someone can help me here :(
Thanks.
Here is what we did which worked. Initially, Websphere was configured to use the Informix JDBC driver as its data source, since we are connecting to an Informix database. We changed it to use the DB2 JCC Driver (as proposed by the IBM Informix tech support) and then in the data source custom property, we set the 'resultHoldability' value to '1' (HOLD_CURSORS_OVER_COMMIT). Re-ran the program and it managed to loop through all the results in the result set.
You could use pstmt.setQueryTimeout(seconds). Make sure oracle driver support this. For more detail
here

Categories

Resources