27.10.2015

PL/SQL: MODEL (пример)

У движка отчетов JasperReports есть особенность: область детализации строго горизонтальна и занимает всю ширину страницы. Если нужно напечатать несколько маленьких бланков, которые умещаются по 2 штуки в ряд, то придется печатать всё-таки по одному.

Выход - подать на вход выборку, уже разбитую на 2 колонки.

Для простейших случаев наподобие представленного можно использовать MODEL - мощную инструкцию PL/SQL, позволяющую с выборкой производить операции с нетривиальной логикой. Применяется крайне редко в особо тяжелых случаях.
select * from (select id1, name1, lead(id2, 1) over(order by null) id2, lead(name2, 1) over(order by null) name2 from (select id1, name1, id2, name2 from (select 1 r, 10 id, 'a' name from dual union select 2 r, 15 id, 'b' name from dual union select 3 r, 20 id, 'c' name from dual union select 4 r, 25 id, 'd' name from dual union select 5 r, 30 id, 'e' name from dual) model dimension by(r, id, name) measures(0 id1, cast(null as varchar2(255)) name1, 0 id2, cast(null as varchar2(255)) name2) rules(id1 [ mod(r, 2) != 0, id, name ] = cv(id), id2 [ mod(r, 2) = 0, id, name ] = cv(id), name1 [ mod(r, 2) != 0, id, name ] = cv(name), name2 [ mod(r, 2) = 0, id, name ] = cv(name)))) where id1 != 0
В приведенном примере сначала мы разбиваем выборку по колонкам в зависимости от четности/нечетности порядкового номера, затем на уровне выше с помощью функции LEAD склеиваем строки, чтобы убрать шахматный порядок в данных. Наконец, ограничением where id1 != 0 отсекаем пустые строки, образовавшиеся после склейки.





23.10.2015

PL/SQL: Месяцы в родительном падеже

Не хотелось плодить кучу условий и использовать какие-либо кириллические константы, поэтому вот:
  function month_rodp(p_date in date) return varchar2
  is
           mon varchar2(20);
  begin
     mon := trim(lower(to_char(p_date, 'MONTH')));
     if (to_char(p_date, 'MM')) in (3,8) then
        mon := mon || chr(1072 using NCHAR_CS);
     else
        mon := substr(mon, 1,  length(mon)-1) || chr(1103 using NCHAR_CS);
     end if;
     return mon;
  end month_rodp;

28.08.2015

Weblogic: weblogic.jdbc.wrapper.Blob_oracle_sql_BLOB cannot be cast to oracle.sql.BLOB

Ошибка возникает потому, что типы oracle.sql сервер Weblogic обвязывает в свои из weblogic.jdbc.wrapper.
Решение 1 - отключить обвязку на уровне источника данных через консоль, галочку нужно снять:


Решение 2 (и предпочтительное) - выполнить приведение типов в коде.
Код до:
public Connection getServerConnection() {
      System.out.println("DataSource = " + this._ds);
      Connection conn = null;
      try {
  if (this.conn == null){
              conn = this._ds.getConnection();  //меняем эту строку
         }
      } catch (SQLException var4) {
         String msg = "ERROR. Cannot get connection from datasource: " + var4.getMessage();
         System.out.println(msg);
         var4.printStackTrace();
      }
      return conn;
}
Код после:
import oracle.jdbc.OracleConnection;
import weblogic.jdbc.extensions.WLConnection;

public Connection getServerConnection() {
      System.out.println("DataSource = " + this._ds);
      Connection conn = null;
      try {
  if (this.conn == null){
              conn = (((WLConnection) this._ds.getConnection()).getVendorConnection());
         }
      } catch (SQLException var4) {
         String msg = "ERROR. Cannot get connection from datasource: " + var4.getMessage();
         System.out.println(msg);
         var4.printStackTrace();
      }
      return conn;
}
Класс WLConnection можно подключить через com.bea.core.datasource_1.9.0.0.jar

27.08.2015

Парсер SAX

SAX - альтернатива стандартному парсеру DOM, который в силу особенностей реализации (создание в памяти объекта XMLDocument, содержащего целиком весь файл), подходит только для распарсивания маленьких xml-документов.

Фишка парсера в том, что поток InputStream обрабатывается последовательно и к тем или иным событиям применяется пользовательская логика:
             SAXParserFactory factory = SAXParserFactory.newInstance();
             SAXParser parser;
             parser = factory.newSAXParser();
             MySAXParser prsHandler = new MySAXParser();
             parser.parse(is, prsHandler);
, где is - объект класса InputStream, MySAXParser - класс с перекрытыми методами обработки событий
public class MySAXParser extends DefaultHandler{
    private String currentParameterTypes;
    private String currentQName;
 
    @Override
    public void startDocument(){  //событие начала парсинга
        System.out.println("start parse document;");
    }
   
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes){
        // встретили элемент
        this.currentParameterTypes = qName;
    }
   
    @Override
    public void endElement(String uri, String localName, String qName){
        // вышли из элемента
    }
   
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // получает значение тега/атрибута this.currentParameterTypes
        String value = new String(ch, start, length);
    }
}
Ниже - график заполнения heap'a во время распарсивания файда в 150МБ.




11.08.2015

Weblogic: Cannot read from policy store

Cannot read from policy store. Reason is PolicyStore Error, javax.xml.stream.XMLStreamException

Данная ошибка означает, что процесс не может прочитать настройки политик для домена.

При детальном осмотре файловой системы оказалось, что файл %domain%\config\fmwconfig\system-jazn-data.xml в какой-то момент стал пустым (подробнее о структуре файла). Проблема решилась заменой данного файла работоспособным, взятым у коллеги.