This question already has answers here:
Variable column names using prepared statements
(7 answers)
Using Prepared Statements to set Table Name
(8 answers)
Closed 4 years ago.
Very first question here so I apologize for any mistakes and imperfections.
Basically there are three files, my main method tech_supportv1, login_controller containing a class used to store a bunch of methods, and login.java, a javabean.
The point is to check if a certain row exists on the tech_support database. To do so I'm trying to use the code below. (db_util and type are classes containing connection data, they are tested and they work).
ISSUE: the data from the main method seems not be pasted into the string in the appropriate placeholders, and an error is returned. (Of course if I manually enter the strings instead of using placeholders, everything works just fine.)
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''technicians' WHERE 'techID' LIKE 16' at line 1
I tired to look at the mariaDB docs but all the other syntax provided yields the same results.
So this the main method.
public class Tech_support_v1 {
public static void main(String[] args) {
System.out.println("Start.");
login bean = new login();
bean.setTable("technicians");
bean.setColumn("techID");
bean.setID(16);
login_controller.select(bean);
}
}
This is the select method (with bean as argument, login is the Javabean class).
public static boolean select(login bean) {
String sql = "SELECT * FROM ? WHERE ? LIKE ?";
ResultSet rs;
try (
Connection conn = db_util.getConn(db_type.MYSQL);
PreparedStatement stmt = conn.prepareStatement(sql);
) {
stmt.setString(1, bean.getTable());
stmt.setString(2, bean.getColumn());
stmt.setInt(3, bean.getID());
rs = stmt.executeQuery();
if (rs.next()) {
System.out.println("Y");
return true;
} else {
System.err.println("N");
return false;
}
} catch (Exception e) {
System.err.println(e);
return false;
}
}
I won't include the bean class because it's literally only three variables with the relative set/get methods. Also the database runs with MariaDB, and is MySQL.
Thanks to everyone in advance.
You have multiple problems with your code :-)
First, you can't set table or column names with "setString" in a Prepared Statement!
See this Question: How to use a tablename variable for a java prepared statement insert
Second, as Daniel Pereira pointed out: You are trying to use a "like" Statement with "setInt"! See: https://dev.mysql.com/doc/refman/8.0/en/pattern-matching.html
You are comparing with LIKE but you are setting an Int. Change the LIKE to = and see if it works.
Try doing something like this:
String sql="SELECT * FROM :table ";
try (
Connection conn = db_util.getConn(db_type.MYSQL);
PreparedStatement stmt = conn.prepareStatement(sql);
)
{
String query = StringUtils.replace(sql, ":table", bean.getTable());
stmt.executeQuery(query);
}
Related
I'm trying to insert a variable into the database.
Heres my code :
public static void main(String[] args) throws SQLException {
Connection connection =null;
DBhelper helper = new DBhelper();
PreparedStatement statement = null;
ResultSet resultSet;
try{
connection= helper.getConnection();
System.out.println("baglantı olustu");
String sql = "INSERT INTO pandemi(toplamvirus) VALUES ('?') ";
statement = connection.prepareStatement(sql);
statement.setInt(1,2);
statement.executeUpdate(sql);
int result = statement.executeUpdate();
}
catch (SQLException exception){
helper.showErrorMessage(exception);
}
finally {
statement.close();
connection.close();
}
//String sql = "UPDATE pandemi SET toplamvirus='ff' ";
}
And the error is:
baglantı olustu
Error: Parameter index out of range (1 > number of parameters, which is 0).
Error code : 0
The database is: https://prnt.sc/rile7q
Pass argument ordinal and a value to setInt
You are incorrectly using the PreparedStatement::setInt method. The first argument is an ordinal number (incorrectly documented in the Javadoc as an index). So first placeholder is # 1, second placeholder is # 2, and so on. You have only a single ? placeholder. Or were you trying to pass a value of two to be inserted into the database? Your question is not clear.
Use naked ?
Also, you need to remove the single-quote marks from around the ? placeholder in your prepared statement. Using '?' means you want a single-character string consisting of a question mark inserted into the database. With the single-quotes in place, you have no placeholder in your SQL statement. So your setInt method will fail. If using a naked ?, the question mark will be recognized as a placeholder.
By the way, I suggest making a habit of using the SQL statement terminator, a semicolon.
String sql = "INSERT INTO pandemi ( toplamvirus ) VALUES ( ? ) ; ";
For more info, see another Answer of mine with a complete example app using the H2 database engine demonstrating INSERT with a placeholder in a prepared statement.
I'm new to JDBC and Java.
I'm coming from Javascript and Typescript background. I decided to learn JDBC with Oracle by creating a small basic project.
I'm using JDK 8. I'm following this study material: TutorialsPoint-PreparedStatement. I figured out that problem is with my DataService.
Here's my DataService class:
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DataService {
Connection con;
PreparedStatement pstmt;
static String branch_name="";
static LocalDate branch_created_on;
static String branch_pulled_from="";
DataService() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","system","scott");
}
catch(Exception e){
System.out.println(e);
}
}
public void getValue() {
branch_name=AddNewBranchRecord.branchNameTextField.getText();
branch_created_on=AddNewBranchRecord.datePicker1.getValue();
branch_pulled_from=(String) AddNewBranchRecord.combo_box_1.getValue();
}
public void putValue() {
System.out.println("Branch name: "+branch_name);
System.out.println("Branch created on: "+branch_created_on);
System.out.println("Branch pulled from: "+branch_pulled_from);
}
public void insertRecord() {
System.out.println("Adding a record...");
getValue();
try {
String sql;
sql = "insert into mybranches values (branch_name, branch_created_on, branch_pulled_from);";
pstmt = con.prepareStatement(sql);
} catch (SQLException ex) {
Logger.getLogger(DataService.class.getName()).log(Level.SEVERE, null, ex);
}
pstmt .close();
}
}
I'm sure there's something that I missed out.
I'm not getting any error or exception but no row is inserted in the database.
I cross checked with select * from mybranches.
However, the same code works perfectly if I use the normal Statement.
You create the PreparedStatement but you don't use it.
A prepared statement is there to e.g. insert different values into a table multiple times.
You create the PreparedStatement once like you would execute a normal Statement and include ? instead of the values that differ.
If you want to execute it, you have to set the values (the ?s will be replaced with them) by using the setXXX(int,Type) methods and then execute it with .execute().
As pointed out in the comments of the question, the SQL code is not valid. The sql code prepared statement is just like the sql code of a regular statement but the values that change all the time are replaced by ?.
The SQL code of the prepared statement would be something like that:
INSERT INTO mybranches VALUES (?,?,?)
If you want to use the PreparedStatement, you could set the values like that:
pstmt.setString(1,branch_name);
pstmt.setObject(2,branch_created_from);
pstmt.setString(3,branch_pulled_from);
Finally, execute it with
pstmt.execute();
Note that (as I already said) you should create the PreparedStatement once and not every time you execute the insertRecord() method and in that method, you should just call the setXXX methods and the execute() method.
The PreparedStatement (and the Connection object) should be closed when you don't need it anymore.
Also, as #TT. suggests in the comments, you should specify the columns in an INSERT statement. It would be something like
INSERT INTO mybranches (name,createdFrom,pulledFrom) VALUES (?,?,?)
I try to create a connection between JDBC and MS Access.
I follow the instruction as per this link. I am using IntelliJ Idea. Here I am sharing some snaps to describe my problem.
This is the code that I write down to make a connection with Database Database2. But as you can see there is no error neither any output. Now I am sharing the table structure and content on the table.
2nd picture is
My code is:
import java.sql.*;
public class Connection_sample {
public static void main(String[] args) {
try {
Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
Connection conn= DriverManager.getConnection("jdbc:ucanaccess://D://tutorial/Database2.accdb");
Statement s = conn.createStatement();
s.executeQuery("select * from Student");
ResultSet rset = s.getResultSet();
while (rset.next()) {
System.out.println(rset.getInt(1)+""+rset.getInt(2));
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Can anyone help me to find the error?
Your problem is the result of using getResultSet() instead of using the result set returned by executeQuery(). You should only use getResultSet() in combination with execute().
A result set should only be obtained once, and it was already returned from executeQuery (which you ignored). When you called getResultSet, you - apparently - got an empty one (which technically violates the contract).
I'm working on a simple application that pulls data from a local database. The below code works fine when I use a string for the SQL query, but I can not get it to work with PreparedStatement. I have reviewed similar problems posted here but most of those were caused by doing this, preparedStmt.executeQuery(query); instead of this preparedStmt.executeQuery(); Here is the code,
private final String POSTTITLE= "posttitle"; // DB Column name
private final String POSTCONTENT= "content"; // DB Column name
public String getDbContent(){
try{
String query ="select values(?, ?) from blog";
PreparedStatement preparedStmt = this.connect.prepareStatement(query);
preparedStmt.setString (1,POSTTITLE);
preparedStmt.setString (2,POSTCONTENT);
ResultSet rs = preparedStmt.executeQuery();
rs.next();
return(rs.getString(this.POSTCONTENT)); //Will replace with loop to get all content
} catch(Exception e) {
System.err.println("Error Reading database!");
System.err.println(e);
return("Error: "+e);
}
}
This is the error I get:
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 ''posttitle', 'content') from blog' at line 1
Parameters in prepared statements are for values - you're trying to use them to select fields. They just don't work that way.
In this very specific instance, you'll need to make the SQL dynamic. However, you'll want to make sure that whatever code you have to allow your columns to be specified is tightly constrained to avoid SQL injection attacks. (For example, you could have an enum with the columns in, or a whitelist of allowed values.)
Try concatenating select query:
String query ="select "+POSTTITLE+","+POSTCONTENT+" from blog";
Remember that prepared statements are for values, not query parameters, for them we use simply concatenations.
Try this:
String query ="select POSTTITLE, POSTCONTENT from blog";
PreparedStatement preparedStmt = this.connect.prepareStatement(query);
ResultSet rs = preparedStmt.executeQuery();
rs.next();
There is no need to use field names as parameter.
Code snippet:
On a button click, actionevent will be called
public void actionPerformed(ActionEvent e)
{
Function f = new Function();
Function is a nested class which i have used to establish the connection with the database.
The code snippet for function class is also provided in the end.
ResultSet rs = null;
String Cid ="cust_id";
String Pno="cust_phone";
String cat="cust_cat";
String start_date="st_date";
String Adv_amt="adv";
String Adv_end="end_date";
String Address="addr";
t2 is the Textfield name which i have used to get entry of customer name. I want to use this customer name as a PK to fetch all the other data about that customer from DB.
rs=f.find(t2.getText());
try{
if(rs.next())
{
t1.setText(rs.getString("cust_id"));
t3.setText(rs.getString("cust_phone"));
t4.setText(rs.getString("cust_cat"));
t5.setText(rs.getString("st_date"));
t6.setText(rs.getString("adv"));
t7.setText(rs.getString("end_date"));
t8.setText(rs.getString("addr"));
}
else
JOptionPane.showMessageDialog(null,"No data for this name");
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null,ex.getMessage());
}
}
Here is the code snippet for nested class Function which is inside the main class:
class Function{
Connection con=null;
ResultSet rs= null;
PreparedStatement ps = null;
public ResultSet find(String s)
{
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection("jdbc:oracle:thin:#Localhost:1521:xe","system","qwerty");
ps= con.prepareStatement("Select * from gkkdb where cust_name='?'");
ps.setString(1,s);
rs= ps.executeQuery();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
return rs;
}
}
Please help figure out the problem.
Don't put the parameter placeholder ? in single quotes.
This:
ps = con.prepareStatement("Select * from gkkdb where cust_name='?'");
should be
ps = con.prepareStatement("Select * from gkkdb where cust_name = ?");
The ? is not recognized as a placeholder if you enclose it in single quotes.
Sorting out the bind variable will fix your immediate issue.
You should explicitly specify what columns you want selected and that way you'll only get what you need (someone might add a BLOB column later) and you'll get them in the right order (someone might change the table create script before running on another DB instance, although you are looking up the columns by name, a different order would only impact if you were using positional indexes).
Ditto on the other answer re: bind variables (i.e. no quotes)
Plus, "select * from" is never a good idea, ask your DBA.
Obviously your code is for example, but you should make sure you free up any resources (Connection, Statement, ResultSet) as soon as they are done with. Use Java 7 try-with-resources.