SQL "missing in or out parameter at index" - java

i have this code for create query and execute sql-procedure but i catch missing-exception
public String generateQuery(Integer idAccount, Long[] phoneList, Date date){
StringBuilder query=new StringBuilder();
query.append("declare arr_pn owa_util.vc_arr;\n");
query.append("begin\n");
int idx = 1;
for (Long p : phoneList)
{ query.append("arr_pn(" + idx + "):='" + String.valueOf(p) + "';\n"); idx++; }
query.append("call LOC_MAINCLIENT.set_client_relations(");
query.append("id_account_ => " + idAccount);
query.append(", phone_number_list_ => arr_pn");
query.append(", dt_ => " + date);
query.append("); end;");
return String.valueOf(query);
}
after that i get this query
declare arr_pn owa_util.vc_arr;
begin
arr_pn(1):='12345';
arr_pn(2):='678970';
arr_pn(3):='5675675';
call LOC_MAINCLIENT.set_client_relations(id_account_ => 123, phone_number_list_ => arr_pn, dt_ => Sun Mar 24 21:54:00 NOVT 2013); end;
what i did wrong?

At the moment the date string isn't quoted, so it's in valid anyway, but the colons will be interpreted by the parser as bind variable markers; specifically it'll be looking for bind variables :54 and :00.
The quick answer is to put the date string into quotes. But that date format is unlikely to match what your database (session) is expecting, so you'd need to format the date into a string it can use and provide the format as well to avoid ambiguity.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
query.append(", dt_ => to_date('" + sdf.format(date)
+ "', 'YYYY-MM-DD HH24:MI:SS')");
You also don't need the call, so get rid of that. That would produce a string like this (with added line breaks and indentation to make it a little easier to see):
declare
arr_pn owa_util.vc_arr;
begin
arr_pn(1):='12345';
arr_pn(2):='678970';
arr_pn(3):='5675675';
LOC_MAINCLIENT.set_client_relations(id_account_ => 123,
phone_number_list_ => arr_pn,
dt_ => to_date('2013-03-24 21:54:00', 'YYYY-MM-DD HH24:MI:SS'));
end;
Assuming your package procedure is declared as:
procedure set_client_relations(id_account_ number,
phone_number_list_ owa_util.vc_arr, dt_ date);
... this this should run. Whether it does what you actually want is a different matter, of course.
You may also need to do something with the time zone if the database doesn't match your locale.
The proper way to do it is to use a prepared statement, provide all the values as bind variables, and pass the correct data types - passing the date as a date rather than as a string representation. That's a little more complicated for an array but certainly do-able. You've said this is legacy code and you have to use this, but you should still investigate switching to bind variables.

Related

How to search by not complete timestamp by Criteria API

I want to search in DB all rows with a part of Timestamp like "2014-08-12". And if there are rows like "2014-08-12 16:58:48.477" or "2014-08-12 15:58:48.477" I want to get it
I use JPA + Hibernate + Criteria API
document.setRegister_date(DateUtil.DateToSQLTimestamp("2013-08-12 16:58:48.477"));
if (register_date != null) {
predicates.add(cb.equal(DocumentsRoot.get("register_date"), register_date));
}
If you know that the format will always exclude time, you can use a range query where you can set the from as 00:00:00.001 and to as 23:59:59.999
String date = "2013-08-12";
document.setRegister_date(DateUtil.DateToSQLTimestamp(date + " 00:00:00.000"));
document.setRegister_end_date(DateUtil.DateToSQLTimestamp(date + " 23:59:59.999"));
Timestamp register_date = document.getRegister_date();
Timestamp register_end_date = document.getRegister_end_date();
predicates.add(cb.between(DocumentsRoot.get("register_date"), register_date, register_end_date));

Play scala, java.sql.date throws me errors, trying to build a to-do form

