mybatis query doesnt work well - java

<insert id="insert" parameterType="Dto">
INSERT INTO table VALUES
(GeomFromText('POINT(#{latitude} #{longitude})'))
</insert>
I would like to execute above query, however it returns some error
Cause: java.sql.SQLException: Parameter index out of range (12 >
number of parameters, which is 11).
INSERT INTO filtered_user_location VALUES (GeomFromText('POINT(? ?)'))
I think the error means that prepared statement(?) in a single quotation doesn't work.
do you have any good idea?

Thx Mr.Alien for edit
I fixed query like
GeomFromText('POINT(${latitude} ${longitude})')
then it works well

In read out with this tutorial,
http://mybatis.co.uk/
Its seems to do somthing like this. You dint mention any column name in your query.
insert into filtered_user_location
(columnname1,columnname2)
VALUES
(#{latitude},#{longitude});

Related

JOOQ timestampDiff(field_datetime1, field_datetime2) to set value in an update query not working

I'm using MYSQL and JOOQ and I'm trying to write an update query.
In this query I want to update field_datetime1 (type datetime) and also update field_timedifference (type bigint) with the time difference in milliseconds between field_datetime1 and field_datetime2.
How do I achive that with JOOQ?
I tried to write this code:
update(table)
.set(field_datetime1, now())
.set(field_timedifference, timestampDiff(field_datetime1, field_datetime2))
But it is not compiling, I get this error:
Cannot resolve method 'set(org.jooq.TableField<MyRecordType,java.lang.Long>, org.jooq.Field<org.jooq.types.DayToSecond>, org.jooq.TableField<MyRecordType,java.lang.Long>)'
I tried to wrap it in DSL.val and it does compile but it sends null in the query.
This is the query that I need to run, I tested it on MYSQL workbanch and it is exactly what I need:
update myTable
set field_timedifference =
TIMESTAMPDIFF(microsecond, field_datetime1, field_datetime2)
My coworker investigated and found an easy way to write it:
update(table)
.set(field_datetime1, now())
.set(field_timedifference, DSL.field("timestampDiff({0}, {1}, {2}", Long.class, DSL.keyword(DatePart.MICROSECOND.toSQL()), field_datetime1, field_datetime2))
This way jooq generates an actual query in the set :)

Liquibase preconditions: How do I check for a column being the correct data type?

I have a db upgrade script to change some datatypes on a few columns. I want to do a preCondition check, and call ALTER TABLE only when it is a DECIMAL datatype, but I will want it to be changed to INTEGER.
Couldn't find a predefined precondition for this, and could not write an sqlCheck either.
There's no built-in precondition for column's dataType in liquibase.
You may just check whether the column exists or not. If it's already of the datatype you need, no error will be thrown.
OR
You can use sqlCheck in your preconditions and it'll be something like this:
<preConditions onFail="MARK_RAN">
<not>
<sqlCheck expectedResult="DECIMAL">
SELECT DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'your_table_name'
AND COLUMN_NAME = 'your_column_name'
</sqlCheck>
</not>
</preConditions>
Another answer already mentions how to do a sqlcheck. However, the actual SQL for Teradata would be something different.
In Teradata you would use a query similar to the following and expect the columnType='D' for decimal values
Select ColumnType
From DBC.ColumnsV
Where databasename='yourdatabasename'
and tablename='yourtablename'
and columnname='yourcolumnname';
You could also do something like this if you want a more human readable column type instead of a type code:
Select Type(tablename.columnname);
I know the question was for Teradata, but principle is the same.
I prefer SQL files, so in changelog I have (for Oracle), is:
<include file="roles.sql" relativeToChangelogFile="true" />
and then in roles.sql
there is
--changeset betlista:2022-01-04_2200-87-insert
--preconditions onFail:MARK_RAN
--precondition-sql-check expectedResult:0 select count(*) from ddh_audit.DDH_USER_ROLE where id = 87;
insert into ddh_audit.DDH_USER_ROLE(id, role_name, description)
values(87, 'CONTAINERS_READONLY', 'Can read Containers reference data');
the query added by David Cram would make the trick.
I do not know and I didn't try if condition could be on multiple lines, I know --rollback can.

How to autogenerate two values when inserting at runtime?

