プロジェクトの質問--カーソル結果セットを返します.


いくつかの余談:
今ますますデータベースの重要な役割を感じて、プログラムはただこのようにあるいはそのような業務の過程を実現して、データベースの支持がなくて、プログラムはいくら書いても鶏の肋骨で、特に大型のインターネットの応用、データベースは絶対に1つの重要な方面です.需要背景説明:実際のプロジェクトでは、3つのデータベーステーブル、1つの商品情報テーブルproductInfo、1つの商品定価テーブルproductPricing、1つの商品全体定価テーブルprodoctUnityPricingがあります.この3枚の表の構造は以下の通りである(注:説明の便宜上、ここでは多くのフィールドを省略する):表1:商品情報表productInfo
 
PRODUCTID PRODUCTNAME PRODUCTPRICE PRODUCEADDRESS PRODUCTTYPE
GD010010001
LG携帯
1000.00
深センXX電子
10001
GD020020002
キヤノンカメラ
2000.00
福州XX電子
10001
GD030040005
Lenovo ThinkPad
5500.00
中国を連想する
10002
この表には商品に関する情報が格納されています.表2:商品定価表productPricing
ID USERID PRODUCTID PRODUCTTYPE PRODUCPRICING
1
0001
GD010010001
10001
1000.11
2
0002
GD010010001
10001
1577.00
3
0001
GD020020002
10001
2000.22
4
0001
GD030040005
10002
5520.00
この表には商品の価格設定情報が格納されており、商品情報表productInfoの商品が価格を再改訂した後、変更された価格情報が表に格納されます.表3:商品全体定価表prodoctUnityPricing
 
ID USERID PRODUCTTYPE UNITYPRICING
1
0001
10001
1.00
このテーブルには、ある種類の商品の全体価格が格納されており、例えば、商品タイプproductType=10001の商品全体価格を調整し、価格を100元均一に浮上させるという全体価格調整情報がテーブルに格納される.ビジネスニーズの説明:処理する問題は、この3つのテーブルから商品情報を取得することです.明らかに、商品情報を検索するだけで、商品情報テーブルproductInfoから検索すれば十分ですが、ユーザーによって商品の価格が異なります.そのため、以下のような状況が現れた.商品に価格が設定されていない場合(すなわち、商品価格設定テーブルproductPricingは、そのユーザに対応する価格設定記録がない)、商品全体の価格設定もない場合(すなわち、商品全体の価格設定テーブルprodoctUnityPricingは、そのユーザに対応する価格設定記録がない)、商品情報テーブルproductInfoのデータを直接照会する.2.商品に定価があるが、商品全体の定価がない場合、商品情報表productInfo表のデータを調べるが、価格は商品定価表productPricingに対応する価格であり、そのうち一部の商品に定価がある場合、一部の商品に定価がない場合、定価の表示定価価格があり、定価のない表示商品情報表の価格が表示される.3商品に全体の価格があるが、商品に商品の価格がない場合、商品情報表の価格に全体の価格が浮上した金額を加えてから、最終的にユーザーに表示される価格である.4.商品に定価があり、商品にも全体定価がある場合は、定価の価格を優先的に表示する.ビジネス・プロシージャは上記のように、この機能も長い間オンラインになっていますが、オンラインのバージョンではsqlクエリーが使用され、sql文も複雑で、最近はストレージ・プロシージャを使用したバージョンが作成されました.
皆さんに参考にしながら、何か問題があるかどうか見てほしいです.次はプロシージャコードを格納し、packageとpackage bodies構造を使用します.
create or replace package package_productprice is

  -- Author  : hnylj

  type resultList is ref cursor;

  procedure processProductPrice(p_userid      in varchar2,
                                p_productType in varchar2,
                                p_pageIndex   in number,
                                p_pageEnd     in number,
                                productList   out resultList);

