2

Hi i'm trying to insert a Date via Servlet in SQL database. If the post submitted field birthday is emtpy then it should insert 0000-00-00

but this is a bit complicated.

i did it this way and it works:

if (birthdate == null) {
            ps_employee.setInt(4, 0); //ps_employee is my PreparedStatement
        } else {
            ps_employee.setDate(4, birthdate);
        }

birthday is null if the post field has no value. otherwise birthday contains a valid java.sql.date object.

The code above works but it shows a warning in sql : "data for birthday truncated"....

Is there a better way to insert a 0000-00-00 Date ???

thanks for your help..

2
  • no: # Software: MySQL # Software version: 5.5.25a - MySQL Community Server (GPL) Commented Sep 25, 2012 at 21:24
  • 2
    You should not store invalid dates in the database. Use NULL instead. Commented Sep 26, 2012 at 6:28

7 Answers 7

3
  String query="INSERT INTO tablename values(?) "
  Connection connection = get the dbconn;
  PreparedStatement preparedStatement= connection.prepareStatement(query);      
  preparedStatement.setNull(0, java.sql.Types.DATE)
Sign up to request clarification or add additional context in comments.

7 Comments

I tried this allready but it throws an exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'Birthdate' cannot be null
@JannisHanke oh.. cant you just create a date with value 0000-00-00 usind simple date format and do an insert if birthdate null?
hm i also tried this : java.sql.Date.valueOf("0000-00-00"); but it throws an exception too.. :(
@JuanMendes on what line would it throwan exception ??
@JuanMendes i guess he meant for : java.sql.Date.valueOf("0000-00-00")
|
2

If the submitted field is empty, you should be storing null, not some magic value that will have to be checked by every application that uses the data for the next 20 years.

Convert null to '0000-00-00' -- or whatever -- on output.

2 Comments

Change the database schema. Really.
That means that your database design does not meet your business requirements. So you have two choices: first, force users to enter birthdates; second, change the database to allow nulls in the birthdate column. As a practical matter, the first option will be more painful than the second, so you should implement the second.
2

The solution hinges on the system's data integrity requirements.

There are two (and only two) choices:

  1. The system's design (there is a design, right?) requires that every record have a valid birthdate. In this case it is the responsibility of the UI to enforce this. Your code will never receive a null date, and is justified in throwing an exception if it does. This eliminates your problem.
  2. It is acceptable for birthdate to be missing in some cases. In this event, the table definition must be changed to allow null values.

The LAST thing you want to do is make up some special date value as a stand-in for NULL. THe fact that the column is NOT NULL is an indication that case (1) above applies, and your special date actually violates the system's data integrity invariants. Every future programmer tasked with maintaining the code will curse your name.

Comments

1

No Good Solution

The question of how to handle empty date-time values in a database has no good solution.

Avoid NULL

As Dr. Chris Date explains in A Guide to the SQL standard and elsewhere, NULLs are a bloody nightmare. Generally they should be avoided if at all possible. In SQL databases, that means declaring each column as NOT NULL (I wish there were a way to make that the default). Where sensible we set some kind of default value.

No Good Default Value For Date-Time

But setting a default value for date-time values can be very confusing. Neither the SQL standard nor JDBC/java.sql.* defines any particular value as a flag for being “empty”.

The java.time framework built into Java 8 and later does define minimum and maximum values as constants in the Instant, LocalDateTime, LocalDate, and LocalTime classes. These values might work as flag values except for the critical issue of resolution. These java.time classes resolve to nanoseconds while many databases have a larger granularity such as microseconds in Postgres. The min & max values are so extreme that their meaning would change when truncated to a smaller granularity.

Zero-Value

You might intuitively think to consider zero-value date-times, 0000-00-00 00:00:00.0 / 0000-00-00 / 00:00:00.0. Not so simple.

No Zero Month / Day

First of all, there is no such thing as a month of 00, nor day-of-month of 00. So, okay, we could change it to 0000-01-01, the first of January.

No Zero Year

Next issue: No such year as 0000. I don't know about all databases, but at least in Postgres there is no such zero year. Trying to insert such a value generates an error.

INSERT INTO moment_  -- TIMESTAMP WITH TIME ZONE.
VALUES (  '0000-01-01 00:00:00.0Z' ) ;

…throws error:

ERROR:  date/time field value out of range: "0000-01-01 00:00:00.0Z"
LINE 2: VALUES (  '0000-01-01 00:00:00.0Z' ) ;
                  ^
********** Error **********

Changing 0000 to year one 0001 works.

INSERT INTO moment_  -- TIMESTAMP WITH TIME ZONE.
VALUES (  '0001-01-01 00:00:00.0Z' ) ;

SET TIME ZONE 'UTC' ;

TABLE moment_ ;

0001-01-01 00:00:00+00

That number is the pivot point for BC versus AD eras. Let’s subtract an hour to see the behavior of moving from AD to BC. By the way strings such as BC are locale-dependent so may vary for you. Also, note that we must set the time zone to UTC to get this date-time operation to complete correctly.

SET TIME ZONE 'UTC' ;

INSERT INTO moment_  -- TIMESTAMP WITH TIME ZONE.
VALUES ( TIMESTAMP '0001-01-01 00:00:00.0Z' - INTERVAL '1 hour' ) ;

SET TIME ZONE 'UTC' ;

TABLE moment_ ;

The result is the year 0001 BC, so we jump from 0001 to 0001 BC; no year zero 0000.

"0001-12-31 23:00:00+00 BC"

So if you do decide to use a certain flag value, you cannot use a true zero value but you could use a near-zero value, the first of January of year one AD: '0001-01-01 00:00:00.0Z'

Time Zone

You must be careful about time zones when working with this special flag value.

When passing strings the SQL session’s current default time zone is applied implicitly (at least in Postgres).

Sorting NULLs

In my own work I do indeed make nearly all columns NOT NULL and set a default. But date-time columns have been an exception as there is no workable flag value. And I have suffered from this. Specifically I learned the hard way how to use NULLS FIRST/NULLS LAST modifiers because the SQL standard does not explicitly define a default sort order for NULL.

Comments

0

The reason you are getting the error is because you are attempting to insert an invalid date. There is no such thing as the 0 month and zero day. MySQL will not accept that as a date.

Either use NULL as the other users have described, or use some minimum baseline date that you define such as '1100-01-01'

3 Comments

i cant insert null.. this value isnt allowed in mysql database field "date" the null value is 0000-00-00
In your application treat a special value as empty then, such as 1100-01-01.
Actually MySQL will accept invalid dates (such as 2012-02-31 or 0000-00-00) but the JDBC driver will refuse to load them later because they are invalid and you cannot instantiate an invalid Date in Java.
0

The way I would do it is through the Default value for the column. Set the Default to '0000-00-00' or '0000-00-00 00:00:00' depending on the Type.

Once you have set up the default value in your DB then you just don't provide that field in your insert statements. You can do this for column that don't allow null, and it will still insert with the MySQL pseudo-null date.

If you do then you should also add this parameter to your SQL connection string, since you can't read a zeroDate...

zeroDateTimeBehavior=convertToNull

The end result is that you handle those dates as null in Java and as 0000-00-00 in the MySQL database.

Comments

0

If your data allows NULLs but your SQL table doesn't (for example dates part of composite keys) you can use a generally accepted "empty" value (GUI tools use this value) to represent a default/blank date. Here is and example:

private static final String EMPTY_MYSQL_DATE = "0000-00-00 00:00:00";    
...
if(someDateObj == null) {
    preparedStatement.setString(++psIndex, EMPTY_MYSQL_DATE);
} else {
    preparedStatement.setTimestamp(++psIndex, new Timestamp(someDateObj.getTime()));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.