I'm using MyBatis as DB framework in JAVA and I'm trying to generate automatically two values when inserting rows in a table: the task id and another value. This is my query:
<insert id="insertTwoValuesSequentialluy" parameterType="com.example.autogenerated.Task" >
<selectKey resultType="java.lang.String" keyProperty="taskId" order="BEFORE" >
select MY_TASK_ID_SEQUENCE.nextval from dual
</selectKey>
insert into DYDA_D.TASK_TABLE (taskId, otherVariable, autogeneratedValue)
values ( #{taskId,jdbcType=VARCHAR},
#{otherVariable,jdbcType=VARCHAR},
MY_SECOND_SEQUENCE.nextval = #{autogeneratedValue,jdbcType=VARCHAR})
</insert>
The code works fine but I'm having the following problem: while at runtime the Task instance gets its member taskId setted, it doesn't happen the same with autogeneratedValue, although when I check the database I can see the column matching autogeneratedValue isn't null for this new row. How can I get autogeneratedValue setted at runtime with no need of making a select query?
PS: don't pay attention to commas and the like, I have lots of columns and I've deleted most of them and changed names on the rest for this snippet. My point with the code is for you to see how I've generated the values, tags I've used etc.
You can do this like this:
<insert id="insertTwoValuesSequentialluy"
parameterType="com.example.autogenerated.Task"
useGeneratedKeys="true"
keyProperty="taskId,autogeneratedValue"
keyColumn="taksId,autogeneratedValue">
insert into DYDA_D.TASK_TABLE (taskId, otherVariable, autogeneratedValue)
values (MY_TASK_ID_SEQUENCE.nextval,
#{otherVariable,jdbcType=VARCHAR},
MY_SECOND_SEQUENCE.nextval)
</insert>

Hibernate - The column name att_id_1 is not valid

For some reason the query that is generated by hibernate is wrong. I have other tables/classes where the generated query is correct however for one table it is wrong. When I do a trace using MS Management Studio I see the following:
exec sp_prepexec #p1 output,NULL,N'select aprresourc0_.agrtid as agrtid1_14_, aprresourc0_.att_id_1 as att_id_2_14_,
aprresourc0_.att_id_2 as att_id_3_14_, aprresourc0_.att_id_3 as att_id_4_14_, aprresourc0_.att_id_4 as att_id_5_14_,
aprresourc0_.attribute_id as attribut6_14_, aprresourc0_.bflag as bflag7_14_, aprresourc0_.client as client8_14_, ...
from aprresourcepost aprresourc0_
where ...
select #p1
The columns att_id_1, att_id_2, att_id_3 and att_id_4 do not exist in the table or my Java class!
How do I fix this? Why does this happen?
It turns out to have been a simple mistake. I continued to work on the project and the next class I was looking at matched the query I was getting in my problem so I checked the code and found I was referencing the wrong class in my code!

Getting MySQLSyntaxErrorException?

I have this code :
String check="SELECT COUNT(*) as check FROM recordstudent WHERE STUDENT_ID="+T_STUDENT_ID+" AND COURSE_ID="+T_COURSE_ID+" AND PACKAGE_ID="+T_PACKAGE_ID+" AND ACTIVITY_ID="+T_ACTIVITY_ID+" AND DATE="+T_DATE+ ";";
rs=myStmt.executeQuery(check);
int ch=0;
while(rs.next()){
ch=Integer.parseInt(rs.getString("check"));
}
if(ch==0)
{
String insertRecord="insert into recordstudent"+
"(STUDENT_ID,COURSE_ID,PACKAGE_ID,ACTIVITY_ID,TEST_NAME,DATE,SCORE,TOTAL_MARKS,PERCENTAGE,CORRECT_ANSWER,TOTAL_QUESTIONS,STUDENT_NAME,SCORE_PER_DIVISION,ATTEMPTS)"+
"VALUES("+
"'"+T_STUDENT_ID+"',"+
"'"+T_COURSE_ID+"',"+
"'"+T_PACKAGE_ID+"',"+
"'"+T_ACTIVITY_ID+"',"+
"'"+T_TEST_NAME+"',"+
"'"+T_DATE+"',"+
"'"+T_SCORE+"',"+
"'"+T_TOTAL_MARKS+"',"+
"'"+T_PERCENTAGE+"',"+
"'"+T_CORRECT_ANSWERS+"',"+
"'"+T_TOTAL_QUESTIONS+"',"+
"'"+T_STUDENT_NAME+"',"+
"'"+T_SCORE_PER_DIVISION+"',"+
"'"+t+"'"
+");";
myStmt.execute(insertRecord);
}
This snippet should insert the data in database only if the ch=0 .But I am getting this error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
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
'check FROM recordstudent WHERE STUDENT_ID=11 AND COURSE_ID=2 AND PACKAGE_ID=11 A'
at line 1
Can Anyone help me and solve my problem ?
Fundamentally: don't build your SQL this way. I notice that you've put quotes round the values in the "insert" SQL statement - but not in the "select" one. That's the start of the problem - but you shouldn't be including values like this in your SQL to start with. You should use parameterized SQL via PreparedStatement, and set values for the parameters. Benefits:
You can see your actual SQL more easily, so you'll be able to spot syntax errors. (This is basically keeping your code separate from your data.)
(Very important) You won't be open to SQL injection attacks
You won't need to worry about conversion issues for numbers, dates and times etc
There are other problems in your SQL (such as spaces and check being a reserved word in MySQL), but the very first thing you should fix is how you use values. Until you've done that, your code is inviting security problems.
(You should then start using more conventional variable names than T_STUDENT_NAME etc, but that's a different matter.)
check is a reserved word. Surround it with backticks: `check`
Try this
SELECT COUNT(*) as 'check' FROM recordstudent....
instead of
SELECT COUNT(*) as check FROM recordstudent....
I think check is a keyword

Categories