end package_productprice;
create or replace package body package_productprice is
  procedure processProductPrice(p_userid      in varchar2,
                                p_productType in varchar2,
                                p_pageIndex   in number,
                                p_pageEnd     in number,
                                productList   out resultList) is
    
    --      (     )
    v_productUnityPrice number(8, 2) := 0.00;
    --         
    v_count number(1) := 0;
  
  begin
    --            
    select count(*)
      into v_count
      from PRODOCTUNITYPRICING a
     where a.userid = p_userid
       and a.producttype = p_productType;
  
    --         
    if v_count = 0 then
      --           
      open productList for
        SELECT *
          FROM (SELECT AA.*, ROWNUM RN
                  FROM (select t.*, p.productPricing
                          from (select a.productid productId,
                                       a.productname productName,
                                       decode(a.productprice,
                                              null,
                                              0.00,
                                              a.productprice) productPrice,
                                       a.producttype productType
                                  from productinfo a
                                 where a.producttype = p_productType) t,
                               (select b.productid productId,
                                       decode(b.PRODUCPRICING,
                                              null,
                                              0.00,
                                              b.PRODUCPRICING) productPricing
                                  from productpricing b
                                 where b.producttype = p_productType
                                   and b.userid = p_userid) p
                         where t.productId = p.productId(+)
                         order by t.productPrice) AA
                 WHERE ROWNUM <= p_pageEnd)
         WHERE RN >= p_pageIndex;
    end if;
    
    --        
    if v_count > 0 then
      --              v_productUnityPrice  
      select decode(a.unitypricing, null, 0, a.unitypricing)
        into v_productUnityPrice
        from PRODOCTUNITYPRICING a
       where a.userid = p_userid
         and a.producttype = p_productType;
      
      --           
      open productList for
        SELECT *
          FROM (SELECT AA.*, ROWNUM RN
                  FROM (select t.*, decode(p.productPricing, null, t.productPrice+v_productUnityPrice, p.productPricing) productPricing
                          from (select a.productid productId,
                                       a.productname productName,
                                       decode(a.productprice,
                                              null,
                                              0.00,
                                              a.productprice) productPrice,
                                       a.producttype productType
                                  from productinfo a
                                 where a.producttype = p_productType) t,
                               (select b.productid productId,
                                       decode(b.PRODUCPRICING,
                                              null,
                                              0.00,
                                              b.PRODUCPRICING) productPricing
                                  from productpricing b
                                 where b.producttype = p_productType
                                   and b.userid = p_userid) p
                         where t.productId = p.productId(+)
                         order by t.productPrice) AA
                 WHERE ROWNUM <= p_pageEnd)
         WHERE RN >= p_pageIndex;
      --      
    end if;
  end processProductPrice;
end package_productprice;

ストアド・プロシージャ・コードは、上述したように、動的カーソルref cursorを使用します.
 
次にjavaがストレージ・プロシージャを呼び出すテスト・コードを示します.
package com.javaeye.hnylj.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.javaeye.hnylj.model.ProductInfo;

/**
 *       
 * 
 * @since Jun 20, 2010
 */
public class ProceduresTest {

	private Connection conn = null;
	private CallableStatement cstmt = null;
	private ResultSet rs = null;
	private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";
	private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521:workdb";
	private static final String USERNAME = "framework";
	private static final String PASSWORD = "framework";
	
	private List<ProductInfo> list;

	/**
	 *      
	 * 
	 * @return Connection
	 */
	public synchronized Connection getConnection() {
		try {
			Class.forName(DRIVER);
			conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
		return conn;
	}

	/**
	 *              
	 * 
	 * @return
	 */
	public List<ProductInfo> queryList() {
		list = new ArrayList<ProductInfo>();
		try {
			if (this.getConnection() != null) {
				conn = this.getConnection();
				cstmt = conn.prepareCall("{call package_productprice.processProductPrice(?,?,?,?,?)}");
				cstmt.setString(1, "0001");
				cstmt.setString(2, "10001");
				cstmt.setInt(3, 1);
				cstmt.setInt(4, 10);
				cstmt.registerOutParameter(5, oracle.jdbc.OracleTypes.CURSOR);
				cstmt.execute();
				rs = (ResultSet)cstmt.getObject(5);

				while (rs.next()) {
					ProductInfo productInfo = new ProductInfo();
					productInfo.setProductId(rs.getString(1));
					productInfo.setProductName(rs.getString(2));
					productInfo.setProductPrice(rs.getDouble(3));
					productInfo.setProductType(rs.getString(4));
					productInfo.setProductPricing(rs.getDouble(5));
					list.add(productInfo);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != rs) {
					rs.close();
				}
				if (null != cstmt) {
					cstmt.close();
				}
				if (null != conn) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	
	/**
	 * main    
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		ProceduresTest test = new ProceduresTest();
		List<ProductInfo> productList = test.queryList();
		for (ProductInfo productInfo : productList) {
			System.out.println(productInfo.getProductId());
			System.out.println(productInfo.getProductName());
			System.out.println(productInfo.getProductPrice());
			System.out.println(productInfo.getProductPricing());
			System.out.println(productInfo.getProductType());
		}
	}
}

また、productId、productName、productPrice、productPricing、productType、および対応するgetterおよびsetterメソッドのみをコードするmodelクラスProductInfoも必要です.