I have 3 comboboxes in Java which are ;
'departurecities={city1,city2,city3}
destinationcities={city1,city2,city3}
date={1,2,3,4,5,6...}
I want to define a variable for the date because I don't know, what user will bus date, so I need a variable for SQL query.
I want to query like that:
sql=select busid from buses where dep='city1'and des='city2' and
datebus=(????variable????);
how can I define it ???
Please help me ..
Thanks in advance
PreparedStatement
In case you want to pass a variable to your SQL statement, I would recommend a PreparedStatement. See Oracle Tutorial.
You can use setInt in order to pass an integer, setString to pass a String etc.
Here is the API.
Here is an example:
String result = null;
String query = "select busid from buses where dep='city1'and des='city2' and datebus=?";
try {
PreparedStatement preps = con.prepareStatement(query);
preps.setInt(1, Integer.parseInt((String) date.getSelectedItem()));
preps.execute();
rs = preps.getResultSet();
if (rs.next()) {
result = rs.getString(...);
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
I assume that datebus is declared as an integer in your database table.
You can use a String type for a constant like '2012-12-31 12:00 am', or, Date or GregorianCalendar if you want to manipulate days/date differences in Java.
In SQL, you can convert string or character values into SQL's internal date format with the to_date() function:
SQL examples:
to_date('29-Oct-09', 'DD-Mon-YY')
to_date('10/29/09', 'MM/DD/YY')
to_date('120109', 'MMDDYY')
So, if you wanted to create a SQL command from Java:
String date = "12/31/2012";
String dep = "city1";
String des = "city2";
String SQL = "INSERT INTO buses VALUES(" + dep + "," + des + ",to_date(" + date + ",'MM/DD/YYYY'));";
Related
I'm having problem with showing database values in my Jtable. I don't know how to use JDataChooser as a searching tool in JTable. I want the process like this, if JDateChooser1 is select to 08-17-2017 and JDateChooser2 is select 09-17-2017
the JTable will only show the values that having that date between 08-17-2017 - 09-17-2017. The format of the Date is (MM-dd-yyyy).
I have this method and as a testing I put the method to a button. I also want to know where I can put this method to be able not using a button. Auto search when I'm done selecting the dates.
sales is my table name in mysql and Date is the column name.
private void Dated() {
try {
String value1, value2;
value1 = jDateChooser1.getDate().toString();
value2 = jDateChooser2.getDate().toString();
String sql = "select * from sales where Date = '" + value1 + "' and '" + value2 + "'";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
You are missing some information in your query :
show the values that having that date between 08-17-2017 - 09-17-2017 you have to use between keyword in the query should be select * from sales where Date between date1 and date1 and not =
because you are using prepapred statement don't use concatination of the query and values.
beside Date is reserved keyword in MySQL instead you have to put it between two ``
Your code should look like :
Date value1 = jDateChooser1.getDate();
Date value2 = jDateChooser2.getDate();
String sql = "select * from sales where `Date` between ? and ?";
pst = conn.prepareStatement(sql);
pst.setDate(1, value1);
pst.setDate(2, value2);
rs = pst.executeQuery();
EDIT
Putting this here in case it helps others. My problem was a failure in understanding how PreparedStatement works. I had believed that the "?"...setInt() syntax was a simple substitution that constructs an SQL statement, interprets it and sends that to the DB, which is not the case. The answers below explain in detail the problem.
ORIGINAL QUESTION
I'm having some trouble getting an Oracle package function call to execute from within a Java app. I am receiving the below error:
ORA-01858: a non-numeric character was found where a numeric was expected
I believe I have constructed the call correctly, and the only place I'm using a string is for a date field (not a numeric one). The function has the signature:
function f_get_mr_target(a_plan_id number,a_machine number,a_shift_id number,a_shift_dt date) return number;
My java code invoking the function is as follows:
public Double checkMRTarget(int planId, int machineNum, int shiftId, String date)
{
//Instantiate the return value
Double mrTarget = null;
//Get the MR target
try
{
//Ready the connection
con = nativeDataSource.getConnection();
//The query string
String sql = "select pkg_bcs.f_get_mr_target(?,?,?,?) target from dual";
//Prepare the query
stmt = null;
stmt = con.prepareStatement(sql);
stmt.setInt(1, planId);
stmt.setInt(2, machineNum);
stmt.setInt(3, shiftId);
stmt.setString(4, date);
//Execute the query
ResultSet rs = stmt.executeQuery();
//Extract the value from the result set
mrTarget = rs.getDouble("target");
}
catch (Throwable e)
{
System.out.println("Error getting mrTarget: " + e);
}
finally
{ closeDBConnections(); }
//Return the value
return mrTarget;
}
Con is a public Connection object shared by all other methods in the class. Stmt is a PreparedStatement object, also shared. The parameters are passed as follows:
planId = 986548
machineNum = 5227
shiftId = 10
date = "trunc(sysdate)"
I've verified that running
select pkg_bcs.f_get_mr_target(986548, 5227, 10, trunc(sysdate)) target from dual;
works just fine in SQLDeveloper. As far as I can tell, it's getting a number where it expects a number
You've called setString, so Java sent a String that Oracle can't implicitly convert into a DATE.
You can convert it to a java.sql.Date, java.sql.Time, or java.sql.Timestamp by first parsing the date with a SimpleDateFormat, and creating the appropriate object, and calling setDate, setTime, or setTimestamp instead of setString.
Alternatively, you can get Oracle to convert it by calling to_date in your JDBC SQL:
// Your date format may vary.
String sql = "select pkg_bcs.f_get_mr_target(?,?,?,to_date(?, 'YYYY-MM-DD')) target from dual";
the 4th parameter which is date do not work with String. It waits for a Date object.
Here is your method signature, pass a Date object instead of String.
public Double checkMRTarget(int planId, int machineNum, int shiftId, Date date)
Substituting a string datatype to a Date parameter is a catastrophe. It will surely the ORA-01858 exception in this case (in context of you code).
Parameter substitution demands exact binding which serves its purpose of being strongly typed.
Please convert the fourth parameter i.e. the string parameter into a date object. & then implement what you wish to. It should work fine then.
Also, trunc(sysdate) in SQL query does not return a string to the SQL client. Rather it returns the date(internal conversion). This is designed such that the parser recognize the date type efficiently and consistently.
I m writing a small utility that captures and logs SQL statements, but will have to remove sensitive data from the Query text and replace with with some dummy text (i.e:XXXXX).
What is a good way to parse the SQL query in java and replace parameters value?
for example:
replace
SELECT NAME, ADDRESS, .... FROM USER WHERE SSN IN ('11111111111111', '22222222222222');
with
SELECT NAME, ADDRESS, .... FROM USER WHERE SSN IN (?, ?);
Using JSQLParser (V0.8.9) this is a solution for your problem:
String sql ="SELECT NAME, ADDRESS, COL1 FROM USER WHERE SSN IN ('11111111111111', '22222222222222');";
Select select = (Select) CCJSqlParserUtil.parse(sql);
//Start of value modification
StringBuilder buffer = new StringBuilder();
ExpressionDeParser expressionDeParser = new ExpressionDeParser() {
#Override
public void visit(StringValue stringValue) {
this.getBuffer().append("XXXX");
}
};
SelectDeParser deparser = new SelectDeParser(expressionDeParser,buffer );
expressionDeParser.setSelectVisitor(deparser);
expressionDeParser.setBuffer(buffer);
select.getSelectBody().accept(deparser);
//End of value modification
System.out.println(buffer.toString());
//Result is: SELECT NAME, ADDRESS, COL1 FROM USER WHERE SSN IN (XXXX, XXXX)
This replaces all found String values within your SQL. To replace other types of data e.g. Long values, override the corresponding visit method in ExpressionDeParser.
Don't use regexp in this case. It turns out quickly to be hard maintainable.
The correct answer depends on how much you want to replace. Something like:
[0-9]{3}-?[0-9]{2}-?[0-9]{4}
will replace social security numbers pretty well. I always take regex code to
regexpal.com
to tweak it and work out bugs.
If you need to replace tons of sensitive information though, and if there are a lot of cases, definitely start looking into using a parser to parse the SQL query string. (such as jsqlparser, as Anirudh recommended.)
String sqlDebit = select * from table where and billing_cycle_start_date between :startDate and :endDate
java:
sqlDebit= sqlDebit.replaceAll(":startDate ", ""+startDate).replaceAll(":endDate", ""+endDate);
With prepare statement you can replace "?" in your query string with your value. Use number to specify which "?" you are referring too. They go by order from right to left.
For example: "SELECT LastName, FirstName FROM Person.Contact WHERE LastName = ? and FirstName = ?"
pstmt.setString(1, "LastNameValue");
pstmt.setString(2, "FirstNameValue");
see full example below:
public static void executeStatement(Connection con) {
try(PreparedStatement pstmt = con.prepareStatement("SELECT LastName, FirstName FROM Person.Contact WHERE LastName = ?");) {
pstmt.setString(1, "Smith");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
}
}
// Handle any errors that may have occurred.
catch (SQLException e) {
e.printStackTrace();
}
}
When I try to execute the below code it gives me an java.sql.SQLException: ORA-01861: literal does not match format string error.
I am trying to copy some of the column values from customer1_details table to customer2_details table. The columns datatype which I am trying to move is TIMESTAMP(6) for TIME_REGISTERED, DATE_DISCHARGED columns and the datatype for DATE_OF_BIRTH column is DATE
try
{
Connection conn=Address.getOracleConnection();
int id = 1;
Date dob = null;
Timestamp timereg = null,datedischarged = null;
Statement stmt=conn.createStatement();
ResultSet res=stmt.executeQuery("SELECT TIME_REGISTERED,DATE_DISCHARGED,DATE_OF_BIRTH from customer1_details WHERE customer_id = '"+id+"' ");
if(res.next())
{
timereg=res.getTimestamp("TIME_REGISTERED");
datedischarged=res.getTimestamp("DATE_DISCHARGED");
dob=res.getDate("DATE_OF_BIRTH");
}
String sql1="INSERT INTO customer2_details(TIME_REGISTERED_3,DATE_DISCHARGED_3,DATE_OF_BIRTH,customer_ID) "
+ "VALUES('"+timereg+"','"+datedischarged+"','"+dob+"','"+id+"') ";
PreparedStatement pst=conn.prepareStatement(sql1);
pst.executeUpdate();
pst.close();
conn.close();
}
catch(Exception e)
{ System.out.print(e); }
It will be more helpful if anyone provides the answer without using INSERT INTO ... SELECT ... statement.
YOu can do it in one statement with a query like:
"INSERT INTO customer2_details (TIME_REGISTERED_3,DATE_DISCHARGED_3,DATE_OF_BIRTH,customer_ID)
SELECT TIME_REGISTERED,DATE_DISCHARGED,DATE_OF_BIRTH, customer_id
from customer1_details WHERE customer_id = '"+id+"' "
This is most likely caused by passing your Date and Timestamp variables as Strings to the insert statement.
When you insert or update Date or Timestamp values, there is a default format in which you can pass those values as strings. What you pass is java's idea of how to convert Dates and Timestamps into strings. These two don't seem to match.
Your best bet is probably to use bind variables, then the framework should take care of that.
An Alternative would be to use Oracle's to_date() function, where you can specify the format string. You would then define a format string which considers java's way of representing dates as strings. However, I am not sure if the java representation depends on the locale. If so, you would have to write you own date_to_string() method, which always returns dates in the same format, or your program may work on some computers, but not on others with a different locale.
And finally you can do an insert-select which bypasses the java layer entirely.
Read the timestamps as strings with getString();
OR call toString() in your java Timestamp object instances.
String sql1="INSERT INTO customer2_details(TIME_REGISTERED_3,DATE_DISCHARGED_3,DATE_OF_BIRTH,customer_ID) "
+ "VALUES('"+timereg.toString()+"','"+datedischarged.toString()+"','"+dob.toString()+"','"+id+"') ";
I am having a textbox field in my jsp called "req_date". The user is selecting a date from a javascript calendar in the format of "DD-MON-YY" ex. "29-aug-2010".So, now I am stuck while trying to insert it in the DB.
I tried " String queryString = "INSERT INTO Charity (req_date) VALUES (?)", but it is not inserting. How do I solve tis out.
The req_date is type of date in the DB.
Can you please help
Date format depends upon Database you use.
For reference Date formats with Oracle.
so your query should look like :
String queryString = "INSERT INTO Charity (req_date) VALUES (to_date('29-aug-2010', 'dd-mon-yyyy'))"
This is just to answer your question. But I will prefer usage of PreparedStatement as also suggested in other answers.
Your code using PreparedStatement should look something like following: (NOTE: I have not tested this code )
String formatIn = "dd-MMM-yyyy";
SimpleDateFormat sdfi = new SimpleDateFormat(formatIn);
java.util.Date inDate = sdfi.parse("29-Aug-2010");
java.sql.Date sqlDate = new java.sql.Date(inDate.getTime());
PreparedStatement prest = con
.prepareStatement("INSERT INTO Charity (req_date) VALUES (?)");
prest.setDate(1, sqlDate);
int row = prest.executeUpdate();
Use a PreparedStatement and its setDate(..). Or use a timestamp (long).
It depends on your database, PostgreSQL does recognize this format:
SELECT CAST('29-aug-2010' AS date);
Result:
'2010-08-29'
In most cases, you'd better use the ISO-format yyyy-mm-dd.