Multiple database db2 and sql server with single query - sql-server

The db2 database is called panth01
the sqlserver database is called proof
As you can see in the code, I made a single query, to extract language in db2 and language in sqlserver.
The problem that in Db2 the column is called LANGUAGE
In sqlserver the column is called LINGUA
In db2 the LANGUAGE column has two words "en"
in SqlServer the LINGUA column has three corners "eng"
I made the query:
//DB2
private static final String DB_DRIVER_DB2 = "com.ibm.db2.jcc.DB2Driver";
private static final String DB_CONNECTION_DB2 = "jdbc:db2://10.12.230.83:50000/PANTH01";
private static final String DB_USER_DB2 = "finance";
private static final String DB_PASSWORD_DB2 = "finance";
//SQLSERVER
private static final String DB_DRIVER_SQLSERVER = "net.sourceforge.jtds.jdbc.Driver";
private static final String DB_CONNECTION_SQLSERVER = "jdbc:jtds:sqlserver://10.65.21.15:1433;DatabaseName=PROVA";
private static final String DB_USER_SQLSERVER = "sa";
private static final String DB_PASSWORD_SQLSERVER = "sa";
public void selectTHERACLASS_HDR_THERACLASS_HDR_NLS() throws Exception {
//DB2_inizio
Connection dbConnection = null;
Statement statement = null;
//DB2_fine
//SqlServer_inzio
Connection dbConnectionSqlServer = null;
Statement statementSqlServer = null;
//SqlServer_fine
//Query SqlServer and db2
String query = "select PANTH01.THERA.CLASS_HDR.LANGUAGE, PROVA.DIZIOPT.LINGUA from PANTH01.THERA.CLASS_HDR JOIN PROVA.DIZIOPT.LINGUA ON PANTH01.THERA.CLASS_HDR.LANGUAGE = PROVA.DIZIOPT.LINGUA";
try {
//DB2_inizio
dbConnection = getConnectionDb2();
statement = dbConnection.createStatement();
//DB2_fine
//sqlserver_inizio
dbConnectionSqlServer = getConnectionSqlServer();
statementSqlServer = dbConnectionSqlServer.createStatement();
ResultSet rSqlServer = statementSqlServer.executeQuery(query);
//sqlserver_inizio_fine
while (rSqlServer.next()) {
String language = rSqlServer.getString("LANGUAGE");
String lingua = rSqlServer.getString("LINGUA");
System.out.println("LANGUAGE: " + language);
System.out.println("LINGUA: " + lingua);
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (statement != null && statementSqlServer != null) {
statement.close();
statementSqlServer.close();
}
if (dbConnection != null && dbConnectionSqlServer != null) {
dbConnection.close();
dbConnectionSqlServer.close();
}
}
}
Output
Invalid object name 'PANTH01.THERA.CLASS_HDR'

Related

How to use scope_identity in jdbc [duplicate]

I want to INSERT a record in a database (which is Microsoft SQL Server in my case) using JDBC in Java. At the same time, I want to obtain the insert ID. How can I achieve this using JDBC API?
If it is an auto generated key, then you can use Statement#getGeneratedKeys() for this. You need to call it on the same Statement as the one being used for the INSERT. You first need to create the statement using Statement.RETURN_GENERATED_KEYS to notify the JDBC driver to return the keys.
Here's a basic example:
public void create(User user) throws SQLException {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_INSERT,
Statement.RETURN_GENERATED_KEYS);
) {
statement.setString(1, user.getName());
statement.setString(2, user.getPassword());
statement.setString(3, user.getEmail());
// ...
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
user.setId(generatedKeys.getLong(1));
}
else {
throw new SQLException("Creating user failed, no ID obtained.");
}
}
}
}
Note that you're dependent on the JDBC driver as to whether it works. Currently, most of the last versions will work, but if I am correct, Oracle JDBC driver is still somewhat troublesome with this. MySQL and DB2 already supported it for ages. PostgreSQL started to support it not long ago. I can't comment about MSSQL as I've never used it.
For Oracle, you can invoke a CallableStatement with a RETURNING clause or a SELECT CURRVAL(sequencename) (or whatever DB-specific syntax to do so) directly after the INSERT in the same transaction to obtain the last generated key. See also this answer.
Create Generated Column
String generatedColumns[] = { "ID" };
Pass this geneated Column to your statement
PreparedStatement stmtInsert = conn.prepareStatement(insertSQL, generatedColumns);
Use ResultSet object to fetch the GeneratedKeys on Statement
ResultSet rs = stmtInsert.getGeneratedKeys();
if (rs.next()) {
long id = rs.getLong(1);
System.out.println("Inserted ID -" + id); // display inserted record
}
When encountering an 'Unsupported feature' error while using Statement.RETURN_GENERATED_KEYS, try this:
String[] returnId = { "BATCHID" };
String sql = "INSERT INTO BATCH (BATCHNAME) VALUES ('aaaaaaa')";
PreparedStatement statement = connection.prepareStatement(sql, returnId);
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
try (ResultSet rs = statement.getGeneratedKeys()) {
if (rs.next()) {
System.out.println(rs.getInt(1));
}
rs.close();
}
Where BATCHID is the auto generated id.
I'm hitting Microsoft SQL Server 2008 R2 from a single-threaded JDBC-based application and pulling back the last ID without using the RETURN_GENERATED_KEYS property or any PreparedStatement. Looks something like this:
private int insertQueryReturnInt(String SQLQy) {
ResultSet generatedKeys = null;
int generatedKey = -1;
try {
Statement statement = conn.createStatement();
statement.execute(SQLQy);
} catch (Exception e) {
errorDescription = "Failed to insert SQL query: " + SQLQy + "( " + e.toString() + ")";
return -1;
}
try {
generatedKey = Integer.parseInt(readOneValue("SELECT ##IDENTITY"));
} catch (Exception e) {
errorDescription = "Failed to get ID of just-inserted SQL query: " + SQLQy + "( " + e.toString() + ")";
return -1;
}
return generatedKey;
}
This blog post nicely isolates three main SQL Server "last ID" options:
http://msjawahar.wordpress.com/2008/01/25/how-to-find-the-last-identity-value-inserted-in-the-sql-server/ - haven't needed the other two yet.
Instead of a comment, I just want to answer post.
Interface java.sql.PreparedStatement
columnIndexes « You can use prepareStatement function that accepts columnIndexes and SQL statement.
Where columnIndexes allowed constant flags are Statement.RETURN_GENERATED_KEYS1 or Statement.NO_GENERATED_KEYS[2], SQL statement that may contain one or more '?' IN parameter placeholders.
SYNTAX «
Connection.prepareStatement(String sql, int autoGeneratedKeys)
Connection.prepareStatement(String sql, int[] columnIndexes)
Example:
PreparedStatement pstmt =
conn.prepareStatement( insertSQL, Statement.RETURN_GENERATED_KEYS );
columnNames « List out the columnNames like 'id', 'uniqueID', .... in the target table that contain the auto-generated keys that should be returned. The driver will ignore them if the SQL statement is not an INSERT statement.
SYNTAX «
Connection.prepareStatement(String sql, String[] columnNames)
Example:
String columnNames[] = new String[] { "id" };
PreparedStatement pstmt = conn.prepareStatement( insertSQL, columnNames );
Full Example:
public static void insertAutoIncrement_SQL(String UserName, String Language, String Message) {
String DB_URL = "jdbc:mysql://localhost:3306/test", DB_User = "root", DB_Password = "";
String insertSQL = "INSERT INTO `unicodeinfo`( `UserName`, `Language`, `Message`) VALUES (?,?,?)";
//"INSERT INTO `unicodeinfo`(`id`, `UserName`, `Language`, `Message`) VALUES (?,?,?,?)";
int primkey = 0 ;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection(DB_URL, DB_User, DB_Password);
String columnNames[] = new String[] { "id" };
PreparedStatement pstmt = conn.prepareStatement( insertSQL, columnNames );
pstmt.setString(1, UserName );
pstmt.setString(2, Language );
pstmt.setString(3, Message );
if (pstmt.executeUpdate() > 0) {
// Retrieves any auto-generated keys created as a result of executing this Statement object
java.sql.ResultSet generatedKeys = pstmt.getGeneratedKeys();
if ( generatedKeys.next() ) {
primkey = generatedKeys.getInt(1);
}
}
System.out.println("Record updated with id = "+primkey);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
I'm using SQLServer 2008, but I have a development limitation: I cannot use a new driver for it, I have to use "com.microsoft.jdbc.sqlserver.SQLServerDriver" (I cannot use "com.microsoft.sqlserver.jdbc.SQLServerDriver").
That's why the solution conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS) threw a java.lang.AbstractMethodError for me.
In this situation, a possible solution I found is the old one suggested by Microsoft:
How To Retrieve ##IDENTITY Value Using JDBC
import java.sql.*;
import java.io.*;
public class IdentitySample
{
public static void main(String args[])
{
try
{
String URL = "jdbc:microsoft:sqlserver://yourServer:1433;databasename=pubs";
String userName = "yourUser";
String password = "yourPassword";
System.out.println( "Trying to connect to: " + URL);
//Register JDBC Driver
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
//Connect to SQL Server
Connection con = null;
con = DriverManager.getConnection(URL,userName,password);
System.out.println("Successfully connected to server");
//Create statement and Execute using either a stored procecure or batch statement
CallableStatement callstmt = null;
callstmt = con.prepareCall("INSERT INTO myIdentTable (col2) VALUES (?);SELECT ##IDENTITY");
callstmt.setString(1, "testInputBatch");
System.out.println("Batch statement successfully executed");
callstmt.execute();
int iUpdCount = callstmt.getUpdateCount();
boolean bMoreResults = true;
ResultSet rs = null;
int myIdentVal = -1; //to store the ##IDENTITY
//While there are still more results or update counts
//available, continue processing resultsets
while (bMoreResults || iUpdCount!=-1)
{
//NOTE: in order for output parameters to be available,
//all resultsets must be processed
rs = callstmt.getResultSet();
//if rs is not null, we know we can get the results from the SELECT ##IDENTITY
if (rs != null)
{
rs.next();
myIdentVal = rs.getInt(1);
}
//Do something with the results here (not shown)
//get the next resultset, if there is one
//this call also implicitly closes the previously obtained ResultSet
bMoreResults = callstmt.getMoreResults();
iUpdCount = callstmt.getUpdateCount();
}
System.out.println( "##IDENTITY is: " + myIdentVal);
//Close statement and connection
callstmt.close();
con.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
try
{
System.out.println("Press any key to quit...");
System.in.read();
}
catch (Exception e)
{
}
}
}
This solution worked for me!
I hope this helps!
You can use following java code to get new inserted id.
ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, quizid);
ps.setInt(2, userid);
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if (rs.next()) {
lastInsertId = rs.getInt(1);
}
It is possible to use it with normal Statement's as well (not just PreparedStatement)
Statement statement = conn.createStatement();
int updateCount = statement.executeUpdate("insert into x...)", Statement.RETURN_GENERATED_KEYS);
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
return generatedKeys.getLong(1);
}
else {
throw new SQLException("Creating failed, no ID obtained.");
}
}
Most others have suggested to use JDBC API for this, but personally, I find it quite painful to do with most drivers. When in fact, you can just use a native T-SQL feature, the OUTPUT clause:
try (
Statement s = c.createStatement();
ResultSet rs = s.executeQuery(
"""
INSERT INTO t (a, b)
OUTPUT id
VALUES (1, 2)
"""
);
) {
while (rs.next())
System.out.println("ID = " + rs.getLong(1));
}
This is the simplest solution for SQL Server as well as a few other SQL dialects (e.g. Firebird, MariaDB, PostgreSQL, where you'd use RETURNING instead of OUTPUT).
I've blogged about this topic more in detail here.
With Hibernate's NativeQuery, you need to return a ResultList instead of a SingleResult, because Hibernate modifies a native query
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id
like
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id LIMIT 1
if you try to get a single result, which causes most databases (at least PostgreSQL) to throw a syntax error. Afterwards, you may fetch the resulting id from the list (which usually contains exactly one item).
In my case ->
ConnectionClass objConnectionClass=new ConnectionClass();
con=objConnectionClass.getDataBaseConnection();
pstmtGetAdd=con.prepareStatement(SQL_INSERT_ADDRESS_QUERY,Statement.RETURN_GENERATED_KEYS);
pstmtGetAdd.setString(1, objRegisterVO.getAddress());
pstmtGetAdd.setInt(2, Integer.parseInt(objRegisterVO.getCityId()));
int addId=pstmtGetAdd.executeUpdate();
if(addId>0)
{
ResultSet rsVal=pstmtGetAdd.getGeneratedKeys();
rsVal.next();
addId=rsVal.getInt(1);
}
If you are using Spring JDBC, you can use Spring's GeneratedKeyHolder class to get the inserted ID.
See this answer...
How to get inserted id using Spring Jdbctemplate.update(String sql, obj...args)
If you are using JDBC (tested with MySQL) and you just want the last inserted ID, there is an easy way to get it. The method I'm using is the following:
public static Integer insert(ConnectionImpl connection, String insertQuery){
Integer lastInsertId = -1;
try{
final PreparedStatement ps = connection.prepareStatement(insertQuery);
ps.executeUpdate(insertQuery);
final com.mysql.jdbc.PreparedStatement psFinal = (com.mysql.jdbc.PreparedStatement) ps;
lastInsertId = (int) psFinal.getLastInsertID();
connection.close();
} catch(SQLException ex){
System.err.println("Error: "+ex);
}
return lastInsertId;
}
Also, (and just in case) the method to get the ConnectionImpl is the following:
public static ConnectionImpl getConnectionImpl(){
ConnectionImpl conexion = null;
final String dbName = "database_name";
final String dbPort = "3306";
final String dbIPAddress = "127.0.0.1";
final String connectionPath = "jdbc:mysql://"+dbIPAddress+":"+dbPort+"/"+dbName+"?autoReconnect=true&useSSL=false";
final String dbUser = "database_user";
final String dbPassword = "database_password";
try{
conexion = (ConnectionImpl) DriverManager.getConnection(connectionPath, dbUser, dbPassword);
}catch(SQLException e){
System.err.println(e);
}
return conexion;
}
Remember to add the connector/J to the project referenced libraries.
In my case, the connector/J version is the 5.1.42. Maybe you will have to apply some changes to the connectionPath if you want to use a more modern version of the connector/J such as with the version 8.0.28.
In the file, remember to import the following resources:
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.mysql.jdbc.ConnectionImpl;
Hope this will be helpful.
Connection cn = DriverManager.getConnection("Host","user","pass");
Statement st = cn.createStatement("Ur Requet Sql");
int ret = st.execute();

I always get the latest data in the database

I want to search and display data from database (data entered in a form). The problem is that I always get the last value in the database.
this is my code:
public void actionPerformed(ActionEvent ae) {
String nom, prenom;
nom = tf3.getText();
prenom = tf4.getText();
String url = "jdbc:mysql://localhost:3306/seminaire";
String userid = "root";
String password = "";
try {
if (nom != "" && prenom != "") {
Connection connection = DriverManager.getConnection(url,
userid, password);
Statement st = connection.createStatement();
ResultSet rs= st.executeQuery("SELECT * FROM participant WHERE nom=nom && prenom=prenom");
while (rs.next())
{
String nm = rs.getString("nom");
String prnm = rs.getString("prenom");
String cat = rs.getString("categorie");
String afl = rs.getString("affiliation");
String mnt = rs.getString("montant");
}
}
}
catch (FileNotFoundException | DocumentException e) {
e.printStackTrace();
}
}
Have you any idea please.
thank you
It looks like the values you assign to nom and prenom aren't used in the query you execute. Also, should && be AND?
I'd recommend using prepared statements to do so, see Java documentation on prepared statements.
I'd change your code to do something like this:
PreparedStatement selectStatement = connection.prepareStatement("SELECT * FROM participant WHERE nom=? AND prenom=?");
selectStatement.setString(1, nom);
selectStatement.setString(2, prenom);
ResultSet rs = selectStatement.executeQuery();

JDBC connection to linked server

I'm trying to connect from a Java application to a Linked Server I created with MSSQL Server.
The URL string is
jdbc:sqlserver://172.15.230.11
and the query is
SELECT * FROM OPENQUERY(172.15.230.11,'SELECT * FROM myTable WHERE
myCode = 345')
But when I run the program, this exception occurs:
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'myUser'.
The actual code is here:
private static final String DB_URL_LOCAL = "jdbc:sqlserver://172.15.230.11";
private static final String DB_USERNAME_LOCAL = "myUser";
private static final String DB_PASSWORD_LOCAL = "myPassword";
private static final String DB_CLASS = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
static String SQL_READ = "SELECT * FROM OPENQUERY(172.15.230.11,'SELECT * FROM myTable WHERE myCode = 345')";
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = getConnection();
preparedStatement = connection.prepareStatement(SQL_READ);
resultSet = preparedStatement.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static Connection getConnection(){
Connection connection = null;
Properties properties = new Properties();
try {
Class.forName(DB_CLASS);
properties.setProperty("characterEncoding", "utf-8");
properties.setProperty("user", DB_USERNAME_LOCAL);
properties.setProperty("password", DB_PASSWORD_LOCAL);
connection = DriverManager.getConnection(DB_URL_LOCAL, properties);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
First of all you have to make sure that you enable remote connections to MSSQLserver.
Then make sure you use a user in your connection wich has sufficient rights to query your schema.
Then make sure you provide the correct source to the JDBC driver:
dbsource= "jdbc:sqlserver://IP:1433;database=MY_SCHEMA";
Then make sure you load the correct JDBC driver and use the appropriate user and password
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
dbCon = DriverManager.getConnection(dbsource, user, password);
On top of all that, if your database is using windows authentication, then you can use 'integratedSecurity':
dbsource= "jdbc:sqlserver://IP:1433;database=MY_SCHEMA;integratedSecurity=true;";

How to retrieve data using JDBC

I have been trying with the following code.
The connection is being made. But the resultSet is coming as empty (not null), whereas there are a couple of entries (2 fields each) in the database for the same.
It does not enter the while condition. I'm new to JDBC, please help!
My code is:
import java.sql.*;
public class JDBCTest123
{
public static void main(String[] args)
{
System.out.println("oracle Connect Example.");
Connection conn = null;
String url = "jdbc:oracle:thin:#127.0.0.1:1521:XE";
String driver = "oracle.jdbc.driver.OracleDriver";
String userName = "system";
String password = "mumpymamai";
Statement stmt = null;
String query = "select * from table1";
try
{
Class.forName(driver);
conn = DriverManager.getConnection(url, userName, password);
stmt = conn.createStatement();
System.out.println("Connected to the database");
ResultSet rs = stmt.executeQuery(query);
while (rs.next())
{
System.out.println(rs.getString(1));
System.out.println(rs.getString(2));
}
conn.close();
System.out.println("Disconnected from database");
} catch (Exception e)
{
e.printStackTrace();
}
}
}
And the output is:
oracle Connect Example.
Connected to the database
Disconnected from database
So few suggestions. I recommend to you use PreparedStatements which are more faster and safer.
PreparedStatement ps = null;
conn = DriverManager.getConnection(url, userName, password);
ps = conn.prepareStatement(query);
ResultSet rs = ps.executeQuery();
while (rs.next())
{
// do some work
}
Second suggestion, call close() method in finally block, because application may crash and then your connection won't be closed. Finally block guarantees that will be always called.
Third suggestion if it doesn't work without Exception, probably you have empty table.

Dapper fails when converting int to bool (Sqlite)

I have a table with IsValid column, with int datatype (Sqlite).
When selecting from it Dapper fails:
{"Error parsing column 0 (IsValid=1 - Int32)"}
{"Specified cast is not valid."}
Which makes sense, but it has to be a pretty common case - shouldn't it be accounted for ?
This is the code:
public void Test()
{
string conns = #"Data Source=mydbfile.db3;Version=3;";
string sql = null;
using (SQLiteConnection connection = new SQLiteConnection(conns))
{
connection.Open();
sql = "INSERT INTO Test (IsValid) VALUES (1)";
connection.Execute(sql);
sql = "SELECT * FROM Test";
var x = connection.Query<Valid>(sql);
}
}
private class Valid
{
public bool IsValid { get; set; }
}
Table has a single 'IsValid' column of type int.

Resources