SQL increment id, filling first line of database - eclipse

I habe a sqlite database in java (eclipse) with the library sqlite-jdbc-3.16.1.jar.
I have 5 rows in table1: id(ID Integer PRIMARY KEY AUTOINCREMENT), name, row3, row4, row5
I want to insert name, row3 and row4 and the id to increment itself.
public static void insertTest(String name, byte[] contentRow3, byte[] contentRow4) {
String sql = "INSERT INTO table1(name, contentRow3, contentRow4) VALUES(?,?,?)";
try (Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(2, name);
pstmt.setBytes(3, contentRow3);
pstmt.setBytes(4, contentRow4);
System.out.println("Added new Person to DB");
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
Error : Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
What is the problem here?

Placeholders in Java prepared statements begin at index 1, not 2. I expect that the following corrected code should work:
try (Connection conn = connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, name);
pstmt.setBytes(2, contentRow3);
pstmt.setBytes(3, contentRow4);
System.out.println("Added new Person to DB");
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
The exception you are getting is complaining that index position 3 is out of bounds. Most likely, under the hood when you did pstmt.setBytes(3, contentRow4) this translated to accessing the fourth array element, which would be index 3 assuming the array indexing is zero based.

Related

Column <<column_name>> not found when using ADO-NET connection for Postgresql in insert query

I have problem when using ADO.NET connection for PostgreSQL. I have tried this query using PSQLODBC driver 12.000.000 both ANSI and Unicode. I use PostgreSQL v.9.5. I notice the column name has "_" in its name.
When I use the Select query, the connection successfully execute it. The query return variables as I want.
using (OdbcConnection conn = (OdbcConnection)Dts.Connections["XXX"].AcquireConnection(Dts.Transaction))
{
try
{
if (conn.State != ConnectionState.Open)
{
conn.Open();
}
}
catch (Exception e)
{
String err = e.Message.ToString();
Console.WriteLine(err);
}
try
{
OdbcCommand cmd = new OdbcCommand();
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT XX FROM <<table>> where <<params>>";
...
OdbcDataReader rdd = cmd.ExecuteReader();
while (rdd.Read())
{
<<read operation here>>;
}
conn.Close();
}
catch (Exception ers)
{
<<catch operation here>>;
}
}
But when I use Insert query, it failed to check the column name, even the column are exist in my PostgreSQL tables:
using (OdbcConnection conn2 = (OdbcConnection)Dts.Connections["OJK_REPORTING_DEV"].AcquireConnection(Dts.Transaction))
{
try
{
if (conn2.State != ConnectionState.Open)
{
conn2.Open();
}
}
catch (Exception e)
{
string x = e.Message.ToString();
}
try
{
OdbcCommand cmd = new OdbcCommand();
cmd.Connection = conn2;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "INSERT INTO <<table>>(<<column>>)VALUES(<<params>>)";
<<cmd.Parameters.AddWithValue here>>;
cmd.ExecuteNonQuery();
conn2.Close();
}
catch (Exception e)
{
<<exception catch here>>;
}
}
When I debug this line, I get this error:
ERROR[42703] ERROR: column <> not found, error while executing the query
Right, after several research, I've got an answer. Since i use PostgreSQL ODBC, the query parameters are not using #<name> inside the query, but using ?, so you need to formulate the query like
INSERT INTO <TABLE_NAME> (<COLUMNS>) VALUE ?
and call the parameters
cmd.AddWithValue("#<name>",<value>)

java.lang.NullPointerException occur upon execution

Null pointer exception occurs when you reference a null object, doesn't it? I intend to create an app that manages a store's data such as purchase (stock purchase), stock list, sales, and customer info. The data is intended to be displayed on the app table as soon as the file dynamicmenu1 is run, without clicking any button, but it only displays hard-coded data instead.
app interface
Data to be displayed from table
at view.dynamicmenu1.simpannotaActionPerformed(dynamicmenu1.java:984)
at view.dynamicmenu1.access$1000(dynamicmenu1.java:37)
at view.dynamicmenu1$11.actionPerformed(dynamicmenu1.java:404)
private void simpannotaActionPerformed(java.awt.event.ActionEvent evt) {
tabmodel.addRow(data); // line 984
try {
/** con = (Connection) Model.koneksidatabase();
java.sql.PreparedStatement prepstmnt = con.prepareStatement(sql);
*/
Statement stmnt = con.createStatement();
String sql = "Insert into tb_pembelian VALUES ('" + textid.getText()+"','"
+textnamabrg.getText()+"','"+textqty.getText()
+"','"+texthrg.getText()+"','"+texttgl.getText()+"','"+textsupplier.getText();
//cek stmnt di 'Model.java' di bagian ArrayList barang().
//Mengapa selalu Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
//at view.dynamicmenu1.simpannotaActionPerformed(dynamicmenu1.java:960)
//at view.dynamicmenu1.access$900(dynamicmenu1.java:21)
//at view.dynamicmenu1$10.actionPerformed(dynamicmenu1.java:378)??????
//NullPointerException??????
stmnt.executeUpdate(sql);
stmnt.close();
JOptionPane.showMessageDialog(null, "Data telah disimpan");
kosongkanform();
} catch ( HeadlessException| SQLException e) {
JOptionPane.showMessageDialog(this, e.getMessage());
}
textid.setText("");
textnamabrg.setText("");
textqty.setText("");
texthrg.setText("");
texttgl.setText("");
textsupplier.setText("");
}
// line 37
public class dynamicmenu1 extends javax.swing.JFrame {
String id_barang;
String nama_barang;
String kuantitas;
String harga_satuan;
String tanggal_beli;
DefaultTableModel tabmodel;
Connection con =null;
Statement stmnt=null;
PreparedStatement prepstmnt;
ResultSet res = null;
String sql = null;
the 3rd null pointer exception error
simpannota.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
simpannotaActionPerformed(evt); // Line 404
}
});
Null pointer errors happen when there isn't anything present.
Have you checked your constructor for proper init for your variables.

