If table exists drop table then create it - syntax in line Create - java

I just want to create a table, but if it exists it needs to be dropped and re-created.
I use MySQL 8.0.29
Error:
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 'CREATE TABLE users (Id long, name varchar(100), lastName
varchar(100), age tin' at line 1
Code:
public static void main(String[] args) throws SQLException {
try (Connection connection = Util.getConnection()) {
String sqlCommand = "DROP TABLE IF EXISTS `users`;" +
"CREATE TABLE `users` (Id long, name varchar(100), lastName varchar(100), age tinyint)";
Statement statement = connection.createStatement();
statement.executeUpdate(sqlCommand);
System.out.println("table created");
int rows = statement.executeUpdate("INSERT users(Id,name,lastName,age) VALUES (101,'Mike','Manson',31)");
}
}

The following may be the reason:
long is not a valid MySQL data type.
variable sqlCommand contains multiple statements. Each SQL statement should be terminated with a semicolon symbol. Adding a semicolon at the end of CREATE statement can solve your issue.

By default the JDBC driver does not support multiple SQL statements in one execute call. There's a connect string option to enable it:
https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-connp-props-security.html#cj-conn-prop_allowMultiQueries
allowMultiQueries
Allow the use of ';' to delimit multiple queries during one statement.
But there's no good reason to use multi-queries. They make your code more complex, not simpler. Allowing multi-queries creates the opportunity for a type of SQL injection vulnerabilities that are not possible otherwise. See https://xkcd.com/327/
Just run one statement per call to executeUpdate().

Related

Java prepairedStatement setInt is adding quotes in the SQL

