SQL working on empty date - java

I am using java with jdbc to connecto to a MySQL database. I need to set one of date fields as empty. This field defaults to NULL and if i insert an empty string, the database creates a 0000-00-00 value in cell.
I then need to use that value in a report(jasperreport) and of course it can't be like 0000-00-00.
What I've tried to do:
Use if..then clause in query but i can't set it properly.
Has anyone an idea on how to get these date as empty string from the database (when I am calling jasperreport I am giving him just a sql query).

Set it to NULL in the DB, don't set it to an empty string.
Then write a select query which uses:
COALESCE(dt,'')
where dt is your date field.
Try this script as a test.
create table test(id int, dt datetime);
insert into test(id, dt) values (1, CURDATE());
insert into test(id, dt) values (2, NULL);
insert into test(id, dt) values (3, NOW());
insert into test(id, dt) values (4, NULL);
select
id, coalesce(dt, '') as dt
from
test;

Related

Issues inserting DATE value into Derby database

I am trying to setup a Derby database and insert some sample info into it for testing.
The code to get the tables I'd like is...
CREATE TABLE users(
userid varchar(128) primary key,
passwd_digest varchar(128)
);
CREATE TABLE customers(
cust_id int not null primary key(START WITH 1, INCREMENT BY 1),
cust_name varchar(128)
);
CREATE TABLE orders(
order_id int not null primary key,
cust_id int not null(START WITH 1, INCREMENT BY 1),
foreign key(cust_id) references customers(cust_id),
order_date date,
order_desc varchar(128)
);
Now when I try to insert the sample data into it using the following code:
insert into customers(cust_id, cust_name) values (3, 'Ringo');
insert into orders(order_id, cust_id, order_date, order_desc) values (4, 3, 12.12.1957, 'A drumset');
I get the following error from IJ:
ERROR 42X01: Syntax error: Encountered ".1957" at line 1, column 82.
Issue the 'help' command for general information on IJ command syntax.
Any unrecognized commands are treated as potential SQL commands and executed directly.
Consult your DBMS server reference documentation for details of the SQL syntax supported by your server.
I've tried putting the date values in the following ways (disregard the other data, it's only the dates that appear to not work) :
insert into orders(order_id, cust_id, order_date, order_desc) values (4, 3, 1957-12-12 00:00:00:000, 'A drumset');
insert into orders(order_id, cust_id, order_date, order_desc) values (4, 3, 1957-12-12, 'A drumset');
insert into orders(order_id, cust_id, order_date, order_desc) values (4, 3, "12-12-1957", 'A drumset');
insert into orders(order_id, cust_id, order_date, order_desc) values (4, 3, DATE("12-12-1957"), 'A drumset');
insert into orders(order_id, cust_id, order_date, order_desc) values (4, 3, 12-12-1957, 'A drumset');
but they all produce similar errors including:
ERROR 42821: Columns of type 'DATE' cannot hold values of type 'INTEGER'.
I'm not sure why I'm getting these errors since I'm putting in values matching the format of Derby's docs (at least it looks that way to me, since it's not working I'm sure I've got it wrong somewhere).
Use the DATE or TIMESTAMP functions, or the JDBC escape syntax, whichever you prefer, to convert your literal values into date or timestamp data types.
Or write your insert logic in Java using PreparedStatement, and use the setDate() and setTimestamp() functions.
Various docs for the above:
DATE function: https://db.apache.org/derby/docs/10.15/ref/rrefdatefunc.html
TIMESTAMP function: https://db.apache.org/derby/docs/10.15/ref/rreftimestampfunc.html
JDBC Escape syntax for dates and times: https://db.apache.org/derby/docs/10.15/ref/rrefjdbc1020262.html
PreparedStatement: https://stackoverflow.com/a/18615191/193453

Unable to insert Date into HSQLdb

I am using HSQL as an in memory database for testing. However, I am unable to insert a date into the column.
Below is my table creation script:
SET DATABASE SQL SYNTAX ORA TRUE;
create table OWN_TABLE (
ID DECIMAL NOT NULL,
NAME VARCHAR(24) NOT NULL,
CAPACITY_SUPPLY_DATE DATE ,
);
And the queries I tried:
INSERT INTO OWN_TABLE(ID, NAME, CAPACITY_SUPPLY_DATE) VALUES(2, '4813', '2090-07-15');
But it gives
Caused by: java.sql.SQLDataException: data exception: invalid datetime format
I also tried 2090-07-15 00:00:00 but it didn't work.
Assuming oracle syntax might work, I tried:
INSERT INTO LABS_CAPACITY_SUPPLY(ID, SHIP_NODE, CAPACITY_SUPPLY_DATE) VALUES(1, '4813', 'TO_DATE(2090-07-30,"yyy-MM-dd")');
But got Unparseable date: "TO_DATE(2090-07-30,"yyy-MM-dd")"
Can somebody please tell me the right way to insert dates into HSQL. I have the 2.3.2 jar.
Use a proper standard SQL date literal:
INSERT INTO OWN_TABLE
(ID, NAME, CAPACITY_SUPPLY_DATE)
VALUES
(2, '4813', DATE '2090-07-15');
Or, if you do want to use the to_date() function then don't put it into single quotes.
INSERT INTO LABS_CAPACITY_SUPPLY
(ID, SHIP_NODE, CAPACITY_SUPPLY_DATE)
VALUES
(1, '4813', TO_DATE(2090-07-30,'yyy-MM-dd'));
Note that for the to_date() function the case of the format string does not matter. 'yyyy-MM-dd' is the same as 'YYYY-MM-DD' or 'yyyy-mm-dd'. The format is not the one used for Java's SimpleDateFormat.
If you are doing this from within a Java program you should not use any of the above solutions. Use a PreparedStatement instead:
java.sql.Date dt = ...;
PreparedStatement pstmt = connect.prepareStatement("INSERT INTO OWN_TABLE(ID, NAME, CAPACITY_SUPPLY_DATE) VALUES(?,?,?)";
pstmt.setInt(1, 2);
pstmt.setString(2, "4813");
pstmt.setDate(3, dt);
How you construct the instance of java.sql.Date depends on where you get the data from. You could use a SimpleDateFormat to parse the user's input. Or you could use LocalDate if you are using Java 8, e.g. java.sql.Date.valueOf(LocaleDate.of(2090,7,30))

SQL datetime from java

I'm trying to add a DATETIME value to the SQL database from Java. Actually I load the java.sql.Date object to an object array and then load the value into the prepared statement from the array.
This is my code:
java.util.Calendar cal = java.util.Calendar.getInstance();
java.sql.Date timestamp = new java.sql.Date(cal.getTimeInMillis());
values[0] = timestamp;
This is the exception that I am getting when I run the code:
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'UPDATE_DATE'.
Stack trace:com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'UPDATE_DATE'.
UPDATE_DATE is the column name in the table. Kindly help me out in this.
EDIT : This is the query:
INSERT INTO EXAMPLETABLE VALUES UPDATE_DATE=?,CONT_STATUS_NEW_ID=?,CONT_STATUS_DESC=?,LOCATION_ID=?,READ_STATUS=?,CONT_TYPE_ID=?,CONT_TYPE_DESC=?,CONT_ID=?
This is where the exception is thrown:
((PreparedStatementDataTarget) insertTarget).executeUpdate(values,arguments);
Actually you can't get anything out of the execute statement since it implements a lot of classes and custom methods. If there is anything wrong , then it should be in the logic which I use to add the date to the Object array (values) .
You are mixing insert and update syntax. You should either use
INSERT INTO tableName [(column list)] VALUES (values list)
Or
UPDATE tableName
SET column = value
[, column = value]
[WHERE condition]
Note #1: square brackets mean the part inside is optional.
Note #2: column list stands for column names delimited by a comma, values list stands for values delimited by a comma.

JDBC: multicolumn IN query

I have a following query:
SELECT
date, userId, value
FROM
tbl_table
WHERE
date = to_date(:date, 'YYYY-MM-DD')
AND
userId = :userId
It allows to request for a single value like this:
MapSqlParameterSource args = new MapSqlParameterSource();
args.addValue("date", date, Types.VARCHAR);
args.addValue("userId", userId, Types.VARCHAR);
SqlRowSet rowSet = jdbcTemplate.queryForRowSet(SQL_SELECT, args);
jdbcTemplate.queryForRowSet(SQL_SELECT_MARKET_VALUE, args);
This is totally ok, but extremelly slow in case you have to query value for many date/userId pairs.
I would like to optimize it using multicolumn IN clause, but how do I handle multicolumn list via JDBC (or better question: is it possible using JDBC)?
Oracle supports multiple columns in "in" predicate:
SELECT
date, userId, value
FROM
tbl_table
WHERE
(date, userId) IN ((to_date(:date1, 'YYYY-MM-DD'), :userId1), (to_date(:date2, 'YYYY-MM-DD'), :userId2))
However JDBC doesn't provide a decent support of in-statement parameters - you will have to build the query using StringBuilder or use some of workarounds described here
It depends of details. If user/date filter is quite persistent (should be user more than once) temporary table will be the best decision. You can fill it once, you can edit it, and you can use it several times without reloading.
If you need of quite large number of pairs, I'd recommend you to use a table type. It would be something like this:
create type DateUserPair as object (dt date, userid integer);
create type DateUserPairs as table of DateUserPair;
....
SELECT
date, userId, value
FROM
tbl_table src,
table(cast :filter as DateUserPairs) flt
WHERE
src.date = flt.dt and
src.userId = flt.userId;
If filter would be small, filtering by (date, userId) in ((?,?), (?,?), ...) would be simple and clever.
Btw, your approach
date = to_date(:date, 'YYYY-MM-DD')
isn't good practise. Such conversions should be done by client, not by server. Use
date = :date
and assign it as date instead.
If what you want is to pass JDBC a list of date/userId pairs, or a list of dates and a list of userIds, I think it will not work.
A possible workaround in Oracle would be using a global temporary table with ON COMMIT DELETE ROWS. Your would have:
-- DDL for the workaround
CREATE GLOBAL TEMPORARY TABLE admin_work_area
(d DATE,
userId VARCHAR2(10))
ON COMMIT DELETE ROWS;
...
-- Start of query method pseudo-code
...
-- You should be able to JDBC-batch these for better performance
INSERT INTO temp_multicolumn_filter (d, userId) VALUES (date1, userId1);
INSERT INTO temp_multicolumn_filter (d, userId) VALUES (date2, userId2);
...
-- Query using temp_multicolumn_filter
SELECT date, userId, value
FROM tbl_table
WHERE
(date, userId) in (select d, userId from temp_multicolumn_filter);
...
-- End of query method pseudo-code
As the temporary table has the ON COMMIT DELETE ROWS, each transaction will only see its own date/userId pairs. Just remember that if you use the temporary table more than once in the same transaction, you might need to clear it before using it.
UPDATE:
Another option would be using a PIPELINED PL/SQL function to "build" your table inside the query:
-- DDL for this workaround
CREATE TYPE date_userid_pair AS OBJECT (
d DATE,
userId VARCHAR2(10));
CREATE TYPE date_userid_dataset IS TABLE OF date_userid_pair;
CREATE FUNCTION decode_date_userid_pairs(dates in varchar2, userIds in varchar2)
RETURN date_userid_dataset PIPELINED IS
result_row date_userid_pair;
BEGIN
WHILE there are more "rows" in the parameters LOOP
result_row.d := -- Decode next date from dates
result_row.userId := -- Decode next userId from userIds
PIPE ROW(result_row);
END LOOP;
END;
// Start of query method pseudo-code
...
// This is Java code: encodeList encodes a List of elements into a String.
encodedDates = encodeList(listOfDates);
encodedUserIds = encodeList(listOfUserIds);
...
// Query using temp_multicolumn_filter
SELECT date, userId, value
FROM tbl_table
WHERE
(date, userId) in (
select date, userId
from TABLE(decode_date_userid_pair(:encodedDates, :encodedUserIds));
...
// End of query method pseudo-code
But this is more hacky, and if you don't have privileges to create a temporary table, then you probably won't have CREATE TYPE either (you might not even have CREATE FUNCTION privilege).

Cassandra time stamp returns 0 rows

I created table column datatype as timestamp while storing it stores the default timestamp format yyyy-mm-dd HH:mm:ssZbut when try to select based on timestamp it doesn't return record.
CREATE TABLE TEST
(
TS timestamp,
VALUE text,
EMAILID text,
PRIMARY KEY (TS,VALUE)
);
INSERT INTO TEST(TS,VALUE,EMAILID) VALUES('1418026180922','sometext','email#');
SELECT * FROM TEST WHERE TS='2014-12-08 00:38:10-0800' ALLOW FILTERING;
THIS Query returns 0 rows? Why it returns like that am i doing something wrong?
It works for below query:
SELECT * FROM TEST WHERE TS='1418026180922' ALLOW FILTERING;
Your query
SELECT * FROM TEST WHERE TS='2014-12-08 00:38:10-0800' ALLOW FILTERING;
discards (or rather ignores) the millisecond part of the timestamp you use to insert the row
1418026180922
// ^^^^
And so the dates aren't equal.
If you had instead inserted
INSERT INTO TEST(TS,VALUE,EMAILID) VALUES('14180261800000','sometext','email#');
you could retrieve it with
select * from test where ts='2014-12-08 00:09:40-0800'; // note that I've fixed it from your '2014-12-08 00:38:10-0800'

Categories

Resources