impossible to retrieve getGeneratedKey from a ResultSet, in an insert previously made in postgresql [duplicate]

This question already has answers here:
How to get the insert ID in JDBC?
(14 answers)
Closed 3 years ago.
I can not recover the generated id after inserting values in the "test" table
Here the create script generated by pgadmi4 of the table "test":
CREATE TABLE school.test
(
test_id bigint NOT NULL DEFAULT nextval('school.test_test_id_seq'::regclass),
name character varying(10) COLLATE pg_catalog."default"
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE school.test
OWNER to postgres;
Here the code to insert the values to the "test" table thourgh JDBC:
Connection conn = pstgConn.dbConnection();
String query = "INSERT INTO school.test(name) VALUES (?)";
try (PreparedStatement pst = conn.prepareStatement(query)) {
pst.setString(1, "anything");
pst.executeUpdate();
// Get Generated Keys
getGeneratdKeys(pst);
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Here the getGeneratedKey function:
public static void getGeneratdKeys(PreparedStatement statement) {
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
generatedKeys.next();
System.out.println(generatedKeys.getLong(1));
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I changed the postgresql jar by a recent version.
Here the error:
org.postgresql.util.PSQLException: The ResultSet is not set correctly, you may need to call next ().
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.checkResultSet(AbstractJdbc2ResultSet.java:2675)
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.getLong(AbstractJdbc2ResultSet.java:1988)
at com.cgi.training.javase.school.dao.testDAO.getGeneratdKeys(testDAO.java:61)
at com.cgi.training.javase.school.dao.testDAO.main(testDAO.java:23)
You need to tell the driver to return the generated key, when you prepare the statement:
PreparedStatement pst = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)
or by passing the names of the columns that are generated keys:
PreparedStatement pst = conn.prepareStatement(query, new String[]{"test_id"});

Unable to know how to link data between two tables

I'm learning RESTful webservices from javabrains website. Here there is a section named Comments and this is related to a message, But I'm unable to know How Can I link these both.
Below is my SQL Tables for Messages and comments.
Messages
Comments
Here Basically, both look pretty same(The table design), but the values differ. And I'm using the below method to send the data.
public Comment addComment(long messageId, Comment comment) throws Exception {
Properties properties = new Properties();
properties.load(getClass().getClassLoader().getResourceAsStream("/config.properties"));
String userName = properties.getProperty("user");
String password = properties.getProperty("pass");
String url = properties.getProperty("Sqldburl");
int key = 0;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection conn = DriverManager.getConnection(url, userName, password);
String query = "select count(*) from Comments";
PreparedStatement ps = conn.prepareStatement(query);
ResultSet rs = ps.executeQuery();
rs.next();
key = rs.getInt(1);
} catch (Exception e) {
System.out.println(e);
}
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection conn = DriverManager.getConnection(url, userName, password);
String query = "insert into Comments(id, message, author) values(?,?,?)";
PreparedStatement ps = conn.prepareStatement(query);
ps.setInt(1, key);
ps.setString(2, comment.getMessage());
ps.setString(3, comment.getAuthor());
ps.executeQuery();
} catch (Exception e) {
System.out.println(e);
}
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
Connection conn = DriverManager.getConnection(url, userName, password);
String query = "select * from Comments where messageId=?";
PreparedStatement ps = conn.prepareStatement(query);
ps.setLong(1, messageId);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
comment.setAuthor(rs.getString("Author"));
comment.setId(rs.getInt("Id"));
comment.setMessage(rs.getString("message"));
}
} catch (Exception e) {
System.out.println(e + "b3");
}
return comment;
}
After writing this code, I've realized that Here I'm adding a comment for sure into Comments table, But it is no where linked to the Messages.
I know a way, that is I've create a new column in the Comments table and using join operation, I need to update the same messageId in comments table. But I want to know if there is a better way of getting this done, without using the concept of joins.
In MessageBean, there is a map declared as below.
private Map<Long, Comment> comments = new HashMap<>();
#XmlTransient
public Map<Long, Comment> getComments() {
return comments;
}
public void setComments(Map<Long, Comment> comments) {
this.comments = comments;
}
can I take any advantage of this to avoid join?

