복붙노트

[SQL] 처리 DATETIME는 JDBC에 0000-00-00 0시 0분 0초 값

SQL

처리 DATETIME는 JDBC에 0000-00-00 0시 0분 0초 값

나는 (아래 참조) 내가하려고하면 예외가

resultset.getString("add_date");

난 그냥 아닌 같은 문자열로 값을 얻으려고해도 0000-00-00 0시 0분 0초 (DATETIME에 대한 준 널 (null) 값)의 DATETIME 값을 포함 MySQL 데이터베이스에 대한 JDBC 연결을위한 목적.

나는 수행하여이 주위에있어

SELECT CAST(add_date AS CHAR) as add_date

이는이 할 수있는 더 나은 방법이있다 ... 작동하지만, 바보 같다?

내 요점은 내가 나 자신을있는 그대로 분석 할 수 있도록 그냥 원시 DATETIME 문자열을 원하는 것입니다.

참고 : 0000이 들어오는 곳 여기 (http://dev.mysql.com/doc/refman/5.0/en/datetime.html에서)

특정 예외는 이것이다 :

SQLException: Cannot convert value '0000-00-00 00:00:00' from column 5 to TIMESTAMP.
SQLState: S1009
VendorError: 0
java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 5 to TIMESTAMP.
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
    at com.mysql.jdbc.ResultSetImpl.getTimestampFromString(ResultSetImpl.java:6343)
    at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5670)
    at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5491)
    at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5531)