I'm trying to build a to-do list using play. Now the issue I'm having, is that I can't seem to use the SQL format Date in my parser.
package models
import java.sql.Date
import anorm.SqlParser._
import anorm._
import org.joda.time.DateTime
import play.api.Play.current
import play.api.db.DB
case class Task(
id:Int,
task:String,
description:String,
dueDate:Date
)
object Task {
val task = {
get[Int]("id") ~
get[String]("task")~
get[String]("description")~
get[Date]("dueDate")map {
case id~task~description~dueDate => Task(id, task, description, dueDate)
}
}
def all(): List[Task] = DB.withConnection { implicit c =>
SQL("select * from task").as(task *)
}
def create(task: String, description: String, dueDate:Date): Unit = {
DB.withConnection { implicit c =>
SQL("insert into task(task, description, dueDate) values ({task},{description},{dueDate})")
.on(
'task -> task,
'description -> description,
'dueDate -> dueDate
).executeUpdate()
}
}
def delete(id: Int) {
DB.withConnection { implicit c =>
SQL("delete from task where id = {id}")
.on('id -> id).executeUpdate()
}
}
}
getDate throws me the following error:
could not find implicit value for parameter extractor: anorm.Column[java.sql.Date]
When I change SQL Date to util Date, it'll whine that SQL Date is expected. The parameter dueDate should become the SQL column whith custom dates as input.
How do I fix this? Is it even possible to use java.sql.date in Scala?
(Im using h2-db for my SQL)
If you need more info, leave a hint.
You shouldn't use java.sql.Date for your domain model. Use java.time.LocalDate or org.joda.time.LocalDate instead; anorm's Column type knows how to handle these by default.
You could try to write your own implicit conversion. Something like this:
import anorm._
implicit def toSqlDateColumn = Column.nonNull { (value, meta) =>
val MetaDataItem(qualified, nullable, clazz) = meta
value match {
case date: java.sql.Date => Right(date)
case _ => Left(TypeDoesNotMatch(s"Cannot convert $value : ${value.asInstanceOf[AnyRef].getClass} to java.sql.Date for column $qualified"))
}
}
If you're OK with using java.util.Date the following should work
Replace
get[Date]("dueDate")
with
date("dueDate")
It looks like by default it uses java.util.Date. See the date method in the SqlParser docs:
play docs anorm.sqlParsers

Parse string description of timezone

I get information about timezone in such string format.
(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius
Is it somehow possible to parse it into some TimeZone object in Java with standard library or external one?
Depending how you want to use the TimeZone afterwards you might either create a custom one
String input = "(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius";
// assuming the format is always fixed at the beginning
String timeZoneOffset = input.substring(4,10);
TimeZone timeZone = TimeZone.getTimeZone("GMT" + timeZoneOffset);
System.out.println("timeZone = " + timeZone);
output (line wrapped)
timeZone = sun.util.calendar.ZoneInfo[id="GMT+02:00",offset=7200000,dstSavings=0,\
useDaylight=false,transitions=0,lastRule=null]
You might get into trouble related to the daytime savings.
Or you create a lookup map with an entry for each offset (stripped down code snipped)
String input = "(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius";
// assuming the format is always fixed at the beginning
String timeZoneOffset = input.substring(4,10);
// needs to be initialized somewhere
Map<String, TimeZone> timeZones = new HashMap<>();
// you need to add all offsets
timeZones.put("+02:00", TimeZone.getTimeZone("EET"));
System.out.println("timeZone lookup = " + timeZones.get(timeZoneOffset));
output (line wrapped)
timeZone lookup = sun.util.calendar.ZoneInfo[id="EET",offset=7200000,dstSavings=3600000,\
useDaylight=true,transitions=123,lastRule=java.util.SimpleTimeZone[id=EET,offset=7200000,\
dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,\
startDay=-,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,\
endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]

Android : Error SimpleDateFormat Unknown pattern character 'u'

I use java 1.7.25
but found this error. what should I do?
FATAL EXCEPTION: main
java.lang.IllegalArgumentException: Unknown pattern character 'u'
at java.text.SimpleDateFormat.validateFormat(SimpleDateFormat.java:264)
at java.text.SimpleDateFormat.validatePattern(SimpleDateFormat.java:319)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:365)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:249)
Here is my code
public static int getDayNumberOfWeek(int day, String monthString, int yyyy) {
//http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
int dayNumberOfWeek = 1;
final String inputFormat = "MMM/dd/yyyy";
final String outputFormat = "u";
String dayString2Digit = DateTimeHelper.getTwoDigit(day);
String inputTimeStamp = monthString + "/" + dayString2Digit + "/" + String.valueOf(yyyy);
try {
dayNumberOfWeek =Integer.valueOf(TimeStampConverter(inputFormat, inputTimeStamp,
outputFormat));
}
catch (ParseException e) {
e.printStackTrace();
}
return dayNumberOfWeek;
}
I use java 1.7.25
No, you don't - not if you're running on Android. You need to look at the Android documentation, not the Java 7 docs.
If you look at the Android SimpleDateFormat documentation you'll see that u isn't listed there. I don't believe there's a format pattern character for "day of week as a number" in Android.
Were you really looking for that though? If you just want the day of the week as a number (without anything else) you can always use
String text = String.valueOf(calendar.get(Calendar.DAY_OF_WEEK));
If you're using android, then you're not using Java 1.7.25. See the android documentation: there's no support for u in SimpleDateFormat.
I'm guessing your problem is going to be in your TimeStampConverter class where you're passing in that "u" as the outputFormat. "u" is not a valid format character in SimpleDateFormat and you must be constructing a format string that contains it.
If you need to use the "u" as a literal, you'll need to enclose it in single quotes.

Strip timestamp from the date field in Datatables

I am using jquery Datatables plugin. I followed the link http://www.codeproject.com/Articles/190718/jQuery-DataTables-and-J2EE-web-application-integra
I am passing a Date in the JSON object to the datatables plugin. The format from webservice call is like
"Sat Jan 10 00:08:00 EST 2009"
, I need to strip off the time, EST and the day, I mean it should look something like
"Jan 10, 2009"
and the column is sorted on the server side. All I need is to strip off the data on the fly on the client side. I am still in the process of learning datatables plugin, I am not sure of implementing this. Experts please point me to the right direction.
[Edit] Since it looks like the date comes back from the server as a string then you're easiest solution is probably a regular expression. Try this:
function reformatDate(dateStr) {
var r = /^\w{3}\s+(\w{3})\s+(\d{1,2})\s+.*?(\d{4})$/
, m = (''+dateStr).match(r);
return (m) ? m[1]+' '+m[2]+', '+m[3] : dateStr;
}
[Original] Assuming you are working with an actual Date object and you don't want to incur the overhead of a proper JavaScript date wrangling library (such as the excellent Datejs) you could format the date like so:
var formatDate = (function() {
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return function(dt) {
return months[dt.getMonth()] + ' ' + dt.getDate() + ', ' + dt.getFullYear();
};
})();
formatDate(new Date()); // => "Mar 15, 2012"
I'm not sure if you can do this with bServerSide set to true but you might be able to setup column definitions using the aoColumns option for the datatable and then apply column rendering via
fnRender: function (o, val) {
parse your date here...
return newDateString;
}

Categories