The column name ... was not found in this ResultSet

We are using java jdk 1.7.0_45, postgresql jdbc connector postgresql-9.3-1100.jdbc41.jar.
Here is a synopsis of our problem, as much as possible of code pasted below.
This code:
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("d.deptId"));
Produces the error:
org.postgresql.util.PSQLException: The column name d.deptId was not found in this ResultSet.
This code:
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("deptId"));
Produces no error.
Is there a way, besides removing the "d." from the first query, to make the first code snippet not throw the error message?
Here is the source code:
public class JoinTest {
#Test
public void test(){
boolean pass = false;
try {
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
String label = rs.getMetaData().getColumnLabel(1); // What do you get?
System.out.println("label = " + label);
while (rs.next()){
System.out.println(rs.getInt("d.deptId"));
pass = true;
}
} catch (SQLException e) {
e.printStackTrace();
pass=false;
}
assertTrue(pass);
}
#Test
public void test2(){
boolean pass = false;
try {
ResultSet rs = DbConn.getInstance().doQuery("Select d.deptId from Depts d");
while (rs.next()){
System.out.println(rs.getInt("deptId"));
pass = true;
}
} catch (SQLException e) {
e.printStackTrace();
pass=false;
}
assertTrue(pass);
}
}
public class DbConn {
private static String url = "jdbc:postgresql://server:port/schema";
private static Properties props = new Properties(); {
props.setProperty("user","userid");
props.setProperty("password","passwprd");
}
private Connection conn;
private DbConn(){}
private static DbConn instance;
public static DbConn getInstance() throws SQLException{
if (instance == null){
instance = new DbConn();
instance.conn = DriverManager.getConnection(url, props);
}
return instance;
}
public ResultSet doQuery(String query) throws SQLException{
Logger.log("DbConn.doQuery: " + query);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(query);
return rs;
}
}
}
The query:
select d.deptId from Depts d
produces a single-column resultset with the result-alias "deptId". There is no "d.deptId" column. If you want one, you can request that as the column alias instead:
select d.deptId AS "d.deptId" from Depts d
PgJDBC can't do anything about this because it has no idea that the resultset column "deptId" is related to the "d.deptId" in the select-list. Teaching it about that would force it to understand way more about the SQL it processes than would be desirable, and lead to maintenance and performance challenges.
The second one works - why isn't that acceptable?
You can also do this:
System.out.println(rs.getInt(1));
If you change the query you have to change the code, too.