I've code a simple hadoop/hive table defined as
CREATE TABLE mike
timeOne TIMESTAMP,
timeTwo TIMESTAMP,
name STRING
And then a myBatis mapper file to insert a record here that looks like this
<insert id="insertMikeFormDataForHadoop" parameterType="hashmap">
INSERT INTO ${tableName} (timeOne, timeTwo, name)
VALUES (#{timeOne, jdbcType=DATE}, #{timeTwo, jdbcType=DATE}, #{name})
</insert>
When I run a test to insert data via this SQL I get error like this.
org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: org.apache.hive.service.cli.HiveSQLException: Error while compiling statement: FAILED: ParseException line 2:16 mismatched input '-' expecting ) near '2017' in value row constructor
### The error may involve com.vertexinc.ve.returns.mapper.FormMapper.insertMikeFormDataForHadoop-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO mike (timeOne, timeTwo, name) VALUES (?, ?, ?)
### Cause: org.apache.hive.service.cli.HiveSQLException: Error while compiling statement: FAILED: ParseException line 2:16 mismatched input '-' expecting ) near '2017' in value row constructor
I've also tried this with jdbcType=TIMESTAMP instead of date with the same error.
I've wondering if I'm doing something wrong or assuming something about hive/hadoop and mybatis that I shouldn't.
(This is a super simple example I've used to illustrate this point).
Turns out this was an issue with the hive jdbc driver version 1.2.1.
The setTimestamp in the HivePreparedStatement had a small defect. Upgrading driver fixed the issue..
https://issues.apache.org/jira/browse/HIVE-11748
Related
I have a Spring CRUD application, with an Oracle SQL database.
I have several integration tests and use the #Sql annotation to run .sql files which put the database in a desired state before running the test. I have had no problem with any of my .sql scripts so far, although they have all be very simple INSERT and DROP statements.
I am now trying to set up a scenario in which the database holds thousands of records in a particular table. I am not bothered about the content, only the number of records.
In order to replicate this scenario, I have written the following SQL script:
DECLARE
id integer := 1;
BEGIN
WHILE id <= 3000
LOOP
INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE)
VALUES (id, 'John', 'Smith', 32);
id := id + 1;
END LOOP;
END;
I have ran this script using IntelliJ and it works as expected.
However, when I put the script into a #Sql annotation, I run into the following error:
org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [sql/setUp.sql]: DECLARE id integer := 1; nested exception is java.sql.SQLException: ORA-06550: line 1, column 23:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
I am at a loss as to the solution; I have encountered similar issues where the solution was just a missing semi-colon, but that doesn't seem to be the case here.
What's even more mystifying is that I tried running the following script via the #Sql annotation:
BEGIN
INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE)
VALUES (1, 'John', 'Smith', 32);
END;
This produced the following error, which makes even less sense:
org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of class path resource [sql/test.sql]: BEGIN INSERT INTO USER (ID, FIRST_NAME, LAST_NAME, AGE) VALUES (1, 'John', 'Smith', 32); nested exception is java.sql.SQLException: ORA-06550: line 1, column 87:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
;
Most interesting to note is that removing the BEGIN and END statements (leaving just the INSERT INTO statement) works.
So does Spring JDBC simply not support BEGIN/END blocks? Are there limitations to the pre test #Sql annotation that I'm not aware of? Or have I missed something painfully obvious?
Thanks to #MarkRotteveel for his suggestion, I have discovered the solution to this issue.
JDBC was indeed running each line of the script as if it was a separate statement, which is incompatible with statement blocks. This is because the separator is set to the ; symbol by default, causing JDBC to treat each block of code ended with a ; as if it was a separate script. I set this separator to the EOF symbol, which caused JDBC to treat the whole file as a single script.
My original test code looked something like this:
#Sql(scripts = {"sql/cleanup.sql", "sql/setUp.sql"})
public void testWithThousandsOfRecords() {
// do tests
}
My test code now looks like this:
#Sql(scripts = "sql/cleanup.sql")
#Sql(scripts = "sql/setUp.sql", config = #SqlConfig(separator = ScriptUtils.EOF_STATEMENT_SEPARATOR))
public void testWithThousandsOfRecords() {
// do tests
}
Note that I had to separate my cleanup and setUp scripts, as changing the separator may break some scripts that worked before.
What is causing this exception, I have used the similar approach in a UserController and that worked fine. Is the mapping of SQL table with Entity Classes wrong ?
I can't store data and I can't retrieve anything from it either. It keeps giving me the same error, Initially I though my Latitude and Longitude might be wrong but then I tried inserting a simple user_id and is being rejected too.
Controller
#Autowired
OrderMapper orderMapper;
#ResponseBody
#RequestMapping(value = "/getOrder", method = RequestMethod.POST)
public Order PlaceOrder()
{
Order order = new Order();
order.setUserId(1);
orderMapper.insert(order);
return order;
}
OrderMapper
<insert id="insert" parameterType="com.mena.api.entity.Order">
insert into order (order_id, user_id, start_latitude,
start_logitude, end_latitude, end_logitude,
total_distance, type, cost,
create_time, start_address, end_address,
user_id2)
values (#{orderId,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER}, #{startLatitude,jdbcType=DECIMAL},
#{startLogitude,jdbcType=DECIMAL}, #{endLatitude,jdbcType=DECIMAL}, #{endLogitude,jdbcType=DECIMAL},
#{totalDistance,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{cost,jdbcType=VARCHAR},
#{createTime,jdbcType=TIMESTAMP}, #{startAddress,jdbcType=VARCHAR}, #{endAddress,jdbcType=VARCHAR},
#{userId2,jdbcType=INTEGER})</insert>
And SQL Table Info
Error Log
</pre><p><b>Root Cause</b></p><pre>org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: 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 'order
where order_id = 1' at line 6
### The error may exist in file [\khadim\khadimApi\khadimApi\target\khadminapi\WEB-INF\classes\mybatis\OrderMapper.xml]
### The error may involve com.mena.api.mapper.OrderMapper.selectByPrimaryKey-Inline
### The error occurred while setting parameters
### SQL: select 'true' as QUERYID, order_id, user_id, start_latitude, start_logitude, end_latitude, end_logitude, total_distance, type,
cost, create_time, start_address, end_address, user_id2 from order where order_id = ?
### Cause: 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 'order
where order_id = 1' at line 6
; bad SQL grammar []; nested exception is 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 'order
where order_id = 1' at line 6
org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235)
org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:447)
com.sun.proxy.$Proxy35.selectOne(Unknown Source)
org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:167)
org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:82)
org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
com.sun.proxy.$Proxy36.selectByPrimaryKey(Unknown Source)
com.mena.api.controller.OrderController.PlaceOrder(OrderController.java:34)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
order is a reserved word in MySql, this is why your select ... from order probably fails with that exception. If order really is the table name in your database, you could escape it as follows:
select ... from `order` ...
Or better yet would be to use a non-reserved table name, like 'orders'.
I am running following query:
my query = insert into tbl_name (ID,name, address,...)" +" values (?,?,?)
then I am using query runner class to insert.
myQueryRunnerObj.insert("my query",
result set handler obj,
generated id,
'my name',
'my address',...);
After this I am getting following exception: Exception in thread "main" java.sql.SQLException: ORA-00936: missing expression and sometimes invalid number of arguments expecting 11 given 10
What could be the reason to get this exception?
Correct syntax is:
INSERT INTO dept (deptno, dname) VALUES (dept_seq.nextval, 1);
or
INSERT INTO dept (deptno, dname)
SELECT dept_seq.nextval, 2
FROM dual;
ORA-00936: missing expression
Cause: A required part of a clause or expression has been omitted. For example, a SELECT statement may have been entered without a list of columns or expressions or with an incomplete expression. This message is also issued in cases where a reserved word is misused, as in SELECT TABLE.
Action: Check the statement syntax and specify the missing component.
check this
I am use Java to insert into a MSSQL database. I have column names with parentheses in them like Duration_(Mins).
I am trying to execute a statement like:
INSERT INTO mytable (Duration_(Mins)) VALUES (?)
and I am getting the following error:
Exception in thread "main" java.sql.SQLException: Incorrect syntax near '('
So I am guessing I need some way to "escape" the bracket?
For MS-SQL Server, this should work:
INSERT INTO mytable ([Duration_(Mins)]) VALUES (?)
For details, refer this link:
http://msdn.microsoft.com/en-us/library/ms132046.aspx#DelimitedIdentifiers
I'm new to java world. And I have a problem with simple query:
<insert id="create" parameterType="models.entities.CategoryEntity">
set #catId := (select categoryId from Categories limit 1);
insert into Categories(CategoryId, Title, LeftValue, RightValue)
values(#catId, 'Test in', 1,2);
....
</insert>
it simply fails when i trying to run it with mybatis:
PersistenceException occured : ### Error updating database. Cause: 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 'insert into Categories(CategoryId, Title, LeftValue, RightValue) values(' at line 2 ### The error may involve Category.create-Inline ### The error occurred while setting parameters ### Cause: 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 'insert into Categories(CategoryId, Title, LeftValue, RightValue) values(' at line 2
If I remove this line:
set #catId := (select categoryId from Categories limit 1);
then everything is ok. What am i doing wrong? Is it problem with jdbc or mybatis? How to use mysql #variables with mybatis? Does someone have examples of using MySql local variables with mybatis?
I found out how to get it worked. Just set datasource property allowMultiQueries=true
jdbc:mysql://localhost:3306/DBS?allowMultiQueries=true