2016-07-21 3 views
0

У меня есть функция PLSQL, запустить функцию в PLSQL возврата курсора есть данные, но я называю эту функцию в задаче ява возврата Resultset falase Помогите Неполадка этоJava вызов процедуры оракул не PLSQL возвращают никаких данных, но в PLSQL данных возвратных

enter code here 

Эта функция PLSQL

FUNCTION get_canh_bao(
     p_toolid  in varchar2) 
     RETURN sys_refcursor IS 

     s   varchar2(4000); 
     ptype  varchar2(1000); 
     pday  varchar2(1000); 
     psql  varchar2(1000); 
     pcreate  varchar2(1000); 
     re   sys_refcursor; 
     pwhere  varchar2(1000); 
    BEGIN 
    -- 
     pwhere := ''; 
     s := 'select b.TYPE_REPORT, b.DAY_NHAPLIEU, a.sql_cmd, a.name_createdate' 
      ||' from cpcdata.tbl_config_nhaplieu a' 
      ||' left join cpcdata.tbl_mainmenu b' 
      ||' on a.tool_id = b.ID ' 
      ||' where b.show_all = 0 and b.flag = 1 and b.ID = :toolid'; 
     execute immediate s INTO ptype, pday, psql, pcreate using p_toolid; 
       -- Tinh ngay canh bao 
       if (INSTR(psql,'where') > 0) then 
        pwhere := ' and '; 
       else 
        pwhere := ' where '; 
       end if; 
       s := psql ||pwhere||pcreate||' between :aDate AND :bDate'; 
       CASE 
        WHEN ptype = 'day' THEN 
         s := psql ||pwhere|| ' to_char('||pcreate||',''dd/mm/yyyy'') = to_char(sysdate - '||pday||',''dd/mm/yyyy'')'; 
         open re for s; 
        WHEN ptype = 'week' THEN 
         open re for s USING TRUNC (sysdate, 'iw'), TRUNC(sysdate, 'iw') + 7 - 1/86400- pday; 
        WHEN ptype = 'month' THEN 
         open re for s USING TRUNC (sysdate, 'mm'), to_date(LAST_DAY(TRUNC (sysdate, 'mm')) + 1 - 1/86400 - pday,'dd/mm/yyyy'); 
        WHEN ptype = 'quy' THEN 
         open re for s USING TRUNC (sysdate, 'Q'), to_date(add_months(trunc(sysdate,'Q'),3)- 1 - pday, 'dd/mm/yyyy'); 
        WHEN ptype = 'year' THEN 
         open re for s USING TRUNC (sysdate , 'YEAR'), to_date(ADD_MONTHS(TRUNC (SYSDATE,'YEAR'),12) - 1 - pday, 'dd/mm/yyyy'); 
        ELSE return null; 
       END CASE; 
     dbms_output.put_line(''||s); 
     RETURN re ; 
     exception when others then 
      declare 
       s_err  varchar2(2000); 
       str   varchar(2000); 
       c_err  sys_refcursor; 
      begin 
       s_err := 'loi khi lay du lieu '|| sqlerrm; 
       str := 'select '||s_err||' from dual'; 
       open c_err for str; 
       return c_err; 
      end; 
    END; 

Это кодовая Java

Class.forName("oracle.jdbc.driver.OracleDriver"); 
    Connection conn = 
     DriverManager.getConnection("jdbc:oracle:thin:@***:**:**", 
            "***", "***"); 
    System.out.println("Connect db success ! "); 
ArrayList arr = new ArrayList(); 
      String sql = "{? = call get_canh_bao(?)}"; 
      CallableStatement cs = conn.prepareCall(sql); 
      cs.registerOutParameter(1, OracleTypes.CURSOR); 
      cs.setString(2, "502"); 
      cs.executeQuery(); 
      ResultSet rs = (ResultSet)cs.getObject(1); 
      System.out.println("------------ResultSet---------------"+rs.next()); 
      while (rs.next()) { 

       System.out.println("a"); 
       String[] str = 
       {"1" }; 
       arr.add(str); 
      } 

    System.out.println("size="+arr.size()); 

Результат при запуске кода в java

+0

Вы заметили, что находитесь в System.out.println, продвигающемся к первой записи, и в цикле while вы берете следующую запись - если она есть. –

ответ

1

Проблема, скорее всего, вызвана одной из преобразований даты, которая использует неявный формат даты.

Oracle не имеет формата даты по умолчанию, формат даты всегда зависит от клиента. У вашего Java-клиента и IDE базы данных могут быть разные значения по умолчанию.

Но не исправить код, изменив настройки клиента. Вместо этого очистите функции даты и удалите все преобразования даты в символ.

В целом, при работе с датами, почти всегда следует избегать TO_DATE и TO_CHAR. Если нужно манипулировать датой, существует почти наверняка функция даты , которая не требует преобразования. Даты всегда должны быть сохранены как даты, поэтому вам не нужно конвертировать туда и обратно из таблицы.

Самая большая проблема, вероятно, это:

pcreate  varchar2(1000); 

Изменение, что на сегодняшний день. Если по какой-то причине a.name_createdate является строкой, то, по крайней мере, сделать преобразование явным.

+0

спасибо, но создайте таблицу типа varchar. Также у меня проблема не в этом. –

+0

В функции процедуры plsql: при возврате данных функции запуска –

0

Вы заселение pcreate (строка) из tbl_config_nhaplieu.name_createdate без указания формата, поэтому (при условии, что это date столбца), возможно, что формат может быть различным в клиентской среде Java, например, если он по умолчанию равен mm/dd/yyyy или dd-mon-yyyy вместо dd/mm/yyyy.

Позже вы сравните его непосредственно к датам:

s := psql || pwhere || pcreate || ' between :aDate and :bDate'; 

но не приводя, таким образом, вы получите запрос, как это:

where 01/02/2016 between :aDate and nDate 

В другом месте вы преобразовать его обратно в дату при условии dd/mm/yyyy формате (который вы не указали, когда вы закодировали его как строку ранее, поэтому нет причин, чтобы он соответствовал этому формату):

s := psql || pwhere || ' to_char(' || pcreate || ',''dd/mm/yyyy'') = to_char(sysdate - ' || pday || ',''dd/mm/yyyy'')'; 

, но это не котируется там тоже, так что вы получите что-то вроде этого:

where to_char(01/02/2016,'dd/mm/yyyy') = to_char(sysdate - 3,'dd/mm/yyyy') 

который подведет.

Тогда это:

to_date(last_day(trunc(sysdate,'mm')) + 1 - 1/86400 - pday, 'dd/mm/yyyy') 

, который не может дать результат, который вы ожидаете. Например:

select to_date(last_day(trunc(sysdate,'mm')) + 1 - 1/86400 - 0, 'dd/mm/yyyy') as test 
from dual; 

, который дает мне 31-JUL-2016 в SQL * Plus и SQL Developer, но 31/07/0016 в PL/SQL Developer, из-за различных nls_date_parameter настроек.

Как сказал Джон, вам нужно очистить всю обработку данных.

Смежные вопросы