I wish to get user info just like provided by
SELECT SYS_CONTEXT ('USERENV', 'SESSION_USER') FROM DUAL;
and
SELECT SYS_CONTEXT ('USERENV', 'OS_USER') FROM DUAL;
inside a JAVA UDF for Oracle 11g without making a JDBC connection and running these queries to query from DUAL.
I tried System.getProperty("user.name") to read the current OS_user through jvm but I think we are not allowed to fetch information outside the database environment.
More generically, problem statement is to fetch information about the user who has logged into database and using that java UDF (where we need to determine these information) ?
I have found solution to above problem by using the "jdbc:default:connection" which is an internal connection maintained by database itself which is always available. Notice I did not do conn.close(); in the end because this is a shared stream which once closed is closed for all database clients.
public static String doSQL() throws SQLException {
String result = new String();
String q1 = "SELECT SYS_CONTEXT('USERENV','SESSION_USER') FROM DUAL";
Connection conn =
DriverManager.getConnection("jdbc:default:connection");
PreparedStatement ps = conn.prepareStatement(
q1
);
ResultSet rs = ps.executeQuery();
while (rs.next())
result = rs.getString(1);
return "my udf says"+result;
}
Related
I'm working on a dynamic web project and using the PreparedStatement to execute the SQL queries against the DB2 database.
String myQuery = "select id from user where name = ?";
PreparedStatement stmt = connection.prepareStatement(myQuery);
stmt.setString(1, test);
ResultSet resultSet = statement.executeQuery();
How can I receive the full SQL query that is about to be executed on the DB2 server in the console?
If you are familiar with Debugging options in Eclipse. You may try the following:
Set a Breakpoint at ResultSet resultSet = statement.executeQuery();
Right click your application, say Debug As select Java Application (or Whatever applicable in your case i.e. may be SpringBoot App etc.
Perform step that gets you to code mentioned in the Question.
If you check Variables tab in Debug Perspective of Eclipse, you will find variables like myQuery , stmt (according to your code)
Whatever you see as value of stmt would be the full SQL query you need.
Also, if you don't want to keep looking at this variable always you may try Java Logging and Print your Full SQL query in Logs.
I have two method for update:
String query = "update mytable set name = 'new_value' where id ='20' ";
Connection conn;
PreparedStatement pState;
try {
conn = DriverManager.getConnection(dbUrl, "root", "2323");
pState = conn.prepareStatement(query);
pState.executeUpdate();
} catch (SQLException sql) {
sql.printStackTrace();
}
OR:
String query = "update mytable set name = ?" + "where id = ?";
Connection conn;
PreparedStatement pState;
int s;
try {
conn = DriverManager.getConnection(dbUrl, "root", "2323");
pState = conn.prepareStatement(query);
pState.setStringt(1, "new_value");
pState.setString(2, "20");
s = pState.executeUpdate(); // if s = 1 then update done successfully
} catch (SQLException sql) {
sql.printStackTrace();
}
Both methods update database record correctly, Which is better?
Second approach is good practice to avoid SQL Injection attacks.
And following is enough to construct query String, another + concatenation is not required.
String query = "update mytable set name = ? where id = ?";
I would say the second approach.
You aren't returning anything, so why create a result set and go down that path?
Edit:
Even after your comment, I would still use the second template. It's more flexible. Additionally, it's faster. The PreparedStatement is pre-compiled in the database which allows the database to execute a parametric query using the statement faster than a normal query. This won't happen if you use string concatenation (like in your first example).
See: http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
Additionally, from that page:
The main feature of a PreparedStatement object is that, unlike a
Statement object, it is given a SQL statement when it is created. The
advantage to this is that in most cases, this SQL statement is sent to
the DBMS right away, where it is compiled. As a result, the
PreparedStatement object contains not just a SQL statement, but a SQL
statement that has been precompiled. This means that when the
PreparedStatement is executed, the DBMS can just run the
PreparedStatement SQL statement without having to compile it first.
Although PreparedStatement objects can be used for SQL statements with
no parameters, you probably use them most often for SQL statements
that take parameters. The advantage of using SQL statements that take
parameters is that you can use the same statement and supply it with
different values each time you execute it.
The second way is more faster if you use frequently the same query. Depends of the database vendor, the query is cached and the efficiency is higher than that using flat sentences. But all that depends on the implementation of the JDBC driver and the services provided by the database.
See more in Using Prepared Statements in the The Java Tutorials.
I know that using JDBC we can create output for queries inside a database, but how can I get the output of the command SHOW PROCESSLIST as an output of a Java program.
In mysql we get it by: SHOW PROCESSLIST
But I was wondering if we can generate the output using Java?
You can use executeQuery for getting SHOW PROCESSLIST ResultSet.
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql", "root", password);
Statement stmt = null;
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SHOW PROCESSLIST");
while (rs.next())
{
System.out.println(rs.getString("Host"));
System.out.println(rs.getString("Id"));
System.out.println(rs.getString("User"));
System.out.println(rs.getString("db"));
System.out.println(rs.getString("Command"));
System.out.println(rs.getString("state"));
System.out.println(rs.getString("info"));
}
Depending on your MySQL version, you can perform a select on
SELECT * FROM information_schema.PROCESSLIST;
and you can do a where between the user, database, and host IP.
For example:
SELECT * FROM information_schema.PROCESSLIST WHERE db ="mycase" AND HOST LIKE "192.168.11.174%"
I have a database table in oracle which has a column of type DATE. It looks like the table below
TABLE1
ID PRODUCT_NAME ITEM_CNT ENTERED_DATE
1 prod1 500 2012-07-01
2 prod2 1000 2012-06-30
in my java code, I want to get the total item_cnt for a certain date range. here is the code sample
String sql = "select sum(item_cnt) from table1 where entered_date between ? and ?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rset = null;
try{
conn = getConnection(url, user, passwd);
pstmt = conn.prepareStatement(sql);
pstmt.setDate(1, java.sql.Date.valueOf(from_date)); //from_date is a string of "yyyy-mm-dd"
pstmt.setDate(2, java.sql.Date.valueOf(to_date)); //to_date is a string of "yyyy-mm-dd"
rset = pstmt.executeQuery();
....
}catch(SQLException e){
//do something
} finally{
//clean up
}
This code was running fine for a while until three days ago, I start getting the following exception at line pstmt.executeQuery();
java.sql.SQLRecoverableException: No more data to read from socket
at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1157)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:884)
at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1167)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1289)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3628)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1493)
I tried to search for answers but couldn't find anything that really explains it. then I changed my sql query to
"select sum(item_cnt) from table1 where entered_date between to_date(?, 'yyyy-mm-dd') and to_date(?, 'yyyy-mm-dd')";
and instead of setting date, I changed the prepared statement to the following
pstmt.setString(1, from_date);
pstmt.setString(2, to_date);
Then the exception is gone.
Another confusion is, when I populate my table, I am still using the following
pstmt.setDate(1, java.sql.Date.valueOf(date)); //date is a string of format "yyyy-mm-dd"
and it is still working. only the select statement was giving me exceptions.
Now everything is working but I really want to know why. Anyone knows?
I did upgrade my java to 1.7.0_03-b05 recently. and I am using ojdbc6.jar. The oracle is 11g. Could this be the driver's problem? is ojdbc7 out?
I was facing this exception while working over JDBC with IBM WAS 7.0, I had performed a JCA lifecycle management operation on data source. Which is like controlling the runtime status of the data source. Purge removes the contents of connection pool for the data source. However, in WAS this purging the pool will not affect the ongoing transactions. Check on your side.
Another thing which I performed was; the disk space was full on directory where Oracle was installed, I added extra space over that.
As a best practice, I stay away from java.sql.Date class and use to_date() and to_char() functions while dealing with Dates in Java with Oracle.
This question already has answers here:
How can I get the SQL of a PreparedStatement?
(14 answers)
Closed 5 years ago.
I'm working with PreparedStatement with MySQL Server.
example:
String myQuery = "select id from user where name = ?";
PreparedStatement stmt = sqlConnection.prepareStatement(myQuery);
stmt.setString(1, "test");
stmt.executeQUery();
ResultSet rs = stmt.getResultSet();
How can I receive the full SQL query that is about to be executed on the MySQL Server?
It's not mandated by the JDBC spec, but several JDBC drivers let the toString of a PreparedStatement return sort-of the query that will be run, and MySQL's Connector/J happens to have this behavior (or at least it did a few years ago).
String myQuery = "select id from user where name = ?";
PreparedStatement stmt = sqlConnection.prepareStatement(myQuery);
stmt.setString(1, "test");
System.out.println(stmt); // May do what you want!
You cannot really get out the query that will be executed but there are logging APIs that will log database calls for you such as log4jdbc and p6spy.
You can't, as Java isn't responsible for constructing it. Prepared statements are supported within MySQL, so Java sends the actual parameterized SQL ("select id from user where name = ?") straight to MySQL along with the parameters
I can tell you what it is. If you're using MySQL 4.1 or newer with Connector/J 3.1 or newer, it will be something like:
PREPARE stmt FROM 'select id from user where name = ?'
SET #a = 'test'
EXECUTE stmt USING #a
This is because MySQL supports server-side prepared statements.
(More likely it uses the binary protocol, but this code is just to make a point)
Hi I implement the following code which fetch SQL from PreparedStatement . No need to use any jar and Driver .
public void printSqlStatement(PreparedStatement preparedStatement, String sql) throws SQLException{
String[] sqlArrya= new String[preparedStatement.getParameterMetaData().getParameterCount()];
try {
Pattern pattern = Pattern.compile("\\?");
Matcher matcher = pattern.matcher(sql);
StringBuffer sb = new StringBuffer();
int indx = 1; // Parameter begin with index 1
while (matcher.find()) {
matcher.appendReplacement(sb,String.valueOf(sqlArrya[indx]));
}
matcher.appendTail(sb);
System.err.println("Executing Query [" + sb.toString() + "] with Database[" + "] ...");
} catch (Exception ex) {
System.err.println("Executing Query [" + sql + "] with Database[" + "] ...");
}
}
Slightly different approach from all answers here,
If you are familiar with Debugging options in Eclipse. You may try the following:
Set a Breakpoint at stmt.executeQUery();
Right click your application, say Debug As select Java Application (or Whatever applicable in your case i.e. may be SpringBoot App etc.
Perform step that gets you to code mentioned in the Question.
If you check Variables tab in Debug Perspective of Eclipse, you will find variables like myQuery , stmt (according to your code)
Whatever you see as value of stmt would be the full SQL query you need.
Also, if you don't want to keep looking at this variable always you may try Java Logging and Print your Full SQL query in Logs.