Creating a table programmatically using MyBatis and MySql - java

I want to create a method to dynamically create tables just passing the table name as a variable.
I have defined my xml mapper
<mapper namespace="com.mappers.TableCreatorMapper">
<cache />
<insert id="createNewTableIfNotExists" parameterType="String" >
CREATE TABLE IF NOT EXISTS #{tableName}
(
`ID` varchar(20) NOT NULL,
PRIMARY KEY (`ID`)
)
ENGINE=InnoDB
</insert>
</mapper>
And my Java Interface Mapper is simply:
public interface TableCreatorMapper {
public void createNewTableIfNotExists(String tableName);
}
but when I call my interface
tableCreatorMapper.createNewTableIfNotExists("test");
I get the following exception:
org.springframework.jdbc.BadSqlGrammarException:
### 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 ''test'
(
`ID` varchar(20) NOT NULL,
PRIMARY KEY (`ID`)
' at line 1
### The error may involve com.mappers.TableCreatorMapper.createNewTableIfNotExists-Inline
### The error occurred while setting parameters
### SQL: CREATE TABLE IF NOT EXISTS ? ( `ID` varchar(20) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB
### 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 ''test'
(
`ID` varchar(20) NOT NULL,
PRIMARY KEY (`ID`)
' at line 1
; 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 ''test'
(
`ID` varchar(20) NOT NULL,
PRIMARY KEY (`ID`)
' at line 1
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231)
at org.sp
If I instead change the query adding the ``for the table name:
CREATE TABLE IF NOT EXISTS `#{tableName}`(
`ID` varchar(20) NOT NULL,
PRIMARY KEY (`ID`)
)
ENGINE=InnoDB
I get
### The error occurred while setting parameters
### SQL: CREATE TABLE IF NOT EXISTS `?`( `ID` varchar(20) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB
### Cause: java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
; SQL []; Parameter index out of range (1 > number of parameters, which is 0).; nested exception is java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
Any idea why?

try
CREATE TABLE IF NOT EXISTS ${_parameter}
(
`ID` varchar(20) NOT NULL,
PRIMARY KEY (`ID`)
)
ENGINE=InnoDB
#{name} is for parameters in PreparedStatement (see String Substitution in Parameters).

in DAO, use annotation #Param
void createTableIfNotExist(#Param("uuid") String uuid);
in MAPPER, use $
<update id="createTableIfNotExist" parameterType="java.lang.String">
CREATE TABLE IF NOT EXISTS `table_${uuid}`
(
`id` bigint(18) NOT NULL,
`info` varchar(18) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='this table is generated by java code.'
</update>
<bind> could be used in MAPPER too.

Related

MySQL 5.7 unable to create desc index

MySQL Version: 5.7.17 on Windows 10
I used the following SQL statement to generate a table.
CREATE TABLE `attributes` (
`id` varchar(36) NOT NULL,
`name` varchar(255) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
KEY `name_idx` (`name` DESC)
)
I tried that statement from Java Code. I tried this statement also from MySQL Workbench.
It never creates a descending index on name.
Is this a known issue?
Have I made a mistake?

Order execution of create table using mysql, h2 and flyway

I have created a an sql script (using mysqldump) to determine my base version of my database. I use this script with flywaydb to totally manage the db creation and other migration actions. The script contains of several tables some of them are fk's to others. the order in which they appear in the sql script generated by mysqldump is the following (only two of the tables appear that are causing the issue described later below)
CREATE TABLE `signaling_interface` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`test_server_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_sigInterfaceConstraint` (`test_server_id`),
KEY `FK_3crdx5y8had0g1mit1k2gebt5` (`test_server_id`),
CONSTRAINT `FK_3crdx5y8had0g1mit1k2gebt5` FOREIGN KEY (`test_server_id`) REFERENCES `test_server` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `test_server` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_3754w88bn333h1dgambvwj6i8` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I want to Junit test my migrations and chose h2 in memory database to do that. But when I try to migrate it gives me an error when creating signaling_interface table because test_server does not exist. It doesn't give me this error when executing migrations in MySQL. Is there a difference between mysql and h2?

How to add an auto increment column in java?

I want to add the database from my jform and there's a column which will be auto incremented, like when i click done, the data will be inserted and a column receipt_no will have a value 1. Next time I click done then this value should be 2 and so on.
So the problem is, i have created a table with receipt_no as the primary key and auto increment, so what should be my query in java, to add the data correctly in the table.
String sql = "insert into table_name values('"++"',...)";
Can you help me in this query?
Step 1: Creating table in MySQL
CREATE TABLE `user_master` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`Firstname` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Step 2: Insert record
INSERT INTO user_master (`Firstname`) values('Vicky');
Step 3: Fetch record
SELECT * FROM user_master;
I can't comment so there is an answer to the comment you posted in your question:
If your table is
CREATE TABLE users(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
firstname VARCHAR(25) NOT NULL,
lastname VARCHAR(25) NOT NULL,
);
You can simply auto_increment the primary by not giving it on your SQL request:
INSERT INTO users(firstname, lastname) VALUES('Steve', 'Jobs');
Java don't have to generate auto increment, it is SQL job :)

SQL Syntax Error with CREATE TABLE

I get a SQL Sytax Error when I try to execute this code:
CREATE TABLE ? (
ID INT(255) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`UUID` VARCHAR(36) NOT NULL
);
I use a PreparedStatement to replace the ? with a String
The Error Message:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an errorin your SQL syntax; check the manual that corresponds to your MySQL serverversion for the right syntax to use near ''95f7ed55-ab3d-46f9-bffe-72bf5780a1ec' (ID INT(255) UNSIGNED AUTO_INCREMENT PRIM' at line 1
Thanks for your help!
Put table name into backticks, it contains - which has to be escaped.
You used single quotes ('), which are bad in SQL.
The sign (-) character is not allowed when not using quotes.
http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
An identifier may be quoted or unquoted. If an identifier contains
special characters or is a reserved word, you must quote it whenever
you refer to it. (Exception: A reserved word that follows a period in
a qualified name must be an identifier, so it need not be quoted.)
This is executed now:
CREATE TABLE 95f7ed55-ab3d-46f9-bffe-72bf5780a1ec (
ID INT(255) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`UUID` VARCHAR(36) NOT NULL
);
But the identifier on the first line needs to be quoted:
CREATE TABLE `95f7ed55-ab3d-46f9-bffe-72bf5780a1ec` (
Maybe something like this will do the trick? (edit: added "IF NOT EXISTS" from Anil Kumar's answer)
CREATE TABLE IF NOT EXISTS `?` (
ID INT(255) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`UUID` VARCHAR(36) NOT NULL
);
Please try following query syntax:
CREATE TABLE table_name (ID INT(255) UNSIGNED AUTO_INCREMENT PRIMARY KEY,UUID VARCHAR(36) NOT NULL);
pls try this code.
CREATE TABLE `table_name`(
`ID` INT( 255 ) UNSIGNED AUTO_INCREMENT PRIMARY KEY ,
`UUID` VARCHAR( 36 ) NOT NULL
);
Note: table_name using this symbol.
-- DROP PROCEDURE IF EXISTS createTblDynamically;
DELIMITER //
CREATE PROCEDURE createTblDynamically(tblName VARCHAR(255))
BEGIN
SET #tableName = tblName;
SET #q = CONCAT('
CREATE TABLE IF NOT EXISTS `' , #tableName, '` (
ID INT(255) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`UUID` VARCHAR(36) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
');
PREPARE stmt FROM #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //

Creating table dynamically by SQL in Servlet

I am getting error in this: prepared statement.
Prepared Statement:
PreparedStatement pStatement=connection.prepareStatement
("CREATE TABLE `details`.?(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL);
INSERT INTO `testdetails`.? (`ID`) VALUES (?);");
pStatement.setString(1, "usrname");
pStatement.setString(2, "usrname");
pStatement.setString(3, "001");
pStatement.executeUpdate();
Error details:
Severe: 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
''usrname'(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL);INSER' at line 1
How to fix this error?
JDBC parameters aren't usually usable for table and column names - they're only for values.
Unfortunately, I think this is one of those cases where you will need to be build the SQL dynamically. You will want to be very careful about which values you allow, of course.
This error appears because, you use #setString, and the string gets wrapped by ''.
To fix this, you can use one of this snippets:
"CREATE TABLE `details`.#tableName#(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL); INTO `testdetails`.#tableName# (`ID`) VALUES (?);".replaceAll("#tableName#", "usrname");
or
new StringBuilder("CREATE TABLE `details`.").append("usrname").append("(`ID` VARCHAR(255) NOT NULL,`Score` VARCHAR(255) NULL); INTO `testdetails`.").append("usrname").append("(`ID`) VALUES (?);").toString();
and pass resulted string into #prepareStatement() method.

Categories