SQL update not working with integer ID - java

This command on SQL Server
UPDATE tbl SET name='Hi' WHERE id=''
works if 'id' is set as an integer value, but it does not work on H2.
What may be the solution?

If ID is integer, you shouldn't use quotes for the value:
UPDATE TEST SET NAME='Hi' WHERE ID = 5; // not ID = '5'
Many databases will accept the quoted version, but are not required to by the SQL language specification.

UPDATE TEST SET NAME='Hi' WHERE ID='1';
that is working in sql server even if id field is integer
but if you want to update the row where id is null then you have to use below statement :
UPDATE TEST SET NAME='Hi' WHERE ID is Null;
instead of UPDATE TEST SET NAME='Hi' WHERE ID ='';
And if id is varchar then you can use your statement to update the values where ID is not null and data is not available there.
But if you want to update the values for record where NULL value of ID field then you have to use
UPDATE TEST SET NAME='Hi' WHERE ID is Null;

H2 throws an exception because it can't convert the empty string '' to a number. H2 internally uses java.lang.Long.parseLong("") which fails with java.lang.NumberFormatException: For input string: "".
For the SQL script:
drop table tbl;
create table tbl(id int primary key, name varchar(255));
insert into tbl values(1, 'Hello');
UPDATE tbl SET name='Hi' WHERE id='';
H2 will throw the exception:
Data conversion error converting [22018-161]
Most other databases (PostgreSQL, Apache Derby, HSQLDB) throw a similar exception.
You need to use a number, or IS NULL as in:
UPDATE tbl SET name='Hi' WHERE id IS NULL;
or
UPDATE tbl SET name='Hi' WHERE id = 0;

Related

JDBC. Replace in all rows value of the column

Java 11. PostgreSQL.
Having following table in db:
TABLE public.account (
id bigserial NOT NULL,
account_id varchar(100) NOT NULL,
display_name varchar(100) NOT NULL,
is_deleted bool NULL DEFAULT false,
);
There are about 1000 rows in this table. In the code I have a static method, which return random string - Helper.getRandomName()
How, using JDBC, in this table (public.account) for all rows replace "display_name" value with value of Helper.getRandomName()?
This is a SQL question. You need to run an update query:
UPDATE public.account set display_name = ?
And provide the new name as the parameter. The absence of a WHERE clause means that all rows will be affected.
If you want to do this for each row individually, then it's harder. You'll want to do a select statement to find all the IDs, and then you can prepare a batch of updates using JDBC, adding a where clause for each ID.
JDBC is just a thin Java wrapper around plain SQL execution.

Merge and When Matched query giving an error sql server

I have a query which I am trying to test. The query should update the data if it finds data in the table with existing primary key. If it doesn't then insert into the table.
The Primary key is of type int and in the properties I can see Identity is set to "True" which I assume it means that it will automatically set the new id for the primary if it is inserted.
MERGE INTO Test_table t
USING (SELECT 461232 ID,'Test1-data' Fascia FROM Test_table) s
ON (t.ID = s.ID)
WHEN MATCHED THEN
UPDATE SET t.Fascia = s.Fascia
WHEN NOT MATCHED THEN
INSERT (Fascia)
VALUES (s.Fascia);
The issue here is this query doesn't work and it never inserts the data or updates. Also, query gets compiled and I don't get any compilation error
Also the reason I want this query is to work because then I will use Java prepared statement to query the database so I am assuming I can do
SELECT ? ID,? Fascia FROM Test_table
So that I can pass the values with set methods in java.
Please let me know if there is something wrong in my query.
You are selecting from the target table as your source.
You either need to remove your FROM Test_table or have at least 1 row in Test_table prior to your merge.
rextester demo: http://rextester.com/XROJD28508
MERGE INTO Test_table t
USING (SELECT 461232 ID,'Test1-data' Fascia --FROM Test_table
) s
ON (t.ID = s.ID)
WHEN MATCHED THEN
UPDATE SET t.Fascia = s.Fascia
WHEN NOT MATCHED THEN
INSERT (Fascia)
VALUES (s.Fascia);

MySQL inserting data while only knowing 1 column name

I am wanting to insert some data into a MySQL table, these are the columns:
uuid | id_1 | id_41
the "id_1" and "id_41" could be anything, all I know is the primary key (uuid) and I am wanting to be able to insert into the table while only knowing the uuid column value as I am doing this so far:
PreparedStatement newPlayer = "INSERT INTO `test` values(?);";
newPlayer.setString(1, event.getPlayer().getUniqueId().toString());
But when I test it, it doesn't add to the table and does not produce any errors. I also know that all of the other values have a default value of 0
If you want to add a row without all columns included, you need to specify the column's name
INSERT INTO `test` (`uuid`) values(?);
Simple tell to insert the column you want insert eg for uuid
INSERT INTO `test` ( `uuid`) values(?);

