I have developed java desktop application where I have a class to create MySQL database and execute SQL script in it. Actually my script is in java package i.e. com.scriptrunner/myscript.sql. When I executed script which is in local drive like c:\myscript.sql, it works fine, but I could not find the solution to read a SQL script from project package and execute it. I have used iBatis ScriptRunner for running this script. Can desktop application read sql script from package and execute it ?
Thank you.
We can execute sql script which is in our package by this code. We need to add ibatis-sqlmap-2.3.0.jar in our library. This code first creates database myDb, then locates the path of script file i.e. in com.command.sql package and finally runs script into myDb database.
String dbName = "myDb";
String jdbcDriver = "com.mysql.jdbc.Driver"
//Created new database myDb.
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/?user=root&password=")) {
Statement s = conn.createStatement();
int Result = s.executeUpdate("CREATE DATABASE IF NOT EXISTS "+dbName);
}
//This is the path to database; i.e. in com.command.sql package.
String scriptFilePath = "src\\com.command.sql\\mydatabase.sql";
// Create MySql Connection
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/"+dbName, "root", "root");
Statement stmt = null;
Class.forName(jdbcDriver);
try {
// Initialize object for ScripRunner
ScriptRunner sr = new ScriptRunner(con, false, false);
// Give the input file to Reader
Reader reader = new BufferedReader(new FileReader(scriptFilePath ));
// Exctute script
sr.runScript(reader);
} catch (IOException | SQLException e) {
System.err.println("Failed to Execute" + scriptFilePath
+ " The error is " + e.getMessage());
}
Related
I have been writing an android application in android studio that needs access to a cloud database. I am using Microsoft Azure for my database and have already created it, however I am struggling to query it from the android application. When trying from Android Studio, I get an error to do with JDBC not being found, however I have tried adding the relevant .jar files with no luck. I have also tried creating a maven project as suggested on the Azure site, and with this I can access the database fine, however as soon as I try using the package created by maven as a module in Android Studio, the sql query no longer works and instead goes to the exception. Below you can see the function I am trying to access in the maven project:
public static ArrayList<Double[]> getIncidentDetails() {
// Connect to database
String url = "jdbc:sqlserver://............"; //Take ............ to be my connection string
Connection connection = null;
ArrayList<Double[]> results = new ArrayList<Double[]>();
try {
connection = DriverManager.getConnection(url);
System.out.println("Connected");
String selectSQL = "SELECT [latitude], [longitude]" + "FROM [Incidents]";
try (Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(selectSQL)) {
while (resultSet.next()) {
System.out.println(resultSet.getString(2));
Double latitude = Double.parseDouble(resultSet.getString(1));
Double longitude = Double.parseDouble(resultSet.getString(2));
results.add(new Double[] {latitude, longitude});
}
connection.close();
}
} catch (Exception e){
System.out.println(e.getMessage());
}
return results;
}
Any ideas on how I could connect to the database from Android Studio, with or without the Maven project would be greatly appreciated.
Try to load the class before you open the connection:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection(connectionUrl);
For example I have coded the following php code and run on redshift like below.
<?php
$connect = pg_connect("host=xx.xxxx.us-east-1.redshift.amazonaws.com port=xxxx dbname=testdb user=xxxx password=xxxxxx");
$query = "select name, email from mytable LIMIT 7";
$result = pg_query($connect,$query);
while(($row = pg_fetch_array($result)) != null) {
$name = $row[0];
$email = $row[1];
echo $name." <<>> ".$email." <<>> ";
}
?>
I saved the above php file and executed in the below way.
myuser#ip-20-143-43-144:/home/myuser$ php runquery.php <Enter>
Then it gives me the output.
I want to test the same thing with java. So I took the example from the aws and saved in the same location.
public class ConnectToCluster {
static final String dbURL = "jdbc:postgresql://xxxx.xxxxx.us-east-1.redshift.amazonaws.com:xxxx/testdb";
static final String MasterUsername = "XXXX";
static final String MasterUserPassword = "XXXXXX";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//Dynamically load postgresql driver at runtime.
Class.forName("org.postgresql.Driver");
//Open a connection and define properties.
System.out.println("Connecting to database...");
Properties props = new Properties();
//Uncomment the following line if using a keystore.
//props.setProperty("ssl", "true");
props.setProperty("user", MasterUsername);
props.setProperty("password", MasterUserPassword);
conn = DriverManager.getConnection(dbURL, props);
//Try a simple query.
System.out.println("Listing system tables...");
stmt = conn.createStatement();
String sql;
sql = "select * from information_schema.tables;";
ResultSet rs = stmt.executeQuery(sql);
//Get the data from the result set.
while(rs.next()){
//Retrieve two columns.
String catalog = rs.getString("table_catalog");
String name = rs.getString("table_name");
//Display values.
System.out.print("Catalog: " + catalog);
System.out.println(", Name: " + name);
}
rs.close();
stmt.close();
conn.close();
}catch(Exception ex){
//For convenience, handle all errors here.
ex.printStackTrace();
}finally{
//Finally block to close resources.
try{
if(stmt!=null)
stmt.close();
}catch(Exception ex){
}// nothing we can do
try{
if(conn!=null)
conn.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
System.out.println("Finished connectivity test.");
}
}
I saved this .java file too in the same location. So, can someone please tell me how to run this java file on command as I did for php.
(1) Download a postgresql JDBC driver from the following link and put it in the same directory of ConnectToCluster.java.
http://jdbc.postgresql.org/download/postgresql-8.4-703.jdbc4.jar
(2) Add the missing lines(import java library) in the head of the java file.
import java.sql.*;
import java.util.*;
public class ConnectToCluster {
...
(3) Run the following command.
javac ConnectToCluster.java && java -cp .:postgresql-8.4-703.jdbc4.jar ConnectToCluster
Yesterday i was using oracle 9.1 with ojdbc 14 jdbc driver with following code for adding employee, it was working fine but now i am using oracle 10.1.0.2.0 with ojdbc14 but now it is giving following error
Io exception: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=168821248)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4)))) error
Following is code for adding employee
public static Connection getConnection() throws Exception {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:#localhost:5500:globldb3";
String username = "scott";
String password = "tiger";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
public String addEmployee(){
Connection conn = null;
PreparedStatement pstmt = null;
boolean committed = false;
try {
conn = getConnection();
conn.setAutoCommit(false);
String query = "INSERT INTO
employee(e_id,e_name,e_f_name,e_desg,e_address,e_phone_no,"+
"e_salary,e_house_rent,e_conv_allow,e_email,d_name,e_hire_month,e_hire_year)"+
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";
pstmt = conn.prepareStatement(query);
pstmt = conn.prepareStatement(query); // create a statement
pstmt.setInt(1,this.eid);
pstmt.setString(2,this.ename);
pstmt.setString(3,this.efname);
pstmt.setString(4,this.edesg);
pstmt.setString(5,this.eaddress);
pstmt.setLong(6,this.ephoneno);
pstmt.setInt(7,this.esalary);
pstmt.setInt(8,this.houserent);
pstmt.setInt(9,this.convallow);
pstmt.setString(10,this.eemail);
pstmt.setString(11,this.edname);
pstmt.setInt(12,this.ehmon);
pstmt.setInt(13,this.ehy);
pstmt.executeUpdate(); // execute insert statement
conn.commit();
conn.setAutoCommit(true);
committed = true;
return "add-employee-msg.xhtml";
} catch (Exception e) {
e.printStackTrace();
return "add-employee-ex.xhtml";
} finally {
try{
if (!committed) conn.rollback();
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
}catch(Exception e){
e.printStackTrace();
}
}
} //addEmployee
Any idea please?
That's a configuration issue:
12505, 00000, "TNS:listener does not currently know of SID given in connect descriptor"
Maybe you just have to copy the original LISTENER.ORA (correct name??) to your new oracle instance. You use the sid globldb3 which may be undefined on the 10.x instance.
You have wrong DB URL.
You have: "jdbc:oracle:thin:#localhost:5500:globldb3"
But should be: "jdbc:oracle:thin:#localhost:5500/globldb3" <- notice slash instead of colon for the SID name.
Due to wrong SID/Servicename this issue will arise. Based on Servicename/SID, need to correct DB URL, otherwise it will be showing Connection refused error.
format for both forms:
JDBC URL FORMAT:
jdbc:oracle:thin:#//:/ServiceName
or
jdbc:oracle:thin:#::
This should work :
<property name="connection.url">jdbc:oracle:thin:#//localhost:1521/ORCL</property>
JDBC URL FOR ORACLE, wrong or correct, how do you know?
INSTANCE SID by ":"
jdbc:oracle:thin:#db_ip_or_name:1521:ODB_IS
SERVICE NAME by "/"
jdbc:oracle:thin:#db_ip_or_name:1521/ODB_SN
How do you know?
SELECT NAME,VALUE,DESCRIPTION
FROM V$PARAMETER P
WHERE P.NAME IN ('db_unique_name','db_name','instance_name','service_names');
*maybe you need your dba's help to query data dictionary view
*----NAME-----|--VALUE--|--DESCRIPTION------------------------------
instance_name | ODB_IS | instance name supported by the instance
service_names | ODB_SN | service names supported by the instance
db_name | ODB_NM | database name specified in CREATE DATABASE
db_unique_name| ODB_UN | Database Unique Name
The defferents are for RAC, DG; PRD,UAT,DEV deployment requirement etc.
Use service_names = db_name as normal, they must been see in 'lsnrctl status'
PORT:
lsnrctl status
*run on the DB server shell window
for a school database project we are making a database program (user GUI and the database). Using Microsoft Access 2010 I created the database and populated it with some sample data, and saved it in .mdb format and placed it in my project folder.
When running it in eclipse the following code works fine, connects and even retrieves the query. However I find that I am unable to export the code to a jar and run it (which is required for the project, give them a working copy of your program on a CD or flash drive), and I'm also unable to port the code over to Netbeans to have it work, as well as trying to compile on a Linux machine.
I assume this is a problem with including drivers or trying to use Microsoft access. The error I get when running the jar or running on Netbeans is given below the code. So I ask either how do I include drivers to make the program portable, or how else can I approach this problem?
Thanks in advance
import java.sql.*;
public class JDBCTest {
static Connection connection;
static Statement statement;
public static void main(String args[]){
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=TLDATABASEDBM.mdb";
connection = DriverManager.getConnection( database ,"","");
buildStatement();
executeQuery();
}catch(Exception e){
e.printStackTrace();
System.out.println("Error!");
}
}
public static void buildStatement() throws SQLException {
statement = connection.createStatement();
}
public static void executeQuery() throws SQLException {
boolean foundResults = statement.execute("SELECT * FROM tblStaff AS x WHERE City='Calgary'");
if(foundResults){
ResultSet set = statement.getResultSet();
if(set!=null) displayResults(set);
}else {
connection.close();
}
}
public static void displayResults(ResultSet rs) throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
int columns=metaData.getColumnCount();
String text="";
while(rs.next()){
for(int i=1;i<=columns;++i) {
text+=""+metaData.getColumnName(i)+":\t";
text+=rs.getString(i);
//text+="</"+metaData.getColumnName(i)+">";
text+="\n";
}
text+="\n";
}
System.out.println(text);
}
}
The error mentioned above:
java.sql.SQLException: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6957)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114)
at sun.jdbc.odbc.JdbcOdbc.SQLDriverConnect(JdbcOdbc.java:3073)
at sun.jdbc.odbc.JdbcOdbcConnection.initialize(JdbcOdbcConnection.java:323)
at sun.jdbc.odbc.JdbcOdbcDriver.connect(JdbcOdbcDriver.java:174)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:207)
at tldatabase.DataConnect.makeConnection(DataConnect.java:35)
at tldatabase.Main.main(Main.java:24)
I know the post was years ago but I felt like answering the question for those who are just experiencing this right now. It took me a while to know the answer to the question so here's the solution:
http://wiki.netbeans.org/FaqSettingHeapSize
Follow the "Running the 32-bit JVM".
All you have to do is find the netbeans.conf in the installation folder of your netbeans and change the directory from something like this:
netbeans_jdkhome="C:\Program Files\Java\jdk1.6.0_24"
to this:
netbeans_jdkhome="C:\Program Files (x86)\Java\jdk1.6.0_21"
The problem is netbeans might be running in 64 bit but MS Access only support 32-bit. So doing this would hopefully solve the problem. Also make sure to install this:
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=23734
The main problem lies in the line:
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=TLDATABASEDBM.mdb";
Make sure that the .mdb file is in the correct directory.
Check the file extension as .mdb or .mdbacc.
Also, if you want to use the same DSN every time, it is better to add the DSN(Data Source Name) into the respective system on which the mdb is stored.
I think that your app do not see TLDATABASEDBM.mdb in current directory. You can give full path to this file in connection string or add system DSN in ODBC Manager and then connect to it with connection string like: jdbc:odbc:TLDATABASEDBM
Honestly, I dont like what I am going to say... but, it solved the same issue for me... mysteriously... :(((
on the line where you are defining the database variable, I changed ...(.mdb)... into ...(.mdb, *.accdb)...
All the best for figuring out what difference that made!
package javaapplication1;
import java.sql.*;
public class MSaccess_archive {
public static void main(String[] args) {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// set this to a MS Access DB you have on your machine
String filename = "mdbTEST.mdb";
String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=";
database+= filename.trim() + ";DriverID=22;}"; // add on to the end
// now we can get the connection from the DriverManager
Connection con = DriverManager.getConnection( database ,"","");
Statement stmt = con.createStatement();
stmt.execute("select * from student"); // execute query in table student
ResultSet rs = stmt.getResultSet(); // get any Result that came from our query
if (rs != null)
while ( rs.next() ){
System.out.println("Name: " + rs.getInt("Age") + " ID: "+rs.getString("Course"));
}
stmt.close();
con.close();
}
catch (Exception err) {
System.out.println("ERROR: " + err);
}
}
}
I am starting to use MySQL with JDBC.
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///x", "x", "x");
stmt = conn.createStatement();
stmt.execute( "CREATE TABLE amigos" +
"("+
"id int AUTO_INCREMENT not null,"+
"nombre char(20) not null,"+
"primary key(id)" +
")");
I have 3-4 tables to create and this doesn't look good.
Is there a way to run a .sql script from MySQL JDBC?
Ok. You can use this class here (posted on pastebin because of file length) in your project. But remember to keep the apache license info.
JDBC ScriptRunner
It's ripoff of the iBatis ScriptRunner with dependencies removed.
You can use it like this
Connection con = ....
ScriptRunner runner = new ScriptRunner(con, [booleanAutoCommit], [booleanStopOnerror]);
runner.runScript(new BufferedReader(new FileReader("test.sql")));
That's it!
I did a lot of research on this and found a good util from spring. I think using SimpleJdbcTestUtils.executeSqlScript(...) is actually the best solution, as it is more maintained and tested.
Edit: SimpleJdbcTestUtils is deprecated. You should use JdbcTestUtils. Updated the link.
Spring Framework's ResourceDatabasePopulator may help. As you said you're using MySQL and JDBC, let's assume you have a MySQL-backed DataSource instance ready. Further, let's assume your MySQL script files are classpath-locatable. Let's assume you are using WAR layout and the script files are located in a directory src/main/webapp/resources/mysql-scripts/... or src/test/resources/mysql-scripts/.... Then you can use ResourceDatabasePopulator to execute SQL scripts like this:
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import javax.sql.DataSource;
DataSource dataSource = getYourMySQLDriverBackedDataSource();
ResourceDatabasePopulator rdp = new ResourceDatabasePopulator();
rdp.addScript(new ClassPathResource(
"mysql-scripts/firstScript.sql"));
rdp.addScript(new ClassPathResource(
"mysql-scripts/secondScript.sql"));
try {
Connection connection = dataSource.getConnection();
rdp.populate(connection); // this starts the script execution, in the order as added
} catch (SQLException e) {
e.printStackTrace();
}
For simple sql script splitted by ';' you can use this simple function.
It remove comments and run statements one by one
static void executeScript(Connection conn, InputStream in)
throws SQLException
{
Scanner s = new Scanner(in);
s.useDelimiter("/\\*[\\s\\S]*?\\*/|--[^\\r\\n]*|;");
Statement st = null;
try
{
st = conn.createStatement();
while (s.hasNext())
{
String line = s.next().trim();
if (!line.isEmpty())
st.execute(line);
}
}
finally
{
if (st != null)
st.close();
}
}
#Pantelis Sopasakis
Slightly modified version on GitHub: https://gist.github.com/831762/
Its easier to track modifications there.
Regarding SQL script runner (which I'm also using), I noticed the following piece of code:
for (int i = 0; i < cols; i++) {
String value = rs.getString(i);
print(value + "\t");
}
However, in the API documentation for the method getString(int) it's mentioned that indexes start with 1, so this should become:
for (int i = 1; i <= cols; i++) {
String value = rs.getString(i);
print(value + "\t");
}
Second, this implementation of ScriptRunner does not provide support for DELIMITER statements in the SQL script which are important if you need to compile TRIGGERS or PROCEDURES. So I have created this modified version of ScriptRunner: http://pastebin.com/ZrUcDjSx which I hope you'll find useful.
Another interesting option would be to use Jisql to run the scripts. Since the source code is available, it should be possible to embed it into an application.
Edit: took a careful look at it; embedding it inside something else would require some modification to its source code.
Can you use this:
public static void executeSQL(File f, Connection c) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(f));
String sql = "", line;
while ((line = br.readLine()) != null) sql += (line+"\n");
c.prepareCall(sql).execute(sql);
}
This function gets SQL file and DB connection.
Then it reads the file line-by-line using BufferedReader from java.io.
And, finally, executes the read statements.
Java 8+ version:
public static void executeSQL(Path p, Connection c) throws Exception {
List<String> lines = Files.readAllLines(p);
String s = String.join("\n", lines.toArray(new String[0]));
c.prepareCall(s).execute(s);
}
Write code to:
Read in a file containing a number of SQL statements.
Run each SQL statement.
For Oracle PL/SQL, the Oracle JDBC-driver indeed supports executing entire SQL-scripts including stored procedures and anonymous blocks (PL/SQL specific notation), see
Can the JDBC Drivers access PL/SQL Stored Procedures?
The Oracle JDBC driver FAQ has more info:
Oracle JDBC drivers support execution
of PL/SQL stored procedures and
anonymous blocks. They support both
SQL92 escape syntax and Oracle PL/SQL
block syntax. The following PL/SQL
calls would work with any Oracle JDBC
driver:
// SQL92 syntax
CallableStatement cs1 = conn.prepareCall
( "{call proc (?,?)}" ) ; // stored proc
CallableStatement cs2 = conn.prepareCall
( "{? = call func (?,?)}" ) ; // stored func
// Oracle PL/SQL block syntax
CallableStatement cs3 = conn.prepareCall
( "begin proc (?,?); end;" ) ; // stored proc
CallableStatement cs4 = conn.prepareCall
( "begin ? := func(?,?); end;" ) ; // stored func
It should be possible to read in a file and feed the content to the prepareCall()-method.
Maven SQL Plugin Use this plugin to execute SQL statements a file or list of files through
sqlCommand
srcFiles
3.fileset configurations
There isn't really a way to do this.
You could either run the mysql command line client via Runtime.exec(String[]) and read this article when you decide for this option
Or try using the ScriptRunner (com.ibatis.common.jdbc.ScriptRunner) from ibatis. But it's a bit stupid to include a whole library just to run a script.
Here's a quick and dirty solution that worked for me.
public void executeScript(File scriptFile) {
Connection connection = null;
try {
connection = DriverManager.getConnection(url, user, password);
if(scriptFile.exists()) {
var buffer = new StringBuilder();
var scanner = new Scanner(scriptFile);
while(scanner.hasNextLine()) {
var line = scanner.nextLine();
buffer.append(line);
// If we encounter a semicolon, then that's a complete statement, so run it.
if(line.endsWith(";")) {
String command = buffer.toString();
connection.createStatement().execute(command);
buffer = new StringBuilder();
} else { // Otherwise, just append a newline and keep scanning the file.
buffer.append("\n");
}
}
}
else System.err.println("File not found.");
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(connection != null) connection.close();
}