﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-crycz-文章分类-Data Base</title><link>http://www.blogjava.net/crycz/category/19523.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 08:26:36 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 08:26:36 GMT</pubDate><ttl>60</ttl><item><title>ibatis存储过程入参集合--转</title><link>http://www.blogjava.net/crycz/articles/355221.html</link><dc:creator>blues</dc:creator><author>blues</author><pubDate>Thu, 28 Jul 2011 05:55:00 GMT</pubDate><guid>http://www.blogjava.net/crycz/articles/355221.html</guid><wfw:comment>http://www.blogjava.net/crycz/comments/355221.html</wfw:comment><comments>http://www.blogjava.net/crycz/articles/355221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crycz/comments/commentRss/355221.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crycz/services/trackbacks/355221.html</trackback:ping><description><![CDATA[<div><pre>原文地址：<div>http://mail-archives.apache.org/mod_mbox/ibatis-user-java/200802.mbox/%3C8B243E70CE6BFB438E3CDE03E1E4F698925024@zil01exm62.ds.mot.com%3E</div><br /><br /><br />After spending a great deal of time in R&amp;D I came up with the following<br />solution for sending IN and OUT Oracle UDT collections (e.g. nested<br />tables or arrays). I'm currently using Oracle 10g. My driver version is<br />10.2.0.2.0 and I had to place the oracle i18n jar (version 10.1.0.2.0.0)<br />in the class path to solve the '???' datum conversion to string problem.<br />I am using AppFuse2 (Spring and iBatis 2.3.0). I had to modify 2.3.0 to<br />allow access to the<br />com.ibatis.sqlmap.engine.type.JdbcTypeRegistry.setType method. (Only<br />required if you want OUT nested table).<br /> <br />There is not much use for using a nested table as out parameter in my<br />code... I would much rather use a REF CURSOR for this purpose. However,<br />for the sake of example and mapping demonstration, I have one i_array IN<br />nested table and one o_array OUT nested table as parameters to my<br />procedure.<br /> <br />I will try to demonstrate how this is done. First we will declare two<br />schema scope (not package) types:<br /> <br />DROP TYPE EMP_SALARY_TAB;<br />DROP TYPE EMP_SALARY_REC;<br /> <br />CREATE OR REPLACE TYPE EMP_SALARY_REC AS OBJECT (<br />   EMP_ID                         NUMBER(5),<br />   EMP_NAME                       VARCHAR2(255),<br />   START_DATE                     DATE,<br />   SALARY                         NUMBER   <br />);<br />/<br /> <br />CREATE OR REPLACE Type EMP_SALARY_TAB AS TABLE OF EMP_SALARY_REC;<br />/<br /> <br />next we will create a small package with one single test procedure<br /> <br />CREATE OR REPLACE PACKAGE EMP_SALARY_PKG IS<br />   PROCEDURE GET_EMP_SALARIES(i_array IN EMP_SALARY_TAB,o_array OUT<br />EMP_SALARY_TAB);<br />End EMP_SALARY_PKG;<br />/<br /> <br />CREATE OR REPLACE PACKAGE BODY EMP_SALARY_PKG AS<br /> <br />   PROCEDURE GET_EMP_SALARIES(i_array IN EMP_SALARY_TAB,o_array OUT<br />EMP_SALARY_TAB)<br />   IS<br />      emp_salary_rec   OM.EMP_SALARY_REC;<br />      num_of_months    NUMBER;<br />      base_salary_usd  NUMBER := 70000;<br />      annual_bonus_pct NUMBER := 3.5;<br />      updated_salary   NUMBER;      <br />   BEGIN<br />      o_array := i_array;<br />      FOR idx IN i_array.first()..i_array.last() LOOP<br />        emp_salary_rec := i_array(idx);<br />        num_of_months := 24;<br />        updated_salary := (((num_of_months / 12) * annual_bonus_pct) /<br />100) + base_salary_usd;<br />        emp_salary_rec.SALARY := updated_salary;<br />        o_array(idx) := emp_salary_rec;<br />      END LOOP;<br />   EXCEPTION<br />      WHEN OTHERS THEN<br />         -- handle errors here...<br />         dbms_output.put_line('Error: '||substr(1,255,sqlerrm));<br /><br />   END GET_EMP_SALARIES;<br /> <br />END EMP_SALARY_PKG;<br />/<br /><br /><br />Now we are ready to begin writing java. First - out POJO (the model used<br />to transfer data to and from the DB) This is a nasty looking model<br />because it implements ora.sql.ORAData and ORADataFactory. I basically<br />copied most of the implementation from the Oracle JPublish help manual<br />leave aside the standard bean methods used by my framework (AppFuse):<br /> <br />package com.mot.nsa.model.oracle;<br /> <br />import java.sql.Connection;<br />import java.sql.SQLException;<br />import java.util.Date;<br />import oracle.jdbc.OracleTypes;<br />import oracle.jpub.runtime.MutableStruct;<br />import oracle.sql.Datum;<br />import oracle.sql.ORAData;<br />import oracle.sql.ORADataFactory;<br />import oracle.sql.STRUCT;<br />import org.apache.commons.logging.Log;<br />import org.apache.commons.logging.LogFactory;<br />import com.mot.nsa.model.BaseObject;<br /> <br />public class EmpSalary extends BaseObject implements ORAData,<br />ORADataFactory {<br /> <br />    // Class fields<br />    private Integer empId;<br />    private String empName;<br />    private Date startDate;<br />    private Double salary;<br />    // JPublish code<br />    public static final String _SQL_NAME = "OM.EMP_SALARY_REC";<br />    public static final int _SQL_TYPECODE = OracleTypes.STRUCT;<br />    protected MutableStruct _struct;<br />    static int[] _sqlType = { OracleTypes.NUMBER, OracleTypes.CHAR,<br />OracleTypes.DATE, OracleTypes.NUMBER };<br />    static ORADataFactory[] _factory = new ORADataFactory[4];<br />    static final EmpSalary _EmpSalaryFactory = new EmpSalary();<br />    // logger (if you wish)<br />    private final Log log = LogFactory.getLog(EmpSalary.class);<br />    /**<br />     * <br />     */<br />    private static final long serialVersionUID = -7710368639791237838L;<br /> <br />    /* constructor */<br />    protected EmpSalary(boolean init) {<br />        if (init) {<br />            _struct = new MutableStruct(new Object[4], _sqlType,<br />_factory);<br />        }<br />    }<br /> <br />    public EmpSalary() {<br />        this(true);<br />    }<br /> <br />    /* ORAData interface */<br />    public Datum toDatum(Connection conn) throws SQLException {<br />        log.info("Calling method toDatum...");<br />        Datum d = _struct.toDatum(conn, _SQL_NAME);<br />        return d;<br />    }<br /> <br />    /* ORADataFactory interface */<br />    public ORAData create(Datum d, int sqlType) throws SQLException {<br />        return create(null, d, sqlType);<br />    }<br /> <br />    protected ORAData create(EmpSalary o, Datum d, int sqlType) throws<br />SQLException {<br />        log.info("Calling method create...");<br />        if (d == null) {<br />            return null;<br />        }<br />        if (o == null) {<br />            o = new EmpSalary(false);<br />        }<br />        o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory);<br />        return o;<br />    }<br /> <br />    public static ORADataFactory getORADataFactory() {<br />        return _EmpSalaryFactory;<br />    }<br /> <br />    // Getters<br />    public Integer getEmpId() throws SQLException {<br />        return (Integer) _struct.getAttribute(0);<br />    }<br /> <br />    public String getEmpName() throws SQLException {<br />        return (String) _struct.getAttribute(1);<br />    }<br /> <br />    public Date getStartDate() throws SQLException {<br />        return (Date) _struct.getAttribute(2);<br />    }<br /> <br />    public Double getSalary() throws SQLException {<br />        return (Double) _struct.getAttribute(3);<br />    }<br /> <br />    // Setters<br />    public void setEmpId(Integer empId) throws SQLException {<br />        this.empId = empId;<br />        _struct.setAttribute(0, this.empId);<br />    }<br /> <br />    public void setEmpName(String empName) throws SQLException {<br />        this.empName = empName;<br />        _struct.setAttribute(1, this.empName);<br />    }<br /> <br />    public void setStartDate(Date startDate) throws SQLException {<br />        this.startDate = startDate;<br />        _struct.setAttribute(2, this.startDate);<br />    }<br /> <br />    public void setSalary(Double salary) throws SQLException {<br />        this.salary = salary;<br />        _struct.setAttribute(3, this.salary);<br />    }<br /> <br />    // Just standard hashCode, equals and toString for POJO's<br />    @Override<br />    public int hashCode() {<br />        return hashCode(this);<br />    }<br /> <br />    @Override<br />    public boolean equals(Object obj) {<br />        return equals(this, obj);<br />    }<br /> <br />    @Override<br />    public String toString() {<br />        return toString(this);<br />    }<br />}<br /><br />Next we will write the 'EmpSalaryTypeHandlerCallback' which handles this<br />type:<br /> <br />import java.sql.Connection;<br />import java.sql.ResultSet;<br />import java.sql.SQLException;<br />import java.util.ArrayList;<br />import java.util.Date;<br />import java.util.List;<br />import oracle.jdbc.OracleTypes;<br />import oracle.jdbc.driver.OracleConnection;<br />import oracle.sql.ARRAY;<br />import oracle.sql.ArrayDescriptor;<br />import oracle.sql.STRUCT;<br />import org.apache.commons.dbcp.DelegatingConnection;<br />import org.apache.commons.logging.Log;<br />import org.apache.commons.logging.LogFactory;<br />import com.ibatis.sqlmap.client.extensions.ParameterSetter;<br />import com.ibatis.sqlmap.client.extensions.ResultGetter;<br />import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;<br />import com.ibatis.sqlmap.engine.type.JdbcTypeRegistry;<br />import com.my.model.oracle.EmpSalary;<br /> <br />public class EmpSalaryTypeHandlerCallback implements TypeHandlerCallback<br />{<br /> <br />    private final Log log =<br />LogFactory.getLog(EmpSalaryTypeHandlerCallback.class);<br />    private static final String SCHEMA = "OM";<br />    private static final String EMP_SALARY_TAB = SCHEMA + "." +<br />"EMP_SALARY_TAB";<br />    private static final String EMP_SALARY_REC = SCHEMA + "." +<br />"EMP_SALARY_REC";<br />    /**<br />     * If we need an OUT parameter of type OM.EMP_SALARY_TAB (e.g. our<br />     * implementation of getResult will be called) we will need to<br />modify iBatis<br />     * framework (v2.3.0) to allow access to JdbcTypeRegistry.setType<br />(currently<br />     * private -&gt; should be public).<br />     * <br />     * If we only need to sen in a OM.EMP_SALARY_TAB - we do not need to<br />modify<br />     * anything and the next static block is not required.<br />     */<br />    static {<br />        JdbcTypeRegistry.setType(EMP_SALARY_REC, OracleTypes.STRUCT);<br />        JdbcTypeRegistry.setType(EMP_SALARY_TAB, OracleTypes.ARRAY);<br />    };<br /> <br />    @SuppressWarnings("unchecked")<br />    public void setParameter(ParameterSetter setter, Object parameter)<br />throws SQLException {<br />        log.info("calling setParameter...");<br />        try {<br />            List&lt;EmpSalary&gt; empSalaries = (List&lt;EmpSalary&gt;) parameter;<br />            // log.info("Converting list to array...");<br />            EmpSalary[] recArray = new EmpSalary[empSalaries.size()];<br />            for (int i = 0; i &lt; recArray.length; i++) {<br />                recArray[i] = empSalaries.get(i);<br />            }<br />            log.info("Converted list to array.");<br />            setter.getPreparedStatement().getConnection();<br />            Connection conn =<br />setter.getPreparedStatement().getConnection();<br />            if (conn instanceof DelegatingConnection) {<br />                DelegatingConnection dcon = (DelegatingConnection) conn;<br />                conn = dcon.getInnermostDelegate();<br />            }<br />            conn = (OracleConnection) conn;<br />            ArrayDescriptor arrayDescriptor =<br />ArrayDescriptor.createDescriptor(EMP_SALARY_TAB, conn);<br />            ARRAY array = new ARRAY(arrayDescriptor, conn, recArray);<br />            setter.setArray(array);<br />        } catch (SQLException sqle) {<br />            log.info("SQLException: " + sqle, sqle);<br />            throw sqle;<br />        }<br />    }<br /> <br />    public Object getResult(ResultGetter getter) throws SQLException {<br />        ARRAY array = (oracle.sql.ARRAY) getter.getArray();<br />        ResultSet rs = array.getResultSet();<br />        List&lt;EmpSalary&gt; empSalaries = new ArrayList&lt;EmpSalary&gt;();<br />        while (rs != null &amp;&amp; rs.next()) {<br />            STRUCT struct = (STRUCT) rs.getObject(2);<br />            Object[] attribs = struct.getAttributes();<br />            EmpSalary empSalary = new EmpSalary();<br />            empSalary.setEmpId(((java.math.BigDecimal)<br />attribs[0]).intValue());<br />            empSalary.setEmpName((String) attribs[1]);<br />            empSalary.setStartDate((Date) attribs[2]);<br />            empSalary.setSalary(((java.math.BigDecimal)<br />attribs[3]).doubleValue());<br />            empSalaries.add(empSalary);<br />        }<br />        return empSalaries;<br />    }<br /> <br />    /**<br />     * Nothing here can help us anyway...<br />     */<br />    public Object valueOf(String arg0) {<br />        if (arg0 == null) {<br />            return new ArrayList&lt;EmpSalary&gt;();<br />        }<br />        return arg0;<br />    }<br />}<br /> <br />Notice: if you want to pass a collection as an OUT parameter - you will<br />have to modify iBatis 2.3.0 so you can do this:<br />JdbcTypeRegistry.setType("MYTYPE",OracleTypes.SomeType). Now we can<br />start iBatis mapping:<br /> <br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE sqlMap      <br />    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      <br />    "http://ibatis.apache.org/dtd/sql-map-2.dtd"&gt;<br />&lt;sqlMap namespace="DBTestSQL"&gt;<br />    <br />    &lt;typeAlias alias="empSalaryTypeHandler"<br />type="com.my.company.dao.ibatis.utils.EmpSalaryTypeHandlerCallback" /&gt;<br />    &lt;typeAlias alias="empSalary" type="com.my.model.oracle.EmpSalary" /&gt;<br />    <br />    &lt;resultMap id="empSalaryResult" class="empSalary"&gt;<br />       &lt;result property="empId" jdbcType="NUMERIC"<br />javaType="java.lang.Integer" column="EMP_ID"/&gt;<br />       &lt;result property="empName" jdbcType="VARCHAR"<br />javaType="java.lang.String" column="EMP_NAME"/&gt;<br />       &lt;result property="startDate" jdbcType="TIMESTAMP"<br />javaType="java.util.Date" column="START_DATE"/&gt;<br />       &lt;result property="salary" jdbcType="NUMERIC"<br />javaType="java.lang.Double" column="SALARY"/&gt;<br />    &lt;/resultMap&gt;<br />        <br />    &lt;parameterMap id="empSalaryParams" class="java.util.Map"&gt;<br />        &lt;parameter property="iArray"  typeHandler="empSalaryTypeHandler"<br />mode="IN" /&gt;<br />        &lt;parameter property="oArray" jdbcType="OM.EMP_SALARY_TAB"<br />typeName="OM.EMP_SALARY_TAB" typeHandler="empSalaryTypeHandler"<br />mode="OUT" resultMap="empSalaryResult" /&gt;<br />    &lt;/parameterMap&gt;<br />    <br />    &lt;procedure id="getEmpSalaries" parameterMap="empSalaryParams"<br />resultMap="empSalaryResult"&gt;<br />        {call OM.EMP_SALARY_PKG.GET_EMP_SALARIES(?,?)}<br />    &lt;/procedure&gt;<br />    <br />&lt;/sqlMap&gt;<br /><br />And finally - you dao implementation should look something like this:<br /> <br />import java.util.HashMap;<br />import java.util.List;<br />import java.util.Map;<br />import com.mot.nsa.dao.EmpSalaryDao;<br />import com.mot.nsa.model.oracle.EmpSalary;<br /> <br />public class EmpSalaryDaoiBatis extends GenericDaoiBatis&lt;EmpSalary,<br />Integer&gt; implements EmpSalaryDao {<br /> <br />    public EmpSalaryDaoiBatis() {<br />        super(EmpSalary.class);<br />    }<br /> <br />    @SuppressWarnings("unchecked")<br />    public List&lt;EmpSalary&gt; getEmpSalaries(List&lt;EmpSalary&gt; empList) {<br />        Map&lt;String, Object&gt; params = new HashMap&lt;String, Object&gt;();<br />        params.put("oArray", empList);<br />        params.put("iArray", empList);<br />        getSqlMapClientTemplate().queryForObject("getEmpSalaries",<br />params);<br />        log.info("Params: " + params);<br />        return (List&lt;EmpSalary&gt;) params.get("oArray");<br />    }<br />}<br /></pre></div><img src ="http://www.blogjava.net/crycz/aggbug/355221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crycz/" target="_blank">blues</a> 2011-07-28 13:55 <a href="http://www.blogjava.net/crycz/articles/355221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mysql和oracle分组统计查询</title><link>http://www.blogjava.net/crycz/articles/307494.html</link><dc:creator>blues</dc:creator><author>blues</author><pubDate>Mon, 28 Dec 2009 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/crycz/articles/307494.html</guid><wfw:comment>http://www.blogjava.net/crycz/comments/307494.html</wfw:comment><comments>http://www.blogjava.net/crycz/articles/307494.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crycz/comments/commentRss/307494.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crycz/services/trackbacks/307494.html</trackback:ping><description><![CDATA[mysql: <br />
select m.name, date_format(p.promiseddate,'%Y-%m-%d'), sum(p.countes), sum(p.amount)<br />
from pu_po_list p left join m_materiel m<br />
on p.materiel_id=m.id<br />
where p.org_id=(select u.org_id from s_user u where u.value='ycz')<br />
and m.name in ('产品0','产品2')<br />
group by&nbsp; m.name, p.promiseddate with rollup;<br />
<br />
Orcale: <br />
select m.name, sum(p.countes), sum(p.amount) from pu_po_list p left join m_materiel m<br />
on p.materiel_id=m.id<br />
where<br />
p.org_id=(select u.org_id from s_user u where u.value='ycz')<br />
--and m.name like '%000%'<br />
--and p.promiseddate &gt; to_date('2007-08-31','yyyy-MM-dd')<br />
--and p.promiseddate &lt; to_date('2007-10-1','yyyy-MM-dd')<br />
group by rollup (m.name);
<img src ="http://www.blogjava.net/crycz/aggbug/307494.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crycz/" target="_blank">blues</a> 2009-12-28 11:23 <a href="http://www.blogjava.net/crycz/articles/307494.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>