I am making an FXML application with intelliJ and MYSQL in Java 11 that allows the user to create a database that has a name of their own choosing. The application:
recognises that the database doesn't yet exist
creates the database via a connect string that uses URL without a specfic DB name
connects to the new database and executes an sql.txt file thereby creating all the required tables.
This approach works save for the fact that when the final statement of the code below executes an automated alert pops up with:
"Cannot connect to database. Please close the program, check the driver is available and that the connection details are correct and then try logging on again".
It does this even though the new database with all required tables has been created and connected to.
Question: Is there anyway to disable this auto-generated message?
protected void execute() throws Exception {
// Connect using URL without DBNAME:This is a re-assignment of inherited value
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// Create database at user request:
String sql = "CREATE DATABASE " + this.newDBName;
stmt = conn.prepareStatement(sql);
stmt.executeUpdate(sql);
StringBuilder sqlText = new StringBuilder();
File file = new File(this.getClass().getResource("createSQLScript.txt").toURI());
/*
Read in the Sql statement text file resource to create tables
using try-with resources and automatic resource closure.*/
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
sqlText.append(line);
}
}
// Set connection object to allow multiple queries in createSQLScript.txt
// A re-assignment of inherited value
conn = DriverManager.getConnection(DB_URL + this.newDBName + "?allowMultiQueries=true", USER, PASS);
stmt = conn.prepareStatement(sqlText.toString());
stmt.executeUpdate(sqlText.toString());
}
PS: DB_URL is - jdbc:mysql://localhost:3306/
This could be related to the fact that you created database in one connection and started accessing it in another connection without closing the previous one.
Connection and PreparedStatement are closable resources. You should always close them with try-finally or try-with-resources pattern, e.g.:
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
// execute stmt...
// populate database...
}
}
try (Connection conn = DriverManager.getConnection(
DB_URL + this.newDBName + "?allowMultiQueries=true", USER, PASS) {
// access newly created database...
}
Related
I'm developing a desktop app to organize different events, thus creating a DB for each event. So far, I've managed to create a DB with whatever name the user wants, using a simple GUI.
However, I can't create tables nor columns for said database, even though it's exactly the same syntax I use in SQL Server Manager.
My code so far:
public static void creDB(String db_name, String table_name){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection(connectionUrl);
String SQL = "CREATE DATABASE " + db_name;
stmt = conn.createStatement();
int result = stmt.executeUpdate(SQL);
String SQL3 = "USE " + db_name;
boolean ree = stmt.execute(SQL3);
String SQL4 = "GO";
boolean rr = stmt.execute(SQL4);
if (result == 0){
System.out.println("Se insertó :D!");
String SQL2 = "CREATE TABLE Pepe(Name_emp INT NOT NULL PRIMARY KEY)";
int res = stmt.executeUpdate(SQL2);
if (res == 0)
System.out.println("GRACIAS DIOS");
}else
System.out.println("Raios shico");
}catch (Exception e) {e.printStackTrace();}
finally {
if (rs != null) try {rs.close();} catch (Exception e) {e.printStackTrace();}
if (stmt != null) try {stmt.close();} catch (Exception e) {e.printStackTrace();}
if (conn != null) try {conn.close();} catch (Exception e) {e.printStackTrace();}
}
}
The error I get is when I try to actually use the DB, using the use [DB name] go; I tried already using that same syntax in one single SQL statement, however it didn't work, so I tried doing it separately and got this error:
com.microsoft.sqlserver.jdbc.SQLServerException: Could not find stored procedure 'GO'.
I know the code above looks like a mess, and it is, but it's just for testing purposes since I'm new to doing DB-related projects with Java; I mixed-matched some of the concepts of this site, which were successful up until the creation of the tables.
I know there's a better way of managing several databases, but as I said, I'm just starting so any advice would be greatly appreciated.
You should not use statements like USE <dbname> when using JDBC, it may lead to unexpected behavior because parts of the driver may still use metadata for the original connected database. You should either use setCatalog on the current connection to switch databases or create an entirely new connection to the new database.
In short, after creating the database, you should use:
conn.setCatalog(db_name);
That's it.
Also, go is not part of the SQL Server syntax, it is only used by tools like the Management Studio, see What is the use of GO in SQL Server Management Studio & Transact SQL? The equivalent in JDBC is to simply execute the statement.
I can figure out how to connect to an AS400 through jt400 with JNDI resources just fine:
Connection conn = null;
Statement stmt = null;
try {
Context ctx = (Context) new InitialContext().lookup("java:comp/env");
conn = ((DataSource) ctx.lookup("jdbc/AS400")).getConnection();
System.out.println(conn.getClientInfo());
stmt = conn.createStatement();
//SQL data fetch using the connection
ResultSet rs = stmt.executeQuery("SELECT * FROM LIBRARY.TABLE");
while (rs.next()) {
System.out.println(rs.getString("COLUMN1"));
}
conn.close();
conn = null;
}
catch(Exception e){System.out.println(e);}
However, another part of the application utilizes DataQueues (from the same jt400 library):
String queue = "/QSYS.LIB/" + libraryName +".LIB/" + queueName +".DTAQ";
try{
system = new AS400(server, user, pass);
DataQueue dq = new DataQueue(system, queue);
// Convert the Data Strings to IBM format
byte[] byteData = message.getBytes("IBM285");
dq.write(byteData);
System.out.println("Wrote to DataQueue");
}catch(Exception e){
e.printStackTrace();
System.err.println(e);
}finally{
// Make sure to disconnect
if(system != null){
try{
system.disconnectAllServices();
System.out.println("Disconnected from DataQueue.");
}catch(Exception e){
System.err.println(e);
}
}
}
Inside of this working code for DataQueues references server, user, pass, which isn't ideal.
I'd like to utilize the AS400 JNDI connection I already set up, but every example I see about connecting Java to DataQueues references an example much like this one.
The documentation all seem to point to AS400 system objects which are hard-coded references to servername, user, pass, etc.
Is there better way to utilize DataQueue() with a JNDI reference?
As assumed in the comments above, the DataQueue is not part of the JDBC connection at all, it can't be used to configure the connection for usage to reading and writing to a DataQueue. Since this is the case, it can't also share connection methods that JDBC uses even though the jt400 library connects with JDBC. A properties file or other server-based solutions is required unless a hard-coded connection is specified in the DataQueue/Java examples online (All 1 of them).
Am getting the following error: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "Connection reset by peer: socket write error."
import java.sql.*;
import com.microsoft.sqlserver.jdbc.*;
public class SQLDatabaseConnection {
// Connect to your database.
// Replace server name, username, and password with your credentials
public static void main(String[] args) {
String connectionString =
"jdbc:sqlserver://XXXXX.database.windows.net:1433;"
+ "database=VDB;"
+ "user=XXX#VVV;"
+ "password=XXXX;"
+ "encrypt=true;"
+ "trustServerCertificate=false;"
+ "hostNameInCertificate=*.database.windows.net;"
+ "loginTimeout=30;";
// Declare the JDBC objects.
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
connection = DriverManager.getConnection(connectionString);
// Create and execute a SELECT SQL statement.
String selectSql = "SELECT TOP 2 * from Application";
statement = connection.createStatement();
resultSet = statement.executeQuery(selectSql);
// Print results from select statement
while (resultSet.next()) {
System.out.println(resultSet.getString(2) + " "
+ resultSet.getString(3));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// Close the connections after the data has been handled.
if (resultSet != null) try {
resultSet.close();
} catch (Exception e) {
}
if (statement != null) try {
statement.close();
} catch (Exception e) {
}
if (connection != null) try {
connection.close();
} catch (Exception e) {
}
}
}
}
I'm only trying to do the "sample" connection snippet of code as referenced on the Azure site (which points to a MS entry), modified only to match my db and test table but without success.
Having reviewed all there is to know, I have:-
ensured that I'm using the right sqljdbc (I've tried all 4)
have the sqlauth.dll on the CLASSPATH
have set the sample up EXACTLY as shown; and incorporated the string that Azure offers.
I have tried various combinations of encrypt and trust without success. As I'm a newbie to Java and Azure, I'm reluctant and unsure how to fiddle with the JVM security settings.
I've proven that my machine can talk to the Azure database (through a VB ODBC connection); and I've tested with the firewall down.
Any thoughts?
I tried to reproduce the issue, but failed that I could access my SQL Azure Instance using the code which be similar with yours.
The difference between our codes is only as below, besides using the connection string of my sql azure instance.
Using the driver sqljdbc4.jar from the sqljdbc_4.0 link.
Using the code Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); to load MS SQL JDBC driver.
Not adding the sqlauth.dll file into the CLASSPATH.
Check my client IP which has been allowed by SQL Azure IP firewall.
Using the sql select 1+1 to test my code, and get the value 4 from code result.getInt(1).
That's fine for me. If you can supply more detals for us, I think it's very helpful for analysising the issue.
Hope it helps.
I am trying to connect to my sql DB on my sql server, using the below code.
But when I run it, the above error shows.
I have added the permissions line to the manifest, but still no luck.
Any advice will be appreciated!
Log.i("Android"," MySQL Connect Example.");
Connection conn = null;
try {
String driver = "net.sourceforge.jtds.jdbc.Driver";
Class.forName(driver).newInstance();
//test = com.microsoft.sqlserver.jdbc.SQLServerDriver.class;
String connString = "jdbc:jtds:sqlserver://server_ip_address :1433/DBNAME;encrypt=fasle;user=xxxxxxxxx;password=xxxxxxxx;instance=SQLEXPRESS;";
String username = "xxxxxx";
String password = "xxxxxxxxxx";
conn = DriverManager.getConnection(connString,username,password);
Log.w("Connection","open");
Statement stmt = conn.createStatement();
ResultSet reset = stmt.executeQuery("select * from TableName");
//Print the data to the console
while(reset.next()){
Log.w("Data:",reset.getString(3));
//Log.w("Data",reset.getString(2));
}
conn.close();
} catch (Exception e) {
Log.w("Error connection","" + e.getMessage());
}
NetworkOnMainThreadException: The exception that is thrown when an application attempts to perform a networking operation on its main thread.
You should call sendfeedback method on asynctask then only above code will work. As webserver is taking lot of time to response main thread becomes unresponsive. To avoid it you should call it on another thread. Hence AsyncTask is better.
http://android-developers.blogspot.in/2009/05/painless-threading.html
I'm using properties file for Database,and here is mycode:
And I have set my database.prperties file in straight src folder.
here is my code(I'm applying this code in a jsp page):
Properties prop=new Properties();
InputStream inputStream=null;
try{
inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("database.properties");
prop.load(inputStream);
}
finally{
if (inputStream != null) try { inputStream.close(); } catch (IOException ignore) {}
}
String driver=prop.getProperty("driver");
if (driver != null)
{
System.setProperty("driver", driver);
}
String url = prop.getProperty("url");
String username= prop.getProperty("username");
String password = prop.getProperty("password");
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url,username,password); // Getting error at this line.
Statement stmt = con.createStatement();
String sql = "select * from info;";
ResultSet rs = stmt.executeQuery(sql);
System.out.println(sql);
Here is my properties file :
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/abc
username=crips
password=drift
But I'm getting this error java.sql.SQLException: Access denied for user 'root '#'localhost' (using password: YES) at line Connection con = DriverManager.getConnection(url,username,password);
Any inputs on this context will appreciated.
java.sql.SQLException: Access denied for user 'crips'#'localhost'
This means that the given user isn't been granted access to the database which you're attempting to connect. You'd need to issue the following SQL command with MySQL admin rights:
GRANT ALL ON abc.* TO 'crips'#'localhost' IDENTIFIED BY 'drift';
Note that the user name and password are case sensitive.
Also note that this has after all nothing to do with reading properties files. You'd have exactly the same problem when supplying username/password/database as hardcoded string variables.