Add default value when field is null with MyBatis

I want to insert the default value from database when my field is null. I use an Oracle Database.
CREATE TABLE "EMPLOYEE"
("COL1" VARCHAR2(800) NOT NULL ENABLE,
"COL2" VARCHAR2(100) DEFAULT NOT NULL 'toto',
CONSTRAINT "PK_EMPLOYEE" PRIMARY KEY ("COL1")
with a simple SQL request, we can write:
insert into EMPLOYEE(COL1,COL2) values ('titi', default)
How can i do this with annotations MyBatis in Spring? I must create an HandlerType?
In mapper XML, build dynamically the SQL (add the col2 column and value when not null):
insert into employee (col1<if test="col2 != null">, col2</if>)
values (#{COL1}<if test="col2 != null">, #{col2}</if>)
EDIT: since value in annotation must be constant, I used to think dynamic SQl was not possible in annotation, but there is a trick I have found here: How to use dynamic SQL query in MyBatis with annotation(how to use selectProvider)? and checked it myself.
To use dynamic SQL this into an annotation, surround it with "script" tags:
#Insert("<script>insert into employee (col1<if test='col2 != null'>, col2</if>)
values (#{COL1}<if test='col2 != null'>, #{col2}</if>)</script>")
In tests, just escape double quotes " or replace them with simple quotes '
It should work if you omit the COL2 in your colum definition of the insert statement. Because the DB recognizes, that there is no value for the new row and it will apply the default value from the create table statement.
Have you tried something like this?
public interface EmployeeDAO {
String INSERT = "insert into employee (col1) values (#{COL1})";
#Insert(INSERT)
public int insertDefault(PersonDO p) throws Exception;
}

How to populate object property with value generated by Mysql Trigger in MyBatis Insert

I can't get the value back from function. It does an insert on a table and must return a number. The data is insert correctly, but the number returned is always null.
Mysql
create table driver_order (
id int(11) unsigned NOT NULL AUTO_INCREMENT,
area_start varchar(200),
area_end varchar(200),
order_number varchar(200),
create_user varchar(200),
primary key (id)
);
DELIMITER $$
CREATE TRIGGER seq_driver_order_number BEFORE INSERT ON driver_order
FOR each ROW
BEGIN
DECLARE seq_type INT(10);
SET seq_type = getUserNo(NEW.create_user);
SET NEW.order_number = getNextCommSequence("motor", seq_type);
END$$
DELIMITER ;
Mybatis
<insert id="insertOrder" useGeneratedKeys="true" keyProperty="id" parameterType="DriverOrder">
INSERT INTO
DRIVER_ORDER(ID,ORDER_NUMBER,AREA_START,AREA_END,CREATE_USER,CREATE_TIME)
VALUES
(#{id},
#{orderNumber,jdbcType=VARCHAR},
#{areaStart,jdbcType=VARCHAR},
#{areaEnd,jdbcType=VARCHAR},
#{createUser,jdbcType=VARCHAR},
now())
</insert>
The return Object all attributes have correctly value include id, except order_number which TRIGGER set value is return null.
Is there something wrong?
The problem is not with a trigger but how to make mybatis get value generated on mysql side during record insertion. Mybatis is rather simple tool in sense that you can't specify properties to columns mapping and everything else happens automagically.
Mybatis core is sql queries not properties-to-columns mappings like in hibernate for example. So mybatis only executes queries and simplifies setting parameters and construction objects from query result.
Nevertheless starting from version 3.2.6 you can use selectKey to get several values and set properties in the object being inserted. If you combine this with last_insert_id() you can get what you need. For your case it is done like this:
<insert id="insertOrder" parameterType="DriverOrder">
<selectKey keyProperty="id,orderNumber" keyColumn="ID,ORDER_NUMBER" order="AFTER" resultType="java.util.Map">
SELECT ID,ORDER_NUMBER FROM DRIVER_ORDER where ID = last_insert_id()
</selectKey>
INSERT INTO
DRIVER_ORDER(ID,ORDER_NUMBER,AREA_START,AREA_END,CREATE_USER,CREATE_TIME)
VALUES
(#{id},
#{orderNumber,jdbcType=VARCHAR},
#{areaStart,jdbcType=VARCHAR},
#{areaEnd,jdbcType=VARCHAR},
#{createUser,jdbcType=VARCHAR},
now())
</insert>

Categories

Resources