I have 3 tables, called Drivers, Offences and Points and Sofar I'm using 3 sql Strings to insert and update data in the tables
String command1 = "INSERT INTO Drivers (IDNumber, FirstName, LastName) VALUES" + drivID + FName + LName;
String command2 = "INSERT INTO Offences(IDNumber, SpeedLimit, DriverSpeed, SeatBelt, DrunkenDriving, DriversLicense) VALUES" + drivID + intspeed + intDSpeed + strSeat + strDrunk + strLicense;
String command3 = "INSERT INTO DriverPoints(IDNumber, Points) VALUES" + drivID + intpoints;
Each table is coneccted to eachother through the primary key IDNumber
Is there a way instead of having 3 Sql commands/Strings where I can have only 1 but still be able to insert and update all 3 tables?
Roughtly your query should look like this:
SELECT d.IDNumber, d.FirstName, d.LastName, o.SpeedLimit, o.DriverSpeed, o.SeatBelt, o.DrunkenDriving, o.DriversLicense, p.Points
FROM Drivers d
JOIN Offences o on (d.IDNumber = o.IDNumber)
JOIN DriverPoints p on (d.IDNumber = p.IDNumber)
WHERE (...) -- Whathever where condition you like
This will read everything.
For updating you have to perform 3 distinct updates statements or use a stored procedure or a view, but this really depends on the database you're using.
EDIT: for insert I suggest you to use PreparedStatements
String command1 = "INSERT INTO Drivers (IDNumber, FirstName, LastName) VALUES (?, ?, ?)";
PreparedStatement ps = connection.prepareStatement(command1);
ps.setInteger(1, drivID );
ps.setString(2, FName );
ps.setString(3, LName );
ps.execute();
Write a Stored Procedure.
However to make it platform independent, you should use ANSI SQL syntax.
As per BigMike's comment, you could also create a view. This will throw more light on creating a view.
You can't insert into multiple tables with one statement, so the short answer is no. You will need three statements to insert into three tables.
Also, your syntax needs to be more like:
String command1 = "INSERT INTO Drivers (IDNumber, FirstName, LastName) VALUES (" + drivID + ", " + FName + ", " + LName + ")";
Note the addition of the commas and braces.
Also, you can put all of the statements into the one query, if that is what you mean.
Related
ok, I am a newbie. I have two ArrayList and I want to insert data from the arralylist to table. one arraylist is for the table parameters to insert and other arraylist for inserting the values of the table.
I have tried searching if there was a dynamic way to insert but could not find any.
ArrayList<String> list= new ArrayList<>();
ArrayList<String> values= new ArrayList<>();
list.add("userid");
list.add("name");
list.add("email");
values.add(userID);
values.add(name);
values.add(email);
String sql = "insert into users (" + list + ") values( " + values + ")";
stmt.executeUpdate(sql);
I want to insert the data into the table. but parameters like userid should be in ''(quotes) and name should be in ''(quotes). but they are not converted automatically. is there any other way to do the same task?
IS there any way to get the data from JSON and insert into tables locally?
You should not not concatenate values like that into a SQL String. Use a PreparedStatement instead:
String sql = "insert into users (userid, name, email) values (?,?,?)";
PreparedStatement pstmt = connection.prepareStatement(sql);
The preferred way to insert multiple rows, is to use batching
for (int i=0; i < values.size(); i++) {
pstmt.setString(i+1, values.get(i);
}
pstmt.executeUpdate();
Passing a value for a column name userid as a String seems to be wrong to begin with. Usually those are stored as integers.
You can use String.join method to compose the query:
String sql = "insert into users (" + String.join(", ", list) + ") values( '" + String.join("', '", values) + "')";
But such by-hand sql composing from raw Strings is dangerous and can be vulnerable to injection attacks. I suggest using other solutions like orm.
I try to insert a String into a hsqldb an it gives me this error:
> java.sql.SQLSyntaxErrorException: user lacks privilege or object not
found: S
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
the column is set to VARCHAR(50) and the sqlstring is build like this:
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +"," + "\""+ emergency.typeD +"\"" + "," + "\""+
emergency.typeB +"\"" + ","+ emergency.floorID + ")";
this ist how i execute the query:
Statement st = null;
st = con.createStatement(); // statements
int i = st.executeUpdate(sql); // run the query
PS: I know i am open to a sqlInjection like this.
EDIT: values are
sql = "INSERT INTO Emergency Values(0,1,"S","IB",1)"
If i change the string to ;
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +","+ emergency.typeD +","+ emergency.typeB +","+
emergency.floorID +")";
the same error occures
Use a PreparedStatement and you won't have problems:
String sql =
"INSERT INTO Emergency (emergency_id, status, type_d, type_b, floor_id) " +
" Values (?, ?, ?, ?, ?)";
Note that I explicitly listed the column names in the insert statement. Not doing that is considered bad coding style.
I had to guess those names as you didn't show us the definition of your table. You have to replace with the correct column names of your table.
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
The root cause of your problem was the incorrect usage of double quotes: ". String constants have to be put in single quotes in SQL. 'foobar' is a string value. Double quotes are used for identifiers "foobar" is e.g. a column name.
Unrelated, but: the use of Counter.emergencyID lets me think that your are generating (or trying to) unique IDs in your application. Don't do that. Use a sequence or identity column in the database. Do it correctly from the beginning. For a single user application this might not make a difference, but there is no way you can implement that correctly and scalable in an application that is used by multiple users at the same time, with concurrent transactions inserting into the same table.
i found the error in #a_horse_with_no_name 's code
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
note the last line, it should be
int i = pstmt.executeUpdate(); // run the query
please refer to HSQLDB cryptic exception message: "feature not supported"
I know the question is old, but I ran into the same problem and found my a solution without using PreparedStatements.
INSERT INTO TypeA (id) VALUES ("Hello");
failed (user lacks privilege or object not found: Hello ), but
INSERT INTO TYPEA (id) VALUES ('Hello');
worked. So it seems like double quotes are not accepted (see also http://www.hsqldb.org/doc/1.8/guide/ch09.html#expression-section )
i need some solution from my foreign key in inserting a FK ID the problem is when i insert the ID, and the Payment it will insert first Customer_ID and the second is default to null value and on next column it will set to the inserted and the other one is null here's my code
pStmt2 = conn.prepareStatement("insert into Audittrail_tbl (Customer_ID) values ((Select Name_ID from Customer_tbl where FName ='"+txtFName.getText()+"' and LName = '"+txtLName.getText()+"'))");
pStmt2 = conn.prepareStatement("insert into Audittrail_tbl (Payment) values ('"+txtPayment.getText()+"')");
pStmt2.executeUpdate();
Your code should be:
String sql = "insert into Audittrail_tbl (Customer_ID, Payment)" +
" select Name_ID, ?" +
" from Customer_tbl" +
" where FName = ?" +
" and LName = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, txtPayment.getText());
stmt.setString(2, txtFName.getText());
stmt.setString(3, txtLName.getText());
stmt.executeUpdate();
}
Or better yet, if Payment is an amount column:
// Using BigDecimal
stmt.setBigDecimal(1, new BigDecimal(txtPayment.getText()));
// Using Double
stmt.setDouble(1, Double.parseDouble(txtPayment.getText()));
Since that will parse the text to number in Java code, where you can better handle parse errors.
Note: Using insert-from-select, instead of insert-values with a subquery, will allow you to select multiple columns from Customer_tbl if needed.
You're doing two inserts, which creates two records. if you want to update the record created by the first query, you need to UPDATE for the second query instead.
And why use two queries? Why not
pStmt2 = conn.prepareStatement("
insert into Audittrail_tbl (Customer_ID, Payment)
values (
(Select Name_ID from Customer_tbl where FName ='"+txtFName.getText()+"' and LName = '"+txtLName.getText()+"'),
'"+txtPayment.getText()+"')");)");
Of course, that won't work as-is (I'm too lazy to check quote/bracket matching), but should give you the general idea.
I want to use several times the same values.
If I use in dbForge for MySQL next query,
SET #v1 = 123, #v2='2014-04-11', #v3 = 'user1', #v4='title1';
INSERT INTO test_table (TID, CREATED, OWNER, TITLE)
VALUES (#v1,#v2,#v3,#v4)
ON DUPLICATE KEY UPDATE
CREATED=#v2, OWNER=#v3, TITLE=#v4
it correctly executes, but in Java, when I use code
final String dbQuerry = "SET #v1 = %s, #v2='%s', #v3 = '%s', #v4='%s';\n"+
"INSERT INTO test_table (TID, CREATED, OWNER, TITLE)\n" +
"VALUES (#v1,#v2,#v3,#v4)\n" +
"ON DUPLICATE KEY UPDATE\n" +
"CREATED=#v2, OWNER=#v3, TITLE=#v4";
String currentQuerry = String.format(dbQuerry, t.getParam("ID"),
t.getParam("Date"),
t.getParam("User"),
t.getParam("Title"));
mDBStatement.execute(currentQuerry);
I have an exception
SQL Exception: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near 'INSERT INTO test_table (TID, CREATED, OWNER, TITLE) VALUES
(#v1,#v2,#v3,#v4) ON ' at line 2
I can use something like this
final String dbQuerry = "INSERT INTO test_table (TID, CREATED, OWNER, TITLE)\n" +
"VALUES (?,?,?,?)\n" +
"ON DUPLICATE KEY UPDATE\n" +
"CREATED=?, OWNER=?, TITLE=?";
PreparedStatement st = mDBConnection.prepareStatement(dbQuerry);
st.setInt(1, Integer.valueOf(t.getParam("ID")));
st.setString(2, t.getParam("Date"));
st.setString(5, t.getParam("Date"));
st.setString(3, t.getParam("User"));
st.setString(6, t.getParam("User"));
st.setString(4, t.getParam("Title"));
st.setString(7, t.getParam("Title"));
But it looks ugly.
Is there is a way to solve this problem?
One option is to use the special VALUES() function to reference the value that would have been inserted into a column, if the INSERT had succeeded, like this:
...
ON DUPLICATE KEY
UPDATE CREATED = VALUES(CREATED)
, OWNER = VALUES(ONWER)
, TITLE = VALUES(TITLE)
The latter form in your example is preferred, using placeholders for the bind variables. What's ugly is having to supply the same value twice.
I'd recommend something like this:
final String dbQuerry = "INSERT INTO test_table (TID,CREATED,OWNER,TITLE)\n" +
" VALUES (?,?,?, ?)\n" +
" ON DUPLICATE KEY UPDATE\n" +
" CREATED=VALUES(CREATED), OWNER=VALUES(OWNER), TITLE=VALUES(TITLE)";
PreparedStatement st = mDBConnection.prepareStatement(dbQuerry);
st.setInt(1, Integer.valueOf(t.getParam("ID")));
st.setString(2, t.getParam("Date"));
st.setString(3, t.getParam("User"));
st.setString(4, t.getParam("Title"));
And that's not ugly. That's the normative pattern.
Using the special VALUES() function is especially useful if we're upserting more than one row, either with a VALUES clause e.g.
INSERT INTO fee (fi, fo, fum)
VALUES
(1,'doo','dah'),(2,'menom','menah'),(3,'buhdeep','uhdeepee')
ON DUPLICATE KEY
UPDATE fo = VALUES(fo)
, fum = VALUES(fum)
Or, with an INSERT ... SELECT form:
INSERT INTO fee (fi, fo, fum)
SELECT t.ay, t.bee, t.cee FROM sometable t
ON DUPLICATE KEY
UPDATE fo = VALUES(fo)
, fum = VALUES(fum)
BTW... the error being returned from the first form is the type of error we'd expect if allowMultiQueries=true is not included in the connect string. Note that enabling multiple queries per execution effectively disables a security feature.
Consider carefully the SQL text that would be generated and sent to the database with some carefully crafted values:
val = "foo'; DROP TABLE students; --"
Using a prepared statement (with static SQL text with placeholder for bind variables, as in the example above) prevents this mode of SQL injection. And disallowing multiple statements in a single execution is another way to thwart SQL injection attacks.
I believe the # variables are used in stored procedures only...
Either you define a stored procedure or you can use the second option :
final String dbQuerry = "INSERT INTO test_table (TID, CREATED, OWNER, TITLE)\n" +
"VALUES (?,?,?,?)\n" +
"ON DUPLICATE KEY UPDATE\n" +
"CREATED=?, OWNER=?, TITLE=?";
PreparedStatement st = mDBConnection.prepareStatement(dbQuerry);
st.setInt(1, Integer.valueOf(t.getParam("ID")));
st.setString(2, t.getParam("Date"));
st.setString(5, t.getParam("Date"));
st.setString(3, t.getParam("User"));
st.setString(6, t.getParam("User"));
st.setString(4, t.getParam("Title"));
st.setString(7, t.getParam("Title"));
I need to insert into three tables at once for now. But in the future I will be inserting in more than three tables.
All the three tables have same columns and same data types. So I can insert the same data into three tables as well. Currently I am inserting into one table.
I am working with new database named XpressMP. And it supports all the major SQL syntax.
public final static String INSERT_SQL = "INSERT INTO COPY"
+ "("
+ "ID, ACCOUNT) VALUES"
+ "(?, ?)";
preparedStatement = dbConnection.prepareStatement(INSERT_SQL);
preparedStatement.setString(1, id);
preparedStatement.setString(2, ACCOUNT);
What will be the best way to insert into three tables at once? It is possible to do in a SQL? Or I need to make a change in the Java code to insert into multiple tables?
You cannot parameterize the table name part. You can create String with tablename and ?, then use that string for preparedStatement.
String tablename="COPY";
public final static String INSERT_SQL = "INSERT INTO " + tablename
+ "("
+ "ID, ACCOUNT) VALUES"
+ "(?, ?)";
preparedStatement = dbConnection.prepareStatement(INSERT_SQL);
preparedStatement.setString(1, id);
preparedStatement.setString(2, ACCOUNT);