Using DB2 Sequence in Java Prepared Statement - java

I want to get the next value of a db2 sequence if the placeholder in the preparedstatement is 0 . How can i do that .
PreparedStmt.setLong(1, attributeID);
So here if attributeID is 0, i want to get the next value from the sequence, other wise i use the attribute ID .
I tried using
PreparedStmt.setObject(1, attributeID > 0 ? attributeID : next val for my seq);
but this does not work !

It's to easy, just get the sequence like you get a result set with executeQuery() method. Then the select statement is:
SELECT SEQ_NAME.NEXTVAL FROM SYSIBM.SYSDUMMY1
The other part is an if sentence. That's all you need to do.

You can declare the primary key column as
ATTRIBUTEID BIGINT GENERATED BY DEFAULT AS IDENTITY
To insert a row with a specific value, include the primary key column in the sql and set its value with:
PreparedStmt.setLong(1, attributeID);
To insert a row where database generates a value for key, omit the primary key column in the sql and do not set its value in the prepared statement.

Related

MySQL Simple Query Error

I am new to MySQL and I wrote a simple query bellow:
CREATE Table tblFeedBack
(
`FeedBackID` INT AUTO_IncremeNT,
`UserID` INT,
`Inserted_TS` TIMESTAMP ,
`FeedBackValue` VARCHAR(100),
PRIMARY KEY (FeedBackID)
);
CREATE PROCEDURE tblFeedBack_InsertUpdate
(
IN U_ID INT,
IN FB_Value VARCHAR(50)
)
BEGIN
IF ((Select COUNT(*) From 'tblFeedback') < 3)
BEGIN
INSERT INTO 'tblFeedBack' (`UserID`,`FeedBackValue`)
VALUES (U_ID,FB_Value);
END
ELSE
BEGIN
DECLARE #MostRecentFID INT;
SELECT TOP 1 `FeedBackID` FROM tblFeedback
WHERE UID = U_ID
ORDER BY `Inserted_TS` DESC
INTO #MostRecentFID;
UPDATE tblfeedback
SET `FeedBackValue` = #FeedBackValue
WHERE `FeedBackID` = #MostRecentFID
END
END
I am getting this error:
Schema Creation Failed: 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 ''tblFeedBack' (`UserID`,`FeedBackValue`) VALUES (1,'12')' at line 9
Can anyone please help me solve this one?
Thanks in advance.
MySQL does not supportĀ TOP you want to use LIMIT 1 instead as they are ordered.
Select `FeedBackID` FROM tblFeedback
WHERE UID = U_ID
ORDER BY `Inserted_TS` DESC
LIMIT 1
INTO #MostRecentFID;
Also, when you query a table using quotes it becomes case sensitive.
IF ((Select COUNT(*) From 'tblFeedback') < 3)
Should be
IF ((Select COUNT(*) From 'tblFeedBack') < 3)
Fix these 2 errors and it should work.
The table names are different in the insert query. One contains 'tblFeedback' and other contains 'tblFeedBack'
Also, please try to remove single quotes near table names in the query.

How can I get an id for a new record in a generic way? (JOOQ 3.4 with Postgres)

With jooq 3.4 I can't figure out how to do this (with Postgresql):
Query query = dsl.insertInto(TABLE)
.set(TABLE.ID, Sequences.TABLE_ID_SEQ.nextval());
but in a case when I don't know which is the exact table, something like this:
TableImpl<?> tableImpl;
Query query = dsl.insertInto(tableImpl)
.set(tableImpl.getIdentity(), tableImpl.getIdentity().getSequence().nextval());
Is it somehow possible?
I tried this:
dsl.insertInto(tableImpl)
.set(DSL.field("id"),
tableImpl.getSchema().getSequence("table_id_seq").nextval())
This works but I still don't know how to get the sequence name from the TableImpl object.
Is there a solution for this? Or is there a problem with my approach?
In plain SQL I would do this:
insert into table_A (id) VALUES nextval('table_A_id_seq');
insert into table_B (table_A_id, some_val) VALUES (currval('table_A_id_seq'), some_val);
So I need the value or a reference to that id for later use of the id that was generated for the inserted record as default, but I don't want to set any other values.
jOOQ currently doesn't have any means of associating a table with its implicitly used sequence for the identity column. The reason for this is that the sequence is generated when the table is created, but it isn't formally connected to that table.
Usually, you don't have to explicitly set the serial value of a column in a PostgreSQL database. It is generated automatically on insert. In terms of DDL, this means:
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to specifying:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
The above is taken from:
http://www.postgresql.org/docs/9.3/static/datatype-numeric.html#DATATYPE-SERIAL
In other words, just leave out the ID values from the INSERT statements.
"Empty" INSERT statements
Note that if you want to create an "empty" INSERT statement, i.e. a statement where you pass no values at all, generating a new column with a generated ID, you can use the DEFAULT VALUES clause.
With SQL
INSERT INTO tablename DEFAULT VALUES
With jOOQ
DSL.using(configuration)
.insertInto(TABLENAME)
.defaultValues()
.execute();
Returning IDs
Note that PostgreSQL has native support for an INSERT .. RETURNING clause, which is also supported by jOOQ:
With SQL
INSERT INTO tablename (...) VALUES (...) RETURNING ID
With jOOQ
DSL.using(configuration)
.insertInto(TABLENAME, ...)
.values(...)
.returning(TABLENAME.ID)
.fetchOne();