해결법

  1. ==============================

    1.나는이 같은 문제를 해결하기 위해 시도를 우연히 발견했다. 나는이에게 다른 방식으로해야 할 일을했을 때문에 설치가 나는 용도 JBOSS 및 최대 절전 모드와 함께 일하고 있습니다. 기본 케이스를 들어,이 구성 속성 페이지에 따라 연결 URI에 zeroDateTimeBehavior = convertToNull를 추가 할 수 있어야합니다.

    나는이 같은 문제를 해결하기 위해 시도를 우연히 발견했다. 나는이에게 다른 방식으로해야 할 일을했을 때문에 설치가 나는 용도 JBOSS 및 최대 절전 모드와 함께 일하고 있습니다. 기본 케이스를 들어,이 구성 속성 페이지에 따라 연결 URI에 zeroDateTimeBehavior = convertToNull를 추가 할 수 있어야합니다.

    나는 당신의 최대 절전 모드 설정에서 해당 매개 변수를 넣어 참조 땅에서 다른 제안을 발견 :

    hibernate.cfg.xml 내에서 :

    <property name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
    

    hibernate.properties에서 :

    hibernate.connection.zeroDateTimeBehavior=convertToNull
    

    하지만 같은 JBOSS 내 MySQL의-ds.xml 파일에 넣어했다 :

    <connection-property name="zeroDateTimeBehavior">convertToNull</connection-property>
    

    이 사람을 도움이되기를 바랍니다. :)

  2. ==============================

    2.대체 대답, 당신은 당신의 데이터 소스 구성에서 직접이 JDBC URL을 사용할 수 있습니다 :

    대체 대답, 당신은 당신의 데이터 소스 구성에서 직접이 JDBC URL을 사용할 수 있습니다 :

    jdbc:mysql://yourserver:3306/yourdatabase?zeroDateTimeBehavior=convertToNull
    

    편집하다:

    업데이트 : 알렉산더는 MySQL의 커넥터-5.1.15이 기능에 영향을 미치는 버그를보고했다. 공식 웹 사이트에 변경 기록을 참조하십시오.

  3. ==============================

    3.그게 내게는 당신의 "해결 방법"코드로 데이터베이스에서 값을 얻을 수있는 유일한 방법은 해결 방법이 아니라 사실이라고 생각합니다 :

    그게 내게는 당신의 "해결 방법"코드로 데이터베이스에서 값을 얻을 수있는 유일한 방법은 해결 방법이 아니라 사실이라고 생각합니다 :

    SELECT CAST(add_date AS CHAR) as add_date
    

    그런데, MySQL의 문서에서 좀 더주의 사항 :

    잘못된 데이터에 MySQL의 제약 :

    MySQL의 5.x의 날짜 및 시간 유형 :

  4. ==============================

    4.

    DATE_FORMAT(column name, '%Y-%m-%d %T') as dtime
    

    오류를 방지하기 위해 사용합니다. 그것은 문자열 형식의 날짜를 반환 한 다음 문자열로 얻을 수 있습니다.

    resultset.getString("dtime");
    

    이것은 실제로 작동하지 않습니다. 심지어에는 getString를 호출하지만. 내부적으로 MySQL은 여전히 ​​첫 번째 날짜로 변환하려고합니다.

  5. ==============================

    5.라인을 추가 한 후, 경우 :

    라인을 추가 한 후, 경우 :

    <property
    name="hibernate.connection.zeroDateTimeBehavior">convertToNull</property>
    
    hibernate.connection.zeroDateTimeBehavior=convertToNull
    
    <connection-property
    name="zeroDateTimeBehavior">convertToNull</connection-property>
    

    오류가 계속 :

    Illegal DATETIME, DATE, or TIMESTAMP values are converted to the “zero” value of the appropriate type ('0000-00-00 00:00:00' or '0000-00-00').
    

    라인을 찾을 수 :

    1) resultSet.getTime("time"); // time = 00:00:00
    2) resultSet.getTimestamp("timestamp"); // timestamp = 00000000000000
    3) resultSet.getDate("date"); // date = 0000-00-00 00:00:00
    

    각각 다음 줄로 교체 :

    1) Time.valueOf(resultSet.getString("time"));
    2) Timestamp.valueOf(resultSet.getString("timestamp"));
    3) Date.valueOf(resultSet.getString("date"));
    
  6. ==============================

    6.나는이 문제와 씨름하고 'convertToNull'솔루션은 위에서 설명한 구현했습니다. 그것은 내 로컬 MySQL의 인스턴스에서 일했다. 내가 Heroku가 내 재생 / 스칼라 응용 프로그램을 배포 할 때 더 이상 작동하지 않을 것입니다. Heroku가 또한 인해에게 Heroku의 사용 연결, 그들은 사용자를 제공하는 DB URL,이 솔루션에 여러 인수를 연결합니다 "?" 인수의 자신의 세트 전에 작동하지 않습니다. 그러나 나는 똑같이 잘 작동하는 것 같다 다른 해결책을 발견했다.

    나는이 문제와 씨름하고 'convertToNull'솔루션은 위에서 설명한 구현했습니다. 그것은 내 로컬 MySQL의 인스턴스에서 일했다. 내가 Heroku가 내 재생 / 스칼라 응용 프로그램을 배포 할 때 더 이상 작동하지 않을 것입니다. Heroku가 또한 인해에게 Heroku의 사용 연결, 그들은 사용자를 제공하는 DB URL,이 솔루션에 여러 인수를 연결합니다 "?" 인수의 자신의 세트 전에 작동하지 않습니다. 그러나 나는 똑같이 잘 작동하는 것 같다 다른 해결책을 발견했다.

    SET sql_mode = 'NO_ZERO_DATE';

    내 테이블 설명에 넣고 그것이 '0000-00-00 0시 0분 0초'의 문제를 해결을 java.sql.Timestamp로 표현 될 수 없다

  7. ==============================

    7.난 당신이 널 (null) 값을 나타내는 널 (null)을 사용하는 것이 좋습니다.

    난 당신이 널 (null) 값을 나타내는 널 (null)을 사용하는 것이 좋습니다.

    당신이 얻을 예외가 무엇입니까?

    BTW :

    0 또는 0000이라고 아무 해가 없습니다 (일부 날짜는 올해 수 있지만)

    그리고 올해에는 0개월 또는 월 0 일이 없습니다. (어느 것이 문제의 원인 일 수 있습니다)

  8. ==============================

    8.나는 '00 -00를 ​​considerating 문제를 해결 -.... '다음 유효한 날짜 아니라, 내가 허가 널 (null) 값으로 "NULL"expresion을 추가 내 SQL 열 정의를 변경 :

    나는 '00 -00를 ​​considerating 문제를 해결 -.... '다음 유효한 날짜 아니라, 내가 허가 널 (null) 값으로 "NULL"expresion을 추가 내 SQL 열 정의를 변경 :

    SELECT "-- Tabla item_pedido";
    CREATE TABLE item_pedido (
        id INTEGER AUTO_INCREMENT PRIMARY KEY,
        id_pedido INTEGER,
        id_item_carta INTEGER,
        observacion VARCHAR(64),
        fecha_estimada TIMESTAMP,
        fecha_entrega TIMESTAMP NULL, // HERE IS!!.. NULL = DELIVERY DATE NOT SET YET
        CONSTRAINT fk_item_pedido_id_pedido FOREIGN KEY (id_pedido)
            REFERENCES pedido(id),...
    

    그럼, 수단 "나는 아직 타임 스탬프를 등록 didnt한다"고, NULL 값을 삽입 할 수 있도록했습니다 ...

    SELECT "++ INSERT item_pedido";
    INSERT INTO item_pedido VALUES
    (01, 01, 01, 'Ninguna', ADDDATE(@HOY, INTERVAL 5 MINUTE), NULL),
    (02, 01, 02, 'Ninguna', ADDDATE(@HOY, INTERVAL 3 MINUTE), NULL),...
    

    테이블 모양이 :

    mysql> select * from item_pedido;
    +----+-----------+---------------+-------------+---------------------+---------------------+
    | id | id_pedido | id_item_carta | observacion | fecha_estimada      | fecha_entrega       |
    +----+-----------+---------------+-------------+---------------------+---------------------+
    |  1 |         1 |             1 | Ninguna     | 2013-05-19 15:09:48 | NULL                |
    |  2 |         1 |             2 | Ninguna     | 2013-05-19 15:07:48 | NULL                |
    |  3 |         1 |             3 | Ninguna     | 2013-05-19 15:24:48 | NULL                |
    |  4 |         1 |             6 | Ninguna     | 2013-05-19 15:06:48 | NULL                |
    |  5 |         2 |             4 | Suave       | 2013-05-19 15:07:48 | 2013-05-19 15:09:48 |
    |  6 |         2 |             5 | Seco        | 2013-05-19 15:07:48 | 2013-05-19 15:12:48 |
    |  7 |         3 |             5 | Con Mayo    | 2013-05-19 14:54:48 | NULL                |
    |  8 |         3 |             6 | Bilz        | 2013-05-19 14:57:48 | NULL                |
    +----+-----------+---------------+-------------+---------------------+---------------------+
    8 rows in set (0.00 sec)
    

    마지막으로 : 행동 JPA :

    @Stateless
    @LocalBean
    public class PedidosServices {
        @PersistenceContext(unitName="vagonpubPU")
        private EntityManager em;
    
        private Logger log = Logger.getLogger(PedidosServices.class.getName());
    
        @SuppressWarnings("unchecked")
        public List<ItemPedido> obtenerPedidosRetrasados() {
            log.info("Obteniendo listado de pedidos retrasados");
            Query qry = em.createQuery("SELECT ip FROM ItemPedido ip, Pedido p WHERE" +
                    " ip.fechaEntrega=NULL" +
                    " AND ip.idPedido=p.id" +
                    " AND ip.fechaEstimada < :arg3" +
                    " AND (p.idTipoEstado=:arg0 OR p.idTipoEstado=:arg1 OR p.idTipoEstado=:arg2)");
            qry.setParameter("arg0", Tipo.ESTADO_BOUCHER_ESPERA_PAGO);
            qry.setParameter("arg1", Tipo.ESTADO_BOUCHER_EN_SERVICIO);
            qry.setParameter("arg2", Tipo.ESTADO_BOUCHER_RECIBIDO);
            qry.setParameter("arg3", new Date());
    
            return qry.getResultList();
        }
    

    마지막으로 모든 작업에서. 나는 당신을 도와 바랍니다.

  9. ==============================

    9.다른 답변에 추가하려면 : 당신은 0000-00-00 문자열을 원한다면, 당신은 (시간대 변환을 희생의주의와 함께) toDatetimeString 동기화 = true를 사용할 수 있습니다.

    다른 답변에 추가하려면 : 당신은 0000-00-00 문자열을 원한다면, 당신은 (시간대 변환을 희생의주의와 함께) toDatetimeString 동기화 = true를 사용할 수 있습니다.

    공식 MySQL의 버그 : https://bugs.mysql.com/bug.php?id=47108.

    또한, 역사, JDBC는 0000-00-00 날짜에 대해 NULL을 반환하지만 지금은 기본적으로 예외를 반환하는 데 사용. 출처

  10. ==============================

    10.당신은 JDBC URL을 추가 할 수 있습니다

    당신은 JDBC URL을 추가 할 수 있습니다

    ?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
    

    널 (null) 값이, SQL 변환 '0000-00-00 0시 0분 0초'의 도움으로.

    예를 들면 :

    jdbc:mysql:<host-name>/<db-name>?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
    
  11. from https://stackoverflow.com/questions/782823/handling-datetime-values-0000-00-00-000000-in-jdbc by cc-by-sa and MIT license