I have a table called Abbonamento that has the following attributes:
Abbonamento(idAbbonamento, tipo, DataInizio, DataScadenza, ....)
DataInizio and DataScadenza are of type DATE.
The problem borns when I do a select on this table:
String queryAbb = "select idabbonamento, tipo, DATE_FORMAT(datainizio,'%d-%m-%Y'), DATE_FORMAT(datascadenza,'%d-%m-%Y'), ...;
prest = con.prepareStatement(queryAbb);
rs = prest.executeQuery();
while (rs.next()) {
a=new Abbonamento();
a.setIdAbbonamento(rs.getInt(1));
a.setTipo(rs.getString(2));
a.setDataInizio(rs.getDate(3));
System.out.println(rs.getDate(3));
a.setDataScadenza(rs.getDate(4));
...
}
Now, if the date DataInizio in the db is for example 2013-11-05 00:00:00 I would like to have 05-11-2013 but the println prints 0004-10-13.
What's wrong with the code above?
Instead of
rs.getDate(3)
you should use
rs.getString(3)
because the data is already formatted as String. If you want to get as Date, first, a Date object is created from your 05-11-2013 string, then you receive that.
If you have Date objects in your objects, you should either parse() the returnes string with the same format you returned from the DB, or let the JDBC do the conversion for you (in this case, simply select idabbonamento, tipo, datainizio, ...) without formatting.
I recommend that let JDBC do it. Less user code, less trouble :)
String queryAbb = "select idabbonamento, tipo, datainizio, datascadenza, ...";
...
a.setDataInizio(rs.getDate(3));
// reading the formatted data:
System.out.println(new SimpleDateFormat().format(a.getDataInizio());
Actually, there is one more trick, but you don't have to care about: rs.getDate() returns java.sql.Date, but you probably use java.util.Date. That's not a problem, because java.sql.Date is a subclass of java.util.Date, so this assignment is totally valid.
Try this:
select idabbonamento, tipo, convert(char(10), datainizio, 105)....
In a database-independent way, you could use java.text.SimpleDateFormat. For example:
java.util.Date date = rs.getDate(3);
String dateFormatted = (new java.text.SimpleDateFormat()).format(date);
a.setDataInizio(dateFormatted);
Related
So I'm trying to get a basic sql string to work where it will grab the records in the sqlite database based on between dates. However, for some reason, it doesn't work. I just don't understand why.
private void viewTransactionsBetweenDatesTable(){
//Sets the table to view transactions between certain dates
try{
//Get's the dates from startDateChooserTransactions1 and endDateChooserTransactions1
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
DateFormat df2 = new SimpleDateFormat("MMM dd, yyyy");
Date sdct = startDateChooserTransactions1.getDate();
Date edct = endDateChooserTransactions1.getDate();
String sdcts = df.format(sdct);
String edcts = df.format(edct);
String sdctlabel = df2.format(sdct);
String edctlabel = df2.format(edct);
//Child's ID
String cid = childIDCheck1.getText();
//Grab's the specified data and places that as the table
String sql = "SELECT * FROM ChildrenPayment WHERE ChildID='"+cid+"' AND strftime('%Y-%m-%d', 'Report Transaction Date') BETWEEN '"+sdcts+"' AND '"+edcts+"' ";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
//Sets up the table
Info1.setModel(DbUtils.resultSetToTableModel(rs));
TableColumnModel tcm = Info1.getColumnModel();
//tcm.removeColumn(tcm.getColumn(3));
// tcm.removeColumn(tcm.getColumn(3));
// tcm.removeColumn(tcm.getColumn(10));
// tcm.moveColumn(11, 10);
// tcm.removeColum(tcm.getColumn(13));
//Changes modLabel1
modLabel1.setText(firstNameEditClass1.getText() + " " + lastNameEditClass1.getText() + " Between " + sdctlabel + " - " + edctlabel);
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}finally{
try{
pst.close();
rs.close();
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
}
I am using a jdatechooser so I am sort of forced to use SimpleDateFormat compared to the better DateTimeFormatter. Anyway, I'm formatting it according to YYYY-MM-DD like sqlite likes, but when I run the function, the table does not display anything. I set the days pretty wide (Feb 01, 2018 to Feb 14, 2018) and the date in my database is Feb 07, 2018. I have a few records in the database for it to pull. However, it just doesn't do it. And no error is popping up, so I do not know why it is not working.
Image of the records that I'm trying to place into my jtable
Edit1: Before I forget, I also tried the following SQL string
String sql = "SELECT * FROM ChildrenPayment WHERE ChildID='"+cid+"' AND 'Report Transaction Date' BETWEEN '"+sdcts+"' AND '"+edcts+"' ";
This will not work:
strftime('%Y-%m-%d', 'Report Transaction Date')
because the format specifiers you have provided require that you supply three values, one each for year, month, and day.
If the dates in the database are stored as complete SQLite datetime strings, you will have to use
"... date([Report Transaction Date]) BETWEEN '"+sdcts+"' AND '"+edcts+"' ";
Note square brackets (not single quotes) around column name. This has nothing to do with needing a date/time value, it's because the column name has spaces in it. Any column name with spaces has to be enclosed in double quotes or square brackets. That's why it's a good idea to never use spaces in column names.
If they are, in fact, stored as 'YYYY-MM-DD' strings, then the reason your alternative didn't work is because you single-quoted the column name 'Report Transaction Date', which results in comparing that literal string to the date values.
how can i map following query in jdbctemplate
select count(*),trim(rdate)
from man
where r='AGREE' and
rdate LIKE date '2016-04-12'
group by trim(rdate);
where i am sending date argument dynamically and this query/method should return type int only.
query in jdbc template should be like
select count(*),trim(rdate)
from man
where r='AGREE' and
rdate LIKE date ?
group by trim(rdate);
where i replace date with ? and it should return type int only
can anyone help me for this?
Here I am going to get data based on date only but my data continence both date and time here I am using like query to select that data based on date but I am not getting it can any plz exp line it thanks.
String device = "NR09G05635";
String date = "2013-11-29";
java.util.Date temp = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse(date);
java.sql.Date date1 = new java.sql.Date(temp.getTime());
sql = "select * from gpsdata1 where deviceId=? and dateTime like '" + date1 + "'";
System.out.println("sql" + sql);
ps1 = con.prepareStatement(sql);
ps1.setMaxRows(1);
ps1.setString(1, device);
ps1.execute();
rs = ps1.getResultSet();
-You use the LIKE operator to compare a character, string, or CLOB value to a pattern. Case is significant. LIKE returns the BOOLEAN value TRUE if the patterns match or FALSE if they do not match
Use TO_CHAR to explicitly create a string based on a DATE, using the format you want. Don't rely on implicit conversions.
Select *
From gpsdata1
Where NVL ( TO_CHAR ( dateTime
, 'YYYY-MM-DD HH:MI:SS AM'
)
, ' ' -- One space
) Like '%';
SELECT * FROM gpsdata1
WHERE deviceId=? and CONVERT(VARCHAR(25), dateTime, 126) LIKE '2013-11-19%'
LIKE operator does not work against DATETIME variables, but you can cast the DATETIME to a VARCHAR
I've looked around and could not seem to find this asked specifically, on SO, but I've found similar questions like this one and lots of questions regarding SQL itself or C#...
Here is what I am seeing:
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
//parameterSource.addValue( "insertDate", DateTime.now().minusHours( 1 ).toGregorianCalendar(), Types.TIME );
parameterSource.addValue( "insertDate", new Timestamp( DateTime.now().minusHours( 1 ).getMillis() ) );
List< String > contents =
_simpleJdbcTemplate
.query(
"SELECT TOP (200) inserteddatetime, Contents FROM dbo.tsomeTable WHERE (ServiceName = 'something') and inserteddatetime > :insertDate",
new RowMapper< String >() {
#Override
public String mapRow( final ResultSet rs, final int rowNum ) throws SQLException {
System.out.println( rs.getTimestamp( "inserteddatetime" ) );
return rs.getString( "Contents" );
}
}, parameterSource );
The query "hangs"\does nothing\never returns if:
I use the uncommented Timestamp object (as presented above)
I replace the parameterSource object with DateTime.now().minusHours( 1 ).toGregorianCalendar() or DateTime.now().minusHours( 1 ).toGregorianCalendar().getTime()
I try the commented out line, but change the type to Timestamp
So, here is my question or questions...
Is there a known bug\issue with querying on datetime columns in sql server?
Why do I have to use Time and not Timestamp?
I suspect that Spring is converting the date objects over to Timestamp when I query with the object directly (as demonstrated in #2).
TIMESTAMP is a server-generated value used to help with data consistency, its not a simple data type, so for storing datetime value, avoid TIMESTAMP datatype.
Also, SQL Server TIMESTAMP is confusing, and it's deprecated. It is replaced by the ROWVERSION keyword, which should reduce confusion.
I have the following
DateFormat dformat = new SimpleDateFormat("yyyy-M-d");
dformat.setLenient(false);
Date cin = dformat.parse(cinDate);
and the sql function
create or replace function search(_checkIn date, _checkOut date) returns setof Bookings as $$
declare
r Bookings;
begin
for r in
select * from Bookings
loop
if ((_checkIn between r.checkIn and r.checkOut) or (_checkOut between r.checkIn and r.checkOut)) then
return next r;
end if;
end loop;
return;
end;
$$ language plpgsql;
The date format for the postgresql is standard (default)
create table Bookings (
id serial,
status bookingStatus not null,
pricePaid money not null,
firstName text,
lastName text,
address text,
creditCard text,
checkOut date not null,
checkIn date not null,
room integer not null,
extraBed boolean not null default false,
foreign key (room) references Rooms(id),
primary key (id)
);
and I'm trying to parse a date into the function so it can return a table for me, I seem to run into the issue of date formatting (which is why I think I'm getting this error)
org.postgresql.util.PSQLException: ERROR: syntax error at or near "Feb"
So I was wondering how would I fix this problem, I don't know how to format the date properly
EDIT:
I'm calling the query like this
try {
String searchQuery = "SELECT * FROM Rooms r where r.id not in (select * from search(" + cin +", " + cout +"))";
PreparedStatement ps = conn.prepareStatement(searchQuery);
rs = ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
so I think the error comes in because the way I format the date is wrong and postgres won't read it
It sounds like you're passing the argument by concatenating them directly into the string. This is a very bad idea, since it can lead to SQL injections. Always use PreparedStatements with the ? place-holders to pass parameters, never pass them directly by concatening them directly into the query string (more so, you'd need the ' delimiters around).
You could have something like:
PreparedStatement stmt
= con.prepareStatement("SELECT id FROM Bookings WHERE checkIn=?")
stmt.setDate(1, new java.sql.Date(cin.getTime()));
// ? parameters are indexed from 1
ResultSet results = stmt.executeQuery();
Alternatively, PostgreSQL internal date conversion is usually fairly good and flexible. You could cast the string parameter to a date with PostgreSQL:
PreparedStatement stmt
= con.prepareStatement("SELECT id FROM Bookings WHERE checkIn=CAST(? AS DATE)");
stmt.setString(1, cinDate);
ResultSet results = stmt.executeQuery();
This is flexible, but might not lead to the exact result you need depending on the date format (you can check the PostgreSQL manual for details on date conversion formats). The input format you're using should work just fine, though (Try SELECT CAST('2012-05-01' AS DATE) directly in PostgreSQL, for example, this will return a correct PostgreSQL date.)
Note that when using new java.sql.Date(cin.getTime()), you're likely to run into time zone issues. You could use java.sql.Date.valueOf(...) too.
To clarify, following your edit:
This will not work, since the dates would be part of the SQL syntax itself, not strings or dates: "SELECT * FROM Rooms r where r.id not in (select * from search(" + cin +", " + cout +"))"
You'd at least need to use ' quotes: "SELECT * FROM Rooms r where r.id not in (select * from search("' + cin +"', '" + cout +"'))". Here, to a degree, you could expect the parameters to be formatted properly, but don't do it. In addition, would would still have to cast the string using CAST('...' AS DATE) or '...'::DATE.
The simplest way would certainly be:
String searchQuery = "SELECT * FROM Rooms r where r.id not in (select SOMETHING from search(CAST(? AS DATE), CAST(? AS DATE)))";
PreparedStatement ps = conn.prepareStatement(searchQuery);
ps.setString(1, cinDate);
ps.setString(2, coutDate);
(As a_horse_with_no_name pointed out in a comment, the general query wouldn't work anyway because of your inner select.)
You already have advice concerning prepared statements and proper format.
You can also largely simplify your PostgreSQL function:
CREATE OR REPLACE FUNCTION search(_checkin date, _checkout date)
RETURNS SETOF bookings AS
$BODY$
BEGIN
RETURN QUERY
SELECT *
FROM bookings
WHERE _checkin BETWEEN checkin AND checkout
OR _checkiut BETWEEN checkin AND checkout;
END;
$BODY$ language plpgsql;
Or even:
CREATE OR REPLACE FUNCTION search(_checkin date, _checkout date)
RETURNS SETOF bookings AS
$BODY$
SELECT *
FROM bookings
WHERE _checkin BETWEEN checkin AND checkout
OR _checkiut BETWEEN checkin AND checkout;
$BODY$ language sql;
Rewrite the LOOP plus conditions to a plain SQL statement which is much faster.
Return from a plpgsql function with RETURN QUERY - simpler and faster than looping.
Or use a plain sql function.
Either variant has its advantages.
No point in using mixed case identifiers without double quoting. Use all lower case instead.
According to this page, the standard format for date/time strings in SQL is:
YYYY-MM-DD HH:MM:SS
And of course for dates you can use
YYYY-MM-DD
PostgreSQL accepts other formats (see here for some details) but there's no reason not to stick to the standard.
However, since you are getting a syntax error it sounds like you are injecting the date strings into your SQL statement without the proper quoting/escaping. Double-check that you are properly escaping your input.