How to get the serial id just after inserting a row? [duplicate]

This question already has answers here:
How to get a value from the last inserted row? [duplicate]
(14 answers)
Closed 9 years ago.
I have a table with row 'id' (a primary key) default set to serial in PostgreSQL. I insert into this row by calling
session.getCurrentSession().createSQLQuery("some insert query")
without adding any value into id as it is default set to serial.
How can I retrieve the `id' of just inserted row?
JDBC statements can return the generated keys. For instance, if the table has a single column id of type serial (probably PK) that is not mentioned in the insert SQL below, the generated value for this column can be obtained as:
PreparedStatement s = connection.createStatement
("INSERT INTO my_table (c,d) VALUES (1,2)",
Statement.RETURN_GENERATED_KEYS);
s.executeUpdate();
ResultSet keys = s.getGeneratedKeys();
int id = keys.getInt(1);
This is faster than sending the second query to obtain the sequence value or max column value later. Also depending on circumstances these two other solutions may not be not be thread safe.
Since it is serial you can use select max(id) from tableName
Using max(id) is a very bad idea. It will not give you the correct result
in case of multiple concurrent transactions. The only correct way is to use
curval() or the returning clause.
In posgresql: There is already a stackoverflow-question exists BTW.
`INSERT INTO tableName(id, name) VALUES(DEFAULT, 'bob') RETURNING id;`
(also)
Get a specific sequence:
SELECT currval('name_of_your_sequence');
Get the last value from the last sequence used:
SELECT lastval();
Manual: http://www.postgresql.org/docs/current/static/functions-sequence.html
For PHP-mysql users:
From php.net clickhere
<?php
$link = mysqli_connect('localhost', 'mysql_user', 'mysql_password');
if (!$link) {
die('Could not connect: ' . mysqli::$connect_error() );
}
mysqli::select_db('mydb');
mysqli::query("INSERT INTO mytable (product) values ('kossu')");
printf("Last inserted record has id %d\n", mysqli::$insert_id());
?>
But you need to connect for every query.
use SELECT CURRVAL(); . Typically used in conjunction with pg_get_serial_sequence
postgreSQL function for last inserted ID

Insert only if row doesn't exist

I am using PreparedStatement to prepare sql queries. I want to insert a row in table if and only if it doesn't exist.
I tried this -
INSERT INTO users (userId) VALUES (?) ON DUPLICATE KEY UPDATE userId = ?
But this will unnecessarily update the userId.
How can i insert the userId here ?
INSERT INTO users
(userId)
SELECT ?
WHERE NOT EXISTS
(
SELECT *
FROM users
where userId = ?
)
You may use
INSERT IGNORE INTO users (userId) VALUES (?)
But you should understand why do you want ignore errors.
on duplicate key does not work correctly when the table is an innodb. It creates exactly the problem you are describing. If you need the functionality of an innodb, then should you first check the existence of the row, otherwise can you convert the table to a myisam table.
edit: if you need to check the existence of the row before the decision to insert or update, then would I advice you to use a stored procedure.
DELIMITER //
CREATE PROCEDURE adjustusers(IN pId int)
BEGIN
DECLARE userid int;
select count(id) into userid from users where id = pId;
if userid = 1 then
update users set id = pId where id = pId;
else
insert into users(id) values(pId);
end if;
END //
DELIMITER ;
A stored procedure is precompiled, just as a prepared statement. Hence no SQL injection problems and some more functionality and only one call to the database.

Mysql&MSAccess: insert into table which have an incremented field

I am sorry if there is a duplicate but I tried all ways still I can't do the insertion.
I have a table with only two fields ( ID , Name )
When I run this SQL code it must be insert a new record and increment the ID field automatically
because it's auto increment but unfortunately don't work .
See the trail and errors :
MYSQL :
PreparedStatement pr = con.prepareStatement("insert into names(name) values(?)");
pr.setString(2,"Azad");
java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 1).
insert into names(id,name) values(?,?)
java.sql.SQLException: No value specified for parameter 1
MS Access :
insert into names(name) values(?)
java.lang.ArrayIndexOutOfBoundsException: 1
insert into names(id,name) values (?,?)
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]COUNT field incorrect
What's the reason of those errors ? and how to solve it ?
Thanks for suggestions and answers.
change pr.setString(2,"Azad"); to pr.setString(1,"Azad");
The first parameter is related to the position of the ? in the prepared statement, not the column index in the table.
java.sql.SQLException: No value specified for parameter 1. This is down to the fact that you have specified two parameters for the query. But have only specified one value, for the second parameter. If "ID" is an auto incremented column then you don't need to pass in a value. If its not then
pr.setString(1,IDVALUE);
pr.setString(2,"Azad");

Categories