How to write transaction in Mariadb? - mariadb

using query " BEGIN; INSERT INTO employee (id, name) VALUES (:id,:name); COMMIT ;" to commit the transaction through java code and additionally setting id and name parameters but getting below error.
"Caused by: java.sql.SQLSyntaxErrorException: (conn=812) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INSERT INTO employee (id, name) VALUES (150,'150_abc'); COMMIT' at line 1
have tried with belwo query:
start transaction; INSERT INTO employee (id, name) VALUES (:id,:name); COMMIT ;
using MariaDb version 10.7.3

you should try the following :
MOST IMPORTANT TO CONSIDER, IS TO SET THE AUTOCOMMIT TO FALSE, otherwise MariaDB will refuse not automatic transaction management.
import java.sql.*;
public class App {
public static void main(String[] argv) {
try (Connection conn = DriverManager.getConnection("jdbc:mariadb://192.0.2.1:3306?user=db_user&password=db_user_password")) {
conn.setAutoCommit(false);
try {
try (PreparedStatement prep = conn.prepareStatement("INSERT INTO test.accounts(first_name, last_name, email, amount) VALUES (?, ?, ?, ?)")) {
prep.setString(1, "John");
prep.setString(2, "Smith");
prep.setString(3, "john.smith#example.com");
prep.setDouble(4, 900.00);
prep.executeQuery();
}
try (PreparedStatement prep = conn.prepareStatement("UPDATE test.accounts SET amount = ? WHERE email = ?")) {
prep.setDouble(1, 1000.00);
prep.setString(2, "john.smith#example.com");
prep.executeQuery();
}
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
conn.rollback();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Related

JdbcTemplate to batchUpdate to multiple tables at same time

JdbcTemplete.batchUpdate() can take a prepared statement and can fire off a number of inserts to the same table.
String sql = "INSERT INTO MYTABLE (COL1, COL2) VALUES (?, ?)"
List params = ...
jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i) throws SQLException {
List<String> singleRowParams = params.get(i);
ps.setString(1, singleRowParams.get(0));
ps.setString(2, singleRowParams.get(1));
}
// This is the number of times to run the SQL statement.
public int getBatchSize() {
return params.size();
}
}
);
How do I insert into mutliple tables in the one batch update, is that even possible?
Thanks
No it's not possible. Think about if you were trying to run this SQL manually, how would you go about doing it? An alternative would be to iterate over your updates and amend the SQL each time for the relevant table(s).

cursor program generating sqlexception ordinal binding and named binding cannot be combined

I have created a program using CallableStatement and Cursors to fetch the records from a table named Student with names starting from 'A' with pl/sql procedures.The program is giving an SQLException: java.sql.SQLException: operation not allowed: Ordinal binding and Named binding cannot be combined!
please help me out to resolve this..
the procedure is:
create or replace procedure get_StudDetails(mycur out sys_refcursor,cond in varchar)
as
begin
open mycur for
select * from Student where stname like cond;
end;
/
the java program is:
import java.sql.*;
import oracle.jdbc.driver.*;
class CursorTest
{
public static void main(String s[])
{
try
{
Connection con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:orcl","rt","pwdd");
CallableStatement cs=con.prepareCall("{call get_StudDetails(?,?)}");
cs.getString(2+"A%");
cs.registerOutParameter(1,OracleTypes.CURSOR);
cs.execute();
System.out.println("procedure invoked");
ResultSet rs=(ResultSet)cs.getObject(1);
while(rs.next())
{
System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3)+"\t"+rs.getString(4));
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Don't use getString but setString instead:
CallableStatement cs=con.prepareCall("{call get_StudDetails(?,?)}");
cs.registerOutParameter(1,OracleTypes.CURSOR);
cs.setString(2, "A%");
cs.execute();

JavaFX Sqlite Insert with Foreign Key

I am currently learning JavaFX and Sqlite.
I have an Sqlite Database which I built with MySQL manager, there are already foreign key rules etc.
For example user and adress:
CREATE TABLE "Benutzer" ("Benutzername" TEXT PRIMARY KEY NOT NULL , "Vorname" VARCHAR, "Nachname" VARCHAR, "Email" TEXT UNIQUE , "Passwort" TEXT, "AdresseID" INTEGER, FOREIGN KEY(AdresseID) REFERENCES Adresse(AdresseID))
CREATE TABLE "Adresse" ("AdresseID" INTEGER PRIMARY KEY NOT NULL , "Land" VARCHAR, "Stadt" VARCHAR, "Straße" TEXT, "Hausnr." INTEGER)
I connected the database to my JavaFX application, now I am trying to create the register function, so a new user is on an fxml template where he can fill in "Benutzername", "Vorname" etc. and his adress "Land", "Stadt" etc.
Here is the form:
Adding these values to the database works, but I do not have an idea how to tell javaFX that this current user which is inserted has to take the current adress which is inserted (its AdressID) as foreign key.
User is inserted without foreign key:
I was reseaching and found things like
mysql_insert_id returns the last auto-increment value generated by the database connection currently in use.
But I dont know how to access it.
Thats my model which I use to fill in the data into my database:
public class RegisterModel {
Connection conection;
// Konstruktor
public RegisterModel() {
conection = SqliteConnection.Connector();
// Wenn die Verbindung nicht erfolgreich ist, dann App schließen
if (conection == null) {
System.out.println("connection not successful");
System.exit(1);
}
}
public boolean isDbConnected() {
try {
return !conection.isClosed();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
}
public boolean RegisterUser(String user_benutzername, String user_vorname, String user_nachname, String user_email,
String user_passwort, String adress_land, String adress_stadt, String adress_strasse,
String adress_hausnummer) throws SQLException {
PreparedStatement preparedStatement = null;
PreparedStatement preparedStatement_for_adress = null;
// or ignore besprechen
String query = "insert or ignore into Benutzer (Benutzername, Vorname, Nachname, Email, Passwort) values(?,?,?,?,?)";
String query_adress = "insert into Adresse (Land, Stadt, Straße, 'Hausnr.') values(?,?,?,?)";
try {
preparedStatement = conection.prepareStatement(query);
preparedStatement.setString(1, user_benutzername);
preparedStatement.setString(2, user_vorname);
preparedStatement.setString(3, user_nachname);
preparedStatement.setString(4, user_email);
preparedStatement.setString(5, user_passwort);
System.out.println("Benutzer wurde eingefuegt");
preparedStatement_for_adress = conection.prepareStatement(query_adress);
preparedStatement_for_adress.setString(1, adress_land);
preparedStatement_for_adress.setString(2, adress_stadt);
preparedStatement_for_adress.setString(3, adress_strasse);
preparedStatement_for_adress.setString(4, adress_hausnummer);
System.out.println("Adresse wurde eingefügt");
preparedStatement.executeUpdate();
preparedStatement_for_adress.executeUpdate();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
preparedStatement.close();
preparedStatement_for_adress.close();
}
}
}
I think there must be a 3rd query which takes the AdressID of the current adress and assigns it to the current user as his adress? So thats the interessting part:
String query = "insert or ignore into Benutzer (Benutzername, Vorname, Nachname, Email, Passwort) values(?,?,?,?,?)";
String query_adress = "insert into Adresse (Land, Stadt, Straße, 'Hausnr.') values(?,?,?,?)";
You should insert the Address first with a PreparedStatement.
Retrieve the ID (last inserted ID) of the Address, see Java PreparedStatement retrieving last inserted ID
Now insert the User with the AddressId stated in step 2. So you have to include the AddressId column in the user INSERT INTO statement.
Your user insert query should become:
String query = "insert or ignore into Benutzer (Benutzername, Vorname, Nachname, Email, Passwort, AddressId) values(?,?,?,?,?,[put last_inserted_id here)";

How to check table is empty with count(*)

I am trying to check if a table is empty. I code this method:
public boolean checkIfNULL()
throws SQLException, ClassNotFoundException {
boolean flag=false;
System.out.println("Checking if table is empty...");
String sq = "select count(*) from TABLE1";
try {
Class.forName(typeDB);
c = DriverManager.getConnection(path);
stm = c.prepareStatement(sq);
PreparedStatement stm = c.prepareStatement(sq);
int rowsAffected = stm.executeUpdate();
if(rowsAffected == 0)
flag=true;
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
if (stm != null) {
stm.close();
}
if (c != null) {
c.close();
}
}
return flag;
}
but sth wrong is hapenning and I get an error message
Query returns results
Exceptionn: java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (Connection is closed)
How I check the returning value of check?
UPDATE 1:
Instead of the query above, I tried also SELECT EXISTS(SELECT 1 FROM TABLE1)
but the same is happening..
UPDATE 2:
I used this:
ResultSet rs = stm.executeQuery();
if(!rs.next())
flag=true;
else
System.err.println("ERROR - The table has records...");
and it prints the ERROR - "The table has records...". How is this possible? I see the table through SQLite manager and it is empty!
You are executing a SELECT, so you need to use executeQuery, not executeUpdate. executeUpdate is for statements like UPDATE, DELETE and INSERT, executeQuery is for executing statements that return a result set (like SELECT).
You need to execute a select statement, and do:
try (ResultSet rs = stm.executeQuery()) {
rs.next(); // You always have a row, with the count
int count = rs.getInt(1);
flag = count == 0;
}
The code in your update won't work, because if you do a SELECT count(*) FROM table, then you always have one row (with the count).

Blackberry sqlite - Cannot prepare already prepared statement exception

In blackberry sqlite while executing the below code i getting exception "Cannot prepare already prepared statement"
public Department[] getDepartment()
{
Department[] department = null;
try
{
database = DatabaseFactory.open(myURI);
Statement st = database.createStatement("SELECT code, name, status FROM Department");
st.prepare();
Cursor c = st.getCursor();
Row r;
int i = 0;
department = new Department[i];
while(c.next())
{
r = c.getRow();
i++;
Department dept = (Department) r.getObject(i);
department[i] = dept;
}
st.close();
database.close();
}
catch ( Exception e )
{
System.out.println("Exception occured --------------" +e.getMessage());
}
return department;
}
anybody know solution for this
The st.prepare() is only necessary if the statement is not prepared, which means:
The statement references an external variable
The statement references a computed variable
In this case, neither is the case, so the statement is redundant.
References
SQLite: File History - prepare.c
Getting “Re-preparing already prepared query” warning with caching enabled · Issue #581 · Netflix/astyanax · GitHub
SQLite: View Ticket - Repreparation errors are always returned as SQLITE_SCHEMA

Resources