I have a simple SQL statement that I want to execute via
String tokenInsQ = "INSERT INTO pitweb.tokens (token_user_id,token_token,token_valid,token_refresh) (?,?,?,?)";
try {
PreparedStatement p = SQL.dbConnection.prepareStatement(tokenInsQ);
p.setInt(1, r.getInt("user_id").intValue());
p.setString(2, token.getString("token"));
p.setTimestamp(3, (Timestamp)token.get("valid"));
p.setTimestamp(4, (Timestamp)token.get("renew"));
System.out.println(p);
p.executeUpdate();
p.close();
}
I expect this to work just fine. Token is a long string and r.getInt("user_id").intValue() Returns 11. The error I keep getting is
org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
Position: 82
So I added the print statement to see the SQL that it is trying to execute. The program Prints.
INSERT INTO pitweb.tokens (token_user_id,token_token,token_valid,token_refresh) ('11','really long string ','2020-03-17 13:15:22.847000 -05:00','2020-03-14 13:15:22.847000 -05:00')
I assume that my problem is that the token_user_id ('11') is in quotes. Is this because of the way that I created the Prepared Statement? or do I have a different problem. the output seems vague to me
Here is what the token table looks like
CREATE TABLE pittweb.token
(
token_id integer NOT NULL DEFAULT nextval('pittweb.token_token_id_seq'::regclass),
toekn_user_id integer,
token_valid timestamp without time zone,
toekn_refresh timestamp without time zone,
token_token text COLLATE pg_catalog."default",
CONSTRAINT token_pkey PRIMARY KEY (token_id),
CONSTRAINT token_toekn_user_id_fkey FOREIGN KEY (toekn_user_id)
REFERENCES pittweb."user" (user_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
WITH (
OIDS = FALSE
)
There is a typo in toekn_refresh as well along with toekn_user_id.
There is a typo in the column name toekn_user_id. In the insert statement, you have used token_user_id and in the DDL it is toekn_user_id

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version etc

I have a simple table having id(autoincrement) and name and i am trying to do a very simple insert query
if (connect != null) {
query = new StringBuffer("");
query.append("INSERT INTO ");
query.append("GROUP( ");
query.append("GROUP_NAME ");
query.append(") values (");
query.append("?)");
System.out.println(query.toString());
stmt = connect.prepareStatement(query.toString());
int i = 0;
stmt.setString(1, group.getGroupName());
records = stmt.executeUpdate();
}
but it gives me an exception with stacktrace:
2016-02-09T10:00:44.876+0500|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 'GROUP(
GROUP_NAME ) values ('Hockey')' at line 1
I have searched about such problems but couldn't find a proper solution.
GROUP is a reserved word in MySQL.
Most of the reserved words in the table are forbidden by standard SQL as column or table names (for example, GROUP).
Preferably, you wouldn't use reserved words as identifiers at all, for exactly this reason. If you absolutely must, then use backticks ` to quote reserved words, as described in Section 9.2.1 of the MySQL Reference Manual.
You can't use GROUP as a name in MySQL unless it's enclosed in backticks:
INSERT INTO `group` (GROUP_NAME) VALUES (?)

SQL works from PMA but not Java

I have a prepared statement like so:
CREATE TABLE IF NOT EXISTS ? (uuid VARCHAR(128), item VARCHAR(48), value FLOAT, UNIQUE (uuid))
If I execute this directly in PMA, but replacing the ? with any text text, it works perfectly and it creates the table correctly. However, if I run it from Java it doesn't work.
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 ''Murder_PlayerData' (uuid VARCHAR(128), item VARCHAR(48), value FLOAT, UNIQUE (u' at line 1
Here's the Java code
String table = "Murder_PlayerData";
String execute = "CREATE TABLE IF NOT EXISTS ? (uuid VARCHAR(128), item VARCHAR(48), value FLOAT(11), UNIQUE (uuid))";
PreparedStatement statement = sql.getConnection().prepareStatement(execute);
statement.setString(1, table);
statement.execute();
Why does it work in PMA but not when I do it from Java?
Prepared statements can't be used to define table names, but to define values related to columns (insert values, values for where or having conditions, etcetera). One way to understand it is: Prepared Statements are for DML operations, not for DDL operations.
If you want to build a table on runtime, you need to build the SQL statement "by hand":
String table = "Murder_PlayerData"
String strSQL = "create table if not exists " + table + "("
// Add your column definitions
+ ")"
Statement stmt = conn.createStatement();
stmt.execute(strSQL);
Notice that, if the variable table can be filled with data provided by the user, your code will be vulnerable to SQL Injection Attacks. I recommend you don't create tables if their names must be provided by users, but rather create the tables without any user interaction and then insert the values, using some kind of key to identify which records belong to each user.

Error while trying to test if a specific table exists in a MySQL database using JDBC

I want to check wether a table named basestation exists in a MySQL table from a Java program using JDBC. My code is:
conn = DriverManager.getConnection(url, username, password);
DatabaseMetaData dbm = conn.getMetaData();
tables = dbm.getTables(null, null, "basestations", null);
if (tables.next())
{
//Table exists in database
//...
}
else
{
//Table does not exist
//...
}
but although table basestations exists in my database it seems that my code never enters the first clause and always decides that table does not exist, causing naturally a table already exists in database SQL error when trying to create the table from the beginning.
Not the best way to do it below.. But you could do the following:
Use JDBC to send the following statement:
select count(*) from information_schema.tables where information_schema.table_schema='your_schema' and information_schema.table_name='basestations';
Parse the jdbc result set.
That should return either 1 or 0. If the resulting count is 1, then the table exists, otherwise, it does not.
I suspect your getTables() not returning anything here. As per getTables documentation Only table descriptions matching the catalog, schema, table name and type criteria are returned. In your case catalog and schema are null, which may not be correct (my guess), populate them with proper values.

How to execute a set of related SQL instructions with JDBC?

I'm trying to execute this script through JDBC (it's SQL Server):
DECLARE #var VARCHAR(10)
SET #var = "test"
INSERT INTO foo (name) VALUES (#var)
It's just an example, in my business case I have a big collection of SQL statements in one script.
I'm trying this:
final Statement stmt = connection.createStatement();
for (String sql : lines) {
stmt.executeUpdate(sql);
}
stmt.close();
SQL Server is saying on the second line:
java.sql.SQLException: Must declare the scalar variable "#var".
Looks like I'm doing something wrong...
You're executing it one line at a time, so of course the second line fails as it depends on the first line. Why not execute it all at once?...

Categories

Resources