Strcuts 开发举例
在JSP页面的form中
<html:form action="/po/poDocument" styleId="poDocumentForm" method="post">
其中styleId="poDocumentForm"
对应Structs-config.xml文件中的
<form-bean name="poDocumentForm" type="com.pccw.po.standard.PoDocumentForm" />
com.pccw.po.standard.PoDocumentForm 就是ActionForm类.
其中action="/po/poDocument" 属性对应的就是Structs-config.xml中的action标签中的 path="/po/poDocument 也就是在浏览器中的输入的值.
对应的是Action类是 com.pccw.po.standard.PoDocumentAction
对应Structs-config.xml中的
<action name="poDocumentForm" type="com.pccw.po.standard.PoDocumentAction" path="/po/poDocument">
<forward name="display_doc_list" path="/elis/po/po_doc_view.jsp" />
<forward name="Add" path="/elis/po/po_doc_frame.jsp" />
<forward name="AddLine" path="/elis/po/req_ship_to.jsp" />
<forward name="ModifyLine" path="/elis/po/req_ship_detail.jsp" />
<forward name="ShowLine" path="/elis/po/po_doc.jsp" />
<forward name="lineList" path="/elis/po/po_doc_detail.jsp" />
</action>
所以在ActionForm可以写一些对应JSP页面上的输入域的验证逻辑,但是主要逻辑写在Action类中
DBA常用sql
--监控索引是否使用 alter index &index_name monitoring usage; alter index &index_name nomonitoring usage; select * from v$object_usage where index_name = &index_name;
--求数据文件的I/O分布 select df.name,phyrds,phywrts,phyblkrd,phyblkwrt,singleblkrds,readtim,writetim from v$filestat fs,v$dbfile df where fs.file#=df.file# order by df.name;
--求某个隐藏参数的值 col ksppinm format a54 col ksppstvl format a54 select ksppinm, ksppstvl from x$ksppi pi, x$ksppcv cv where cv.indx=pi.indx and pi.ksppinm like '_%' escape '' and pi.ksppinm like '%meer%';
--求系统中较大的latch select name,sum(gets),sum(misses),sum(sleeps),sum(wait_time) from v$latch_children group by name having sum(gets) > 50 order by 2;
--求归档日志的切换频率(生产系统可能时间会很长) select start_recid,start_time,end_recid,end_time,minutes from (select test.*, rownum as rn from (select b.recid start_recid,to_char(b.first_time,'yyyy-mm-dd hh24:mi:ss') start_time, a.recid end_recid,to_char(a.first_time,'yyyy-mm-dd hh24:mi:ss') end_time,round(((a.first_time-b.first_time)*24)*60,2) minutes from v$log_history a,v$log_history b where a.recid=b.recid+1 and b.first_time > sysdate - 1 order by a.first_time desc) test) y where y.rn < 30
--求回滚段正在处理的事务 select a.name,b.xacts,c.sid,c.serial#,d.sql_text from v$rollname a,v$rollstat b,v$session c,v$sqltext d,v$transaction e where a.usn=b.usn and b.usn=e.xidusn and c.taddr=e.addr and c.sql_address=d.address and c.sql_hash_value=d.hash_value order by a.name,c.sid,d.piece;
--求出无效的对象 select 'alter procedure '||object_name||' compile;' from dba_objects where status='INVALID' and wner='&' and object_type in ('PACKAGE','PACKAGE BODY'); / select owner,object_name,object_type,status from dba_objects where status='INVALID';
--求process/session的状态 select p.pid,p.spid,s.program,s.sid,s.serial# from v$process p,v$session s where s.paddr=p.addr;
--求当前session的状态 select sn.name,ms.value from v$mystat ms,v$statname sn where ms.statistic#=sn.statistic# and ms.value > 0;
--求表的索引信息 select ui.table_name,ui.index_name from user_indexes ui,user_ind_columns uic where ui.table_name=uic.table_name and ui.index_name=uic.index_name and ui.table_name like '&table_name%' and uic.column_name='&column_name';
--显示表的外键信息 col search_condition format a54 select table_name,constraint_name from user_constraints where constraint_type ='R' and constraint_name in (select constraint_name from user_cons_columns where column_name='&1'); select rpad(child.table_name,25,' ') child_tablename, rpad(cp.column_name,17,' ') referring_column,rpad(parent.table_name,25,' ') parent_tablename, rpad(pc.column_name,15,' ') referred_column,rpad(child.constraint_name,25,' ') constraint_name from user_constraints child,user_constraints parent, user_cons_columns cp,user_cons_columns pc where child.constraint_type = 'R' and child.r_constraint_name = parent.constraint_name and child.constraint_name = cp.constraint_name and parent.constraint_name = pc.constraint_name and cp.position = pc.position and child.table_name ='&table_name' order by child.owner,child.table_name,child.constraint_name,cp.position;
--显示表的分区及子分区(user_tab_subpartitions) col table_name format a16 col partition_name format a16 col high_value format a81 select table_name,partition_name,HIGH_VALUE from user_tab_partitions where table_name='&table_name'
--使用dbms_xplan生成一个执行计划 explain plan set statement_id = '&sql_id' for &sql; select * from table(dbms_xplan.display);
--求某个事务的重做信息(bytes) select s.name,m.value from v$mystat m,v$statname s where m.statistic#=s.statistic# and s.name like '%redo size%';
--求cache中缓存超过其5%的对象 select o.owner,o.object_type,o.object_name,count(b.objd) from v$bh b,dba_objects o where b.objd = o.object_id group by o.owner,o.object_type,o.object_name having count(b.objd) > (select to_number(value)*0.05 from v$parameter where name = 'db_block_buffers');
--求谁阻塞了某个session(10g) select sid, username, event, blocking_session, seconds_in_wait, wait_time from v$session where state in ('WAITING') and wait_class != 'Idle';
--求session的OS进程ID col program format a54 select p.spid "OS Thread", b.name "Name-User", s.program from v$process p, v$session s, v$bgprocess b where p.addr = s.paddr and p.addr = b.paddr UNION ALL select p.spid "OS Thread", s.username "Name-User", s.program from v$process p, v$session s where p.addr = s.paddr and s.username is not null;
--查会话的阻塞 col user_name format a32 select /*+ rule */ lpad(' ',decode(l.xidusn ,0,3,0))||l.oracle_username user_name, o.owner,o.object_name,s.sid,s.serial# from v$locked_object l,dba_objects o,v$session s where l.object_id=o.object_id and l.session_id=s.sid order by o.object_id,xidusn desc ;
select /*+ rule */ s.username, decode(l.type,'tm','table lock', 'tx','row lock', null) lock_level, o.owner,o.object_name,s.sid,s.serial# from v$session s,v$lock l,dba_objects o where l.sid = s.sid and l.id1 = o.object_id(+) and s.username is not null ;
--求等待的事件及会话信息/求会话的等待及会话信息 select se.sid,s.username,se.event,se.total_waits,se.time_waited,se.average_wait from v$session s,v$session_event se where s.username is not null and se.sid=s.sid and s.status='ACTIVE' and se.event not like '%SQL*Net%' order by s.username; select s.sid,s.username,sw.event,sw.wait_time,sw.state,sw.seconds_in_wait from v$session s,v$session_wait sw where s.username is not null and sw.sid=s.sid and sw.event not like '%SQL*Net%' order by s.username; -
-求会话等待的file_id/block_id col event format a24 col p1text format a12 col p2text format a12 col p3text format a12 select sid,event,p1text, p1, p2text, p2, p3text, p3 from v$session_wait where event not like '%SQL%' and event not like '%rdbms%' and event not like '%mon%' order by event; select name,wait_time from v$latch l where exists (select 1 from (select sid,event,p1text, p1, p2text, p2, p3text, p3 from v$session_wait where event not like '%SQL%' and event not like '%rdbms%' and event not like '%mon%' ) x where x.p1= l.latch#);
--求会话等待的对象 col owner format a18 col segment_name format a32 col segment_type format a32 select owner,segment_name,segment_type from dba_extents where file_id = &file_id and &block_id between block_id and block_id + blocks - 1;
--求buffer cache中的块信息 select o.OBJECT_TYPE, substr(o.OBJECT_NAME,1,10) objname , b.objd , b.status, count(b.objd) from v$bh b, dba_objects o where b.objd = o.data_object_id and o.owner = '&1' group by o.object_type, o.object_name,b.objd, b.status ;
--求日志文件的空间使用 select le.leseq current_log_sequence#, 100*cp.cpodr_bno/le.lesiz percentage_full from x$kcccp cp,x$kccle le where le.leseq =cp.cpodr_seq;
--求等待中的对象 select /*+rule */ s.sid, s.username, w.event, o.owner, o.segment_name, o.segment_type, o.partition_name, w.seconds_in_wait seconds, w.state from v$session_wait w, v$session s, dba_extents o where w.event in (select name from v$event_name where parameter1 = 'file#' and parameter2 = 'block#' and name not like 'control%') and o.owner <> 'sys' and w.sid = s.sid and w.p1 = o.file_id and w.p2 >= o.block_id and w.p2 < o.block_id + o.blocks
--求当前事务的重做尺寸 select value from v$mystat, v$statname where v$mystat.statistic# = v$statname.statistic# and v$statname.name = 'redo size';
--唤醒smon去清除临时段 column pid new_value Smon set termout off select p.pid from sys.v_$bgprocess b,sys.v_$process p where b.name = 'SMON' and p.addr = b.paddr / set termout on oradebug wakeup &Smon undefine Smon
--求回退率 select b.value/(a.value + b.value),a.value,b.value from v$sysstat a,v$sysstat b where a.statistic#=4 and b.statistic#=5;
--求DISK READ较多的SQL select st.sql_text from v$sql s,v$sqltext st where s.address=st.address and s.hash_value=st.hash_value and s.disk_reads > 300;
--求DISK SORT严重的SQL select sess.username, sql.sql_text, sort1.blocks from v$session sess, v$sqlarea sql, v$sort_usage sort1 where sess.serial# = sort1.session_num and sort1.sqladdr = sql.address and sort1.sqlhash = sql.hash_value and sort1.blocks > 200;
--求对象的创建代码 column column_name format a36 column sql_text format a99 select dbms_metadata.get_ddl('TABLE','&1') from dual; select dbms_metadata.get_ddl('INDEX','&1') from dual;
--求表的索引 set linesize 131 select a.index_name,a.column_name,b.status, b.index_type from user_ind_columns a,user_indexes b where a.index_name=b.index_name and a.table_name='&1';
求索引中行数较多的 select index_name,blevel,num_rows,CLUSTERING_FACTOR,status from user_indexes where num_rows > 10000 and blevel > 0 select table_name,index_name,blevel,num_rows,CLUSTERING_FACTOR,status from user_indexes where status <> 'VALID'
--求当前会话的SID,SERIAL# select sid, serial# from v$session where audsid = SYS_CONTEXT('USERENV','SESSIONID');
--求表空间的未用空间 col mbytes format 9999.9999 select tablespace_name,sum(bytes)/1024/1024 mbytes from dba_free_space group by tablespace_name;
--求表中定义的触发器 select table_name,index_type,index_name,uniqueness from user_indexes where table_name='&1'; select trigger_name from user_triggers where table_name='&1';
--求未定义索引的表 select table_name from user_tables where table_name not in (select table_name from user_ind_columns);
--执行常用的过程 exec print_sql('select count(*) from tab'); exec show_space2('table_name'); --求free memory select * from v$sgastat where name='free memory'; select a.name,sum(b.value) from v$statname a,v$sesstat b where a.statistic# = b.statistic# group by a.name;
查看一下谁在使用那个可以得回滚段,或者查看一下某个可以得用户在使用回滚段, 找出领回滚段不断增长的事务,再看看如何处理它,是否可以将它commit,再不行 就看看能否kill它,等等,查看当前正在使用的回滚段的用户信息和回滚段信息: set linesize 121 SELECT r.name "ROLLBACK SEGMENT NAME ",l.sid "ORACLE PID",p.spid "SYSTEM PID ",s.username "ORACLE USERNAME" FROM v$lock l, v$process p, v$rollname r, v$session s WHERE l.sid = p.pid(+) AND s.sid=l.sid AND TRUNC(l.id1(+)/65536) = r.usn AND l.type(+) = 'TX' AND l.lmode(+) = 6 ORDER BY r.name;
--查看用户的回滚段的信息 select s.username, rn.name from v$session s, v$transaction t, v$rollstat r, v$rollname rn where s.saddr = t.ses_addr and t.xidusn = r.usn and r.usn = rn.usn
--生成执行计划 explain plan set statement_id='a1' for &1;
--查看执行计划 select lpad(' ',2*(level-1))||operation operation,options,OBJECT_NAME,position from plan_table start with id=0 and statement_id='a1' connect by prior id=parent_id and statement_id='a1'
--查看内存中存的使用 select decode(greatest(class,10),10,decode(class,1,'Data',2,'Sort',4,'Header',to_char(class)),'Rollback') "Class", sum(decode(bitand(flag,1),1,0,1)) "Not Dirty",sum(decode(bitand(flag,1),1,1,0)) "Dirty", sum(dirty_queue) "On Dirty",count(*) "Total" from x$bh group by decode(greatest(class,10),10,decode(class,1,'Data',2,'Sort',4,'Header',to_char(class)),'Rollback');
--查看表空间状态 select tablespace_name,extent_management,segment_space_management from dba_tablespaces; select table_name,freelists,freelist_groups from user_tables;
--查看系统请求情况 SELECT DECODE (name, 'summed dirty write queue length', value)/ DECODE (name, 'write requests', value) "Write Request Length" FROM v$sysstat WHERE name IN ( 'summed dirty queue length', 'write requests') and value>0;
--计算data buffer命中率 select a.value + b.value "logical_reads", c.value "phys_reads", round(100 * ((a.value+b.value)-c.value) / (a.value+b.value)) "BUFFER HIT RATIO" from v$sysstat a, v$sysstat b, v$sysstat c where a.statistic# = 40 and b.statistic# = 41 and c.statistic# = 42; SELECT name, (1-(physical_reads/(db_block_gets+consistent_gets)))*100 H_RATIO FROM v$buffer_pool_statistics;
--查看内存使用情况 select least(max(b.value)/(1024*1024),sum(a.bytes)/(1024*1024)) shared_pool_used, max(b.value)/(1024*1024) shared_pool_size,greatest(max(b.value)/(1024*1024),sum(a.bytes)/(1024*1024))- (sum(a.bytes)/(1024*1024)) shared_pool_avail,((sum(a.bytes)/(1024*1024))/(max(b.value)/(1024*1024)))*100 avail_pool_pct from v$sgastat a, v$parameter b where (a.pool='shared pool' and a.name not in ('free memory')) and b.name='shared_pool_size';
--查看用户使用内存情况 select username, sum(sharable_mem), sum(persistent_mem), sum(runtime_mem) from sys.v_$sqlarea a, dba_users b where a.parsing_user_id = b.user_id group by username;
--查看对象的缓存情况 select OWNER,NAMESPACE,TYPE,NAME,SHARABLE_MEM,LOADS,EXECUTIONS,LOCKS,PINS,KEPT from v$db_object_cache where type not in ('NOT LOADED','NON-EXISTENT','VIEW','TABLE','SEQUENCE') and executions>0 and loads>1 and kept='NO' order by owner,namespace,type,executions desc; select type,count(*) from v$db_object_cache group by type;
--查看库缓存命中率 select namespace,gets, gethitratio*100 gethitratio,pins,pinhitratio*100 pinhitratio,RELOADS,INVALIDATIONS from v$librarycache
--查看某些用户的hash select a.username, count(b.hash_value) total_hash,count(b.hash_value)-count(unique(b.hash_value)) same_hash, (count(unique(b.hash_value))/count(b.hash_value))*100 u_hash_ratio from dba_users a, v$sqlarea b where a.user_id=b.parsing_user_id group by a.username;
--查看字典命中率 select (sum(getmisses)/sum(gets)) ratio from v$rowcache;
--查看undo段的使用情况 SELECT d.segment_name,extents,optsize,shrinks,aveshrink,aveactive,d.status FROM v$rollname n,v$rollstat s,dba_rollback_segs d WHERE d.segment_id=n.usn(+) and d.segment_id=s.usn(+);
--无效的对象 select owner,object_type,object_name from dba_objects where status='INVALID'; select constraint_name,table_name from dba_constraints where status='INVALID';
--求出某个进程,并对它进行跟踪 select s.sid,s.serial# from v$session s,v$process p where s.paddr=p.addr and p.spid=&1; exec dbms_system.SET_SQL_TRACE_IN_SESSION(&1,&2,true); exec dbms_system.SET_SQL_TRACE_IN_SESSION(&1,&2,false);
--求出锁定的对象 select do.object_name,session_id,process,locked_mode from v$locked_object lo, dba_objects do where lo.object_id=do.object_id;
--求当前session的跟踪文件 SELECT p1.value || '/' || p2.value || '_ora_' || p.spid || '.ora' filename FROM v$process p, v$session s, v$parameter p1, v$parameter p2 WHERE p1.name = 'user_dump_dest' AND p2.name = 'instance_name' AND p.addr = s.paddr AND s.audsid = USERENV('SESSIONID') AND p.background is null AND instr(p.program,'CJQ') = 0;
--求对象所在的文件及块号 select segment_name,header_file,header_block from dba_segments where segment_name like '&1';
--求对象发生事务时回退段及块号 select a.segment_name,a.header_file,a.header_block from dba_segments a,dba_rollback_segs b where a.segment_name=b.segment_name and b.segment_id='&1'
--9i的在线重定义表 /*如果在线重定义的表没有主键需要创建主键*/ exec dbms_redefinition.can_redef_table('cybercafe','announcement'); create table anno2 as select * from announcement exec dbms_redefinition.start_redef_table('cybercafe','announcement','anno2'); exec dbms_redefinition.sync_interim_table('cybercafe','announcement','anno2'); exec dbms_redefinition.finish_redef_table('cybercafe','announcement','anno2'); drop table anno2 exec dbms_redefinition.abort_redef_table('cybercafe','announcement','anno2'); --常用的logmnr脚本(cybercafe) exec sys.dbms_logmnr_d.build(dictionary_filename =>'esal',dictionary_location =>'/home/oracle/logmnr'); exec sys.dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_24050.dbf', ptions=>sys.dbms_logmnr.new); exec sys.dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_22912.dbf', ptions=>sys.dbms_logmnr.addfile); exec sys.dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_22913.dbf', ptions=>sys.dbms_logmnr.addfile); exec sys.dbms_logmnr.add_logfile(logfilename=>'/home/oracle/oradata/esal/archive/1_22914.dbf', ptions=>sys.dbms_logmnr.addfile); exec sys.dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/logmnr/esal.ora'); create table logmnr2 as select * from v$logmnr_contents; -
-与权限相关的字典 ALL_COL_PRIVS表示列上的授权,用户和PUBLIC是被授予者 ALL_COL_PRIVS_MADE表示列上的授权,用户是属主和被授予者 ALL_COL_RECD表示列上的授权,用户和PUBLIC是被授予者 ALL_TAB_PRIVS表示对象上的授权,用户是PUBLIC或被授予者或用户是属主 ALL_TAB_PRIVS_MADE表示对象上的权限,用户是属主或授予者 ALL_TAB_PRIVS_RECD表示对象上的权限,用户是PUBLIC或被授予者 DBA_COL_PRIVS数据库列上的所有授权 DBA_ROLE_PRIVS显示已授予用户或其他角色的角色 DBA_SYS_PRIVS已授予用户或角色的系统权限 DBA_TAB_PRIVS数据库对象上的所有权限 ROLE_ROLE_PRIVS显示已授予用户的角色 ROLE_SYS_PRIVS显示通过角色授予用户的系统权限 ROLE_TAB_PRIVS显示通过角色授予用户的对象权限 SESSION_PRIVS显示用户现在可利用的所有系统权限 USER_COL_PRIVS显示列上的权限,用户是属主、授予者或被授予者 USER_COL_PRIVS_MADE显示列上已授予的权限,用户是属主或授予者 USER_COL_PRIVS_RECD显示列上已授予的权限,用户是属主或被授予者 USER_ROLE_PRIVS显示已授予给用户的所有角色 USER_SYS_PRIVS显示已授予给用户的所有系统权限 USER_TAB_PRIVS显示已授予给用户的所有对象权限 USER_TAB_PRIVS_MADE显示已授予给其他用户的对象权限,用户是属主 USER_TAB_PRIVS_RECD显示已授予给其他用户的对象权限,用户是被授予者 --如何用dbms_stats分析表及模式? exec dbms_stats.gather_schema_stats(ownname=>'&USER_NAME',estimate_percent=>dbms_stats.auto_sample_size, method_opt => 'for all columns size auto',degree=> DBMS_STATS.DEFAULT_DEGREE); exec dbms_stats.gather_schema_stats(ownname=>'&USER_NAME',estimate_percent=>dbms_stats.auto_sample_size,cascade=>true); /* FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause] FOR COLUMNS [size clause] column|attribute [size_clause] [,column|attribute [size_clause]...], where size_clause is defined as size_clause := SIZE {integer | REPEAT | AUTO | SKEWONLY} integer--Number of histogram buckets. Must be in the range [1,254]. REPEAT--Collects histograms only on the columns that already have histograms. AUTO--Oracle determines the columns to collect histograms based on data distribution and the workload of the columns. SKEWONLY--Oracle determines the columns to collect histograms based on the data distribution of the columns */
错误修改删除数据后的恢复方法
具体方法如下 >>
1. 我们可以使用
SELECT item_cost FROM cst_item_costs
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' hour)
WHERE organization_id = 1
AND yyyymm = 200712
AND item_number = '6384BLCCSL';
来查看1个小时前的数据.
* 这里需要说明几点:
a. AS OF TIMESTAMP expr 是SELECT语句中的FLASHBACK子句
b. SYSTIMESTAMP 是系统提供的时间函数,精确度可以达到微秒级,并提供当前时区
eg. select SYSTIMESTAMP from dual;
SYSTIMESTAMP
---------------------------------------------------------------------------
29-DEC-07 11.16.08.112686 AM +09:00
c. INTERVAL 的作用是用来指定时间区间,下面是它参与运算的法则
Operand1 Operator Operand2 Result Type
-------------------------------------------------------
Datetime - Interval Datetime
我们可以通过修改时间单位和数量来改变倒退时间
eg. TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' day) --查询一天前的数据
TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' minute ) --查询十分钟前的数据
TIMESTAMP (SYSTIMESTAMP - INTERVAL '50' second ) --查询50秒前的数据
d. 关于在FlashBack中的可回朔时间
Oracle中有两个参数能够决定可回朔时间 >>
undo 表空间大小 和 undo_retention 初始化参数.
一般的ERP正式系统里面的 undo tablespace 为 20G左右, undo_retention设置为 3600S.
业务繁忙时间最大可回朔时间约为 2-3h,非业务时间为4-5h,这里需要注意: 最大可回朔时间是由
undo表空间大小及数据库数据变更的频繁程度来决定的.
如果超过最大可回朔时间时,系统会给出有名的 ORA-01555 快照太老(Snapshot too old)错误.
e. 做FlashBack必须要有 FlashBack Any Table 的系统权限.
2. 那么依此类推,我们就可以利用FlashBack来恢复某段时间前的数据了
UPDATE cst_item_costs SET item_cost =
(SELECT item_cost FROM cst_item_costs
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' hour)
WHERE organization_id = 1
AND yyyymm = 200712
AND item_number = '6384BLCCSL)
WHERE organization_id = 1
AND yyyymm = 200712
AND item_number = '6384BLCCSL';
* 这里也要说明几点:
a. 在恢复数据前,要检查WHERE条件是否具有唯一性
b. 如果要成批恢复或全表恢复数据的话,要检查是否在指定的时间区间内还有其他会话写入的数据
Mozilla Firefox浏览器登陆Oracle EBS 11i 方法
1.找到Oracle EBS 11i (Oracle电子商务套件)客户端插件的按装目录。我的目录为:“C:Program FilesOracleJInitiator 1.3.1.21bin”
2.在bin目录下找到“NPJinit13121.dll”文件COPY到Mozilla Firefox浏览器安装目录的“plugins”文件夹下。
在FORM如何直接答应报表
1.报表直接写成Html格式.
2.然后在系统Web PL/SQL里面注册程序.
3.在form的按钮里面添加如下代码.
v_command := fnd_profile.VALUE ('APPS_WEB_AGENT');
v_command := v_command || '/CPOORDIMP_PRN_PKG.POIMP_PRN?p_IMPORT_REQUEST_ID=' || :QPO_HEADER.IMPORT_REQUEST_ID;
OAF 如何发布你的个性化文件
如何发布你的OAF的个性化文件,实际上Oracle提供了两个比较有用的工具:XMLExporter和XMLImporter,但是导入的时候的个性化的路径很难找到.下面是我自己发现的一个方法.举例:
1.我把helloword的页面个性化了,个性化在组织层,把标签的prompt改成了cehshi
2. SELECT * FROM jdr_paths
WHERE path_name LIKE '%HelloWorldPG%'
3.SELECT jdr_mds_internal.getDocumentName(44515)
FROM dual
44515是上面SQL的返回结果,当然上面的SQL会返回多个果,但是根据你的个性话,根据实际就可以得到比较准确的路径.
实际上个性化存放的目录是有一定规则的.一般如果你能找到原文件的化,你的个性化的存放目录就很容易找到:规则如下:
+ <component>
+ webui
file1.xml
+ customizations
+ <layer type>
+ <layer value>
file2.xml
file1就是原文件,file2就是个性话文件.中间还有layer type 和value这两个目录的规则如下:
Level | Level Value |
---|---|
Function | Function Code |
Site | 0 |
Organization | Organization ID |
Responsibility | Responsibility ID |
User | User ID |
结合我的例子就可以知道这个目录结构,我是在org层作的个性化.
org/82
4.telnet 然后cd到 $JAVA_TOP
5.java oracle.jrad.tools.xml.exporter.XMLExporter /oracle/apps/fnd/framework/toolbox/tutorial/webui/customizations/org/82/HelloWorldPG -rootdir $JAVA_TOP/cmcc -username apps -password js818super -dbconnection "(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(Host=10.32.153.44)(PORT = 11501))(CONNECT_DATA = (SID = JSSIT)))"
注意上面的语句不要有回车.
6.下面是我导出来的XML的文件:
<?xml version = '1.0' encoding = 'UTF-8'?>
<customization xmlns="http://xmlns.oracle.com/jrad" version="9.0.5.4.89_555" xml:lang="en-US" customizes="/oracle/apps/fnd/framework/toolbox/tutorial/webui/HelloWorldPG" package="/oracle/apps/fnd/framework/toolbox/tutorial/webui/customizations/org/82">
<modifications>
<modify element="HelloName" prompt="cehshi"/>
</modifications>
</customization>
这一看上面的prompt的值,就是我改的.
7.然后就是import这个就不在说了,过程和export一样.
多说一下,OAF的多语言的个性化是要在layer value层再多建一个语言目录下面语句.
1.到处原来的XML:
java oracle.jrad.tools.xml.exporter.XMLExporter /oracle/apps/ fnd/wf/worklist/webui/customizations/site/0/ AdvancWorklistRG -rootdir $APPL_TOP/admin/patch -username APPSNAME -password APPSPWD -dbconnection "(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp) (HOST=yourhost)(PORT=yourport))(CONNECT_DATA= (SID=yoursid)))"
2.生成US语言的版本,这一步是必须的,所以的翻译都需要用US版做基础.这个就放在了US文件夹下面了.
java oracle.jrad.tools.trans.extractor.XLIFFExtractor $APPL_TOP/admin/patch/oracle/apps/fnd/wf/worklist/ webui/customizations/site/0/AdvancWorklistRG.xml mmd_dir=$OA_HTML/jrad root=$APPL_TOP/admin/patch xliff_dir=$APPL_TOP/admin/patch/oracle/apps/fnd/wf/ worklist/webui/customizations/site/0/US/
3.然后把US文件夹下面的.xlf 文件拷贝到你的需要翻译的目录如:ZHS
cp $APPL_TOP/admin/patch/oracle/apps/fnd/wf/worklist/ webui/customizations/site/0/US/AdvancWorklistRG.xlf $APPL_TOP/ admin/patch/oracle/apps/fnd/wf/worklist/webui/ customizations/site/0/ZHS/AdvancWorklistRG.xlf
4.修改这个xlf文件. 要修改:
target-language="en-US"和 <target>Payment Terms</target>
直接的,直接改成中文的名称
<?xml version = '1.0' encoding = 'UTF-8'?>
<xliff version="1.0">
<file datatype="jdr" original="PayTermsLOVRN" product-version="$Header: PayTermsLOVRN.xlf 115.1 2003/02/26 19:58:26 jfrost noship $" source-language= "en-US" target-language="en-US" product-name="qp">
<body>
<trans-unit id=".oracle.apps.qp.lov.webui. PayTermsLOVRN..PTName...prompt" translate="yes" maxbytes="4000" maxwidth="26" size-unit="char">
<source>Payment Terms</source>
<target>Payment Terms</target>
<prop-group name="ora_untranslatable">
<prop prop-type="tagName">messageStyledText </prop>
<prop prop-type="attributeName">prompt</prop>
</prop-group>
</trans-unit>
<trans-unit id=".oracle.apps.qp.lov.webui. PayTermsLOVRN..TermId...prompt" translate="yes" maxbytes="4000" maxwidth="14" size-unit="char">
<source>Term Id</source>
<target>Term Id</target>
<prop-group name="ora_untranslatable">
<prop prop-type="tagName">formValue</prop>
<prop prop-type="attributeName">prompt</prop>
</prop-group>
</trans-unit>
</body>
</file>
</xliff>
OAF 和 Forms的几点比较
近期几天研究了一下OAF的开发,这个是oracle宣称的新技术,但是实在是觉得不怎么样,所以总结一个OAF不如Forms的地方.
1.开发语言
OAF众所周知是用Java来开发的,不可否认Java在语言方面具有很大的先进性,可以说是到目前为止最为流行的一种语言.而form则是采用PL/SQL.单独从语言的先进性来看Pl/SQL肯定不如Java.但是我们不要忘了,我们用OAF来做开发什么东西.是Oracle ERP的二次开发,也就是在Oracle ERP的基础上用oracle database作为数据进行企业管理的软件开发.就是这个基础决定了,我们必须要用到PL/SQL.很难想象你能用OAF做oracle ERP开发而完全不用PL/SQL.这样只能说明要么你是天才,要么你是蠢蛋. 这样就导致了OAF开发需要会两种语言Java和PL/SQL,这就大大的增加了开发人员的要求,当然也要提高企业的开发成本.
2.发布的方法
我觉得这个不用多讲,AOF开发的页面发布繁杂的很,首先要对应好目录,然后把杂七杂八的Class上传到服务器上,还有把导入XML,对应的JAVA类的路径,总之是两字来概括:杂乱.而form没有这个问题,就是一个fmb文件,在服务器上编译以后成为一个fmx.比较简单方便.
3.界面
首先说说form的界面吧.总的来说form给人的第一印象就是一个字:丑.注意我这里说的是第一印象,第一印象以后呢,反而会觉得还可以,属于耐看型的.其实我们说的界面的好差并不是指界面的美丑,这里还包含了很大一个因素:人性化.也就是用起来方不方便.oracle的forms我觉得因为它技术构架决定了,肯定比网页方式在界面来的人性化.这里涉及C/S比较B/S构架的最大的一个优点,开发人员都了解,我就不多少说.所以我觉得软件是一种工具就像剑客手里的剑,它是辅助人类完成工作的,就好像剑是用来击倒对手的,一把镶满了宝石的剑不一定是剑客觉得最好用的剑.
OAF的界面,呵呵这个界面有点搞笑,继承了oralce软件的一贯传统,还是很那个字:丑.但是oracle好像对他们的界面还是相当的自信,不建议用户在开发中使用自己编写HTML,和Javascript.上述这两项是我们改善B/S结构界面的比较主要途径.至于实用性,我真的很难想象他比Forms界面提高了多少.而且很多在forms中很容易控制的东西,到了OAF忽然变的很难.它有的form都有,form有的它不一定有.就比如做个很简单的功能:把age这个列数值>50的纪录用蓝色字体显示.
4.重用性
谈到这个可是说重用性JAVA等面向对象语言的一个最大的优势.的确OAF可以把一个页面分成好多个Class然后可以很方便的import,和extend.这个对大型的项目开发真的是有很大的好处.form的重用就没有办法这么灵活了.但是根据我的开发经验我,我很少从Templete直接开始建forms,我先找一个界面上功能差不多form直接改.而且数据库的开发归集到最根本的几个操作就是查询,添加,删除,和更改.所以我觉得可以重用的还是蛮多的.
5.程序设计
但是我这里说的是Oracle ERP的二次开发的程序设计,如果开发其他程序,我觉得这两个这个都不好.我觉得Oracle ERP开发有一个最大的特点就是原型性开发,就是说很多时候,用户是在发现原来标准的界面不好使,或者不符合当前实际业务了,提出需求,然后更改,所以这些需求有时候很具体,很现实,很容易把握.所以面向对象的设计方法有时候在这里真的显得有点大才小用了.而forms呢,可以说用这个东西开发大型项目真的不好使,但是做二次开发可以.反而在有些时候要比OAF更加的实用.
不管怎样OAF毕竟是新技术,他还需要很长的时间来完善.还有很多的功能值得期待.
OAF 中怎样设置动态的查询
在OAF的开发中,动态查询是避免不了的,就是根据用户输入的条件来查询,当然OAF中有很多方面的方法,但是有一种方法是用的最为普遍的.
1.在controler中的proce***equest 的方法中调用
am.invokeMethod("initDetails", parameters);
当然要调用invokeMethod方法先要OAApplicationModule am = pageContext.getApplicationModule(webBean);来实例化am.
initDetails是写在AM的java 文件的中的一个方法,parameters可以用pageContext.getParameters 方法得到你想要的任何参数.
2.在AM的java文件中写一个initDetails方法函数,来调用VO中的方法.如:initQuery(String XXXX);
3.在VO中添加下面的代码,这个代码是从OAF的UG里面拿出来的,我觉得这段代码比较的经典,以后在开发中会不断的用到.
这段代码直接运行的话要原来的基础上要import一个类:
import java.util.Vector
Initialize and execute the query
public void initQuery(String name, String onHold, String number)
{
StringBuffer whereClause = new StringBuffer(100);
Vector parameters = new Vector(3);
int clauseCount = 0;
int bindCount = 0;
setWhereClauseParams(null); // Always reset
if ((name != null) && (!("".equals(name.trim())))) { whereClause.append(" NAME like :"); whereClause.append(++bindCount); parameters.addElement(name + "%"); clauseCount++; }
if ((number != null) && (!(""Equals(number.trim())))) { Number supplierId = null; // SUPPLIER_ID is a NUMBER; datatypes should always // match, and the parameter passed to this method is a // String. try { supplierId = new Number(number); } catch(Exception e) {} if (clauseCount > 0) { whereClause.append(" AND "); } whereClause.append(" SUPPLIER_ID = :"); whereClause.append(++bindCount); parameters.addElement(supplierId); clauseCount++; }
if ((onHold != null) && (!(""Equals(onHold.trim())))) { if (clauseCount > 0) { whereClause.append(" AND "); } whereClause.append(" ON_HOLD_FLAG = :"); whereClause.append(++bindCount); parameters.addElement("Y"); clauseCount++; }
setWhereClause(whereClause.toString());
if (bindCount > 0) { Object[] params = new Object[bindCount]; // the copyInto() is 1.1.8 compliant which, as of 4/02/03, is required by ARU parameters.copyInto(params); setWhereClauseParams(params); } executeQuery();
} // end initQuery( )
Genterate an Application Module Interface
If you want to generate an application module interface
so you can invoke typed methods directly
(with compile-time checking) instead of calling
invokeMethod(), you must first create the methods
that you want to expose to the client. Then:
- In the JDeveloper Navigator, select the application module
- that you just created, right-click and select Edit <appmodule_name>....
- In the Application Module Wizard, select Client Methods.
- Select the methods you want to be able to invoke remotely in the
- Available list and shuttle them to the Selected list.
- Select OK to create your interface.
Block的数据源是View的 如何操作数据
前几天有个朋友问起这个问题,刚好我在以前同事的blog中看到这文章,下面的内容是转的,不是本来写的:
Block的数据源是View的,如果想操作数据,需要注意在以下几个Trigger里面写代码:
On-lock:
select INVENTORY_ITEM_ID into :XX_UPDATE_CATEGORY_V.INVENTORY_ITEM_ID
from XX_UPDATE_CATEGORY_DETAIL
where rowid = :XX_UPDATE_CATEGORY_V.row_id
for update of INVENTORY_ITEM_ID;
on-insert:
DECLARE
L_USER_ID NUMBER;
BEGIN
L_USER_ID:=TO_NUMBER(FND_PROFILE.VALUE('USER_ID'));
insert into xxuts.xx_update_category_detail
values
END;
on-update:
update xxuts.xx_update_category_detail
set
where
ROWID=:XX_UPDATE_CATEGORY_V.ROW_ID
;
on-delete:
DELETE FROM xx_update_category_detail WHERE ROWID=:XX_UPDATE_CATEGORY_V.ROW_ID;
如何把数据上传到EBS的forms的数据块中
1. 前几天做了一个把文件上传到form的输入域中的程序,这里把步骤简单的写一下,附上关键的源代码.以供参考.
1.创建一个临时表: XXX_TEMP_FILES
建表语句是:
CREATE TABLE XXX_TEMP_FILES (
FILE_ID NUMBER,
SEQ NUMBER,
TEXT VARCHAR2(2000),
CREATION_DATE DATE
)
创建这个表的目的就是要把数据从FND_LOBS这个表的file_data这个字段的数据,通过程序,因为这个表的这个数据是lobs类型的,所以整个文件都放在这个字段里,我们利用这个临时表,把数据文件拆成一行一个纪录.然后每行在根据分个符查分.
2. 创建上传包: XXX_FILE_IO
XXX_FILE_IO 包含三个子程序:
INS_TEMP_FILES:从fnd_lobs 表中取上传的数据,把它按行来拆分,并插入到: XXX_TEMP_FILES 表中
SEL_TEMP_FILES:从XXX_TEMP_FILES 中把数据去出
DEL_TEMP_FILES:数据已经上传到Form的界面中,需要删除文件.
主要语句就是:
PROCEDURE INS_TEMP_FILES(p_file_id IN NUMBER) IS
w_integer INTEGER;
w_blob BLOB;
w_raw RAW(10);
w_buff VARCHAR2(30000);
w_line VARCHAR2(30000);
w_len INTEGER;
eofsw BOOLEAN := FALSE;
offset INTEGER;
w_b_len NUMBER := 0;
w_num NUMBER;
w_seq NUMBER := 0;
BEGIN
SELECT file_data INTO w_blob FROM fnd_lobs WHERE file_id = p_file_id;
offset := 1;
LOOP
EXIT WHEN eofsw;
w_seq := w_seq + 1;
w_raw := utl_raw.cast_to_raw(chr(10));
w_num := dbms_lob.instr(w_blob, w_raw, offset, 1);
w_len := w_num - w_b_len;
w_b_len := w_num;
IF w_num = 0
THEN
w_len := 20000;
eofsw := TRUE;
END IF;
BEGIN
DBMS_LOB.READ(w_blob, w_len, offset, w_buff);
EXCEPTION
WHEN no_data_found THEN
EXIT;
WHEN OTHERS THEN
RAISE;
END;
w_line := utl_raw.cast_to_varchar2(w_buff);
SELECT REPLACE(w_line, chr(10), NULL) INTO w_line FROM dual;
SELECT REPLACE(w_line, chr(13), NULL) INTO w_line FROM dual;
INSERT INTO XXX_TEMP_FILES
(FILE_ID, SEQ, TEXT, CREATION_DATE)
VALUES
(p_file_id, w_seq, w_line, SYSDATE);
offset := offset + w_len;
END LOOP;
END;
3. 在Form文件中的Program Unit中健一个包.XXX_UPLOAD
这个文件最好做成PLL,和其他客制化的有用的程序一起打包,上传到form这是一个系统比较有用的通用的程序.
主要是利用FND_GFM这个通用上传的工具,把文件传到,FND_LOBS中去,然后第二步建好的的包,进行数据拆分:
p_file_id := NULL;
access_id := FND_GFM.AUTHORIZE(NULL);
FND_PROFILE.GET('APPS_WEB_AGENT', l_server_url);
l_url := rtrim(l_server_url, '/') ||
'/fnd_file_upload.displayGFMform?access_id=' ||
to_char(access_id) ||
chr(38) ||
'l_server_url=' ||
l_server_url;
if (l_url is NULL) then
raise form_trigger_failure;
return NULL;
end if;
FND_UTILITIES.OPEN_URL(l_url);
FND_MESSAGE.SET_NAME('FND', 'ATCHMT-FILE-UPLOAD-COMPLETE');
button_choice := FND_MESSAGE.QUESTION(
button1 => 'YES',
button2 => null,
button3 => 'NO',
default_btn => 1,
cancel_btn => 3,
icon => 'question'
);
if button_choice = 1 then
p_file_id := FND_GFM.GET_FILE_ID(access_id);
XXX_FILE_IO.INS_TEMP_FILES(p_file_id);
-- pcm_dbms_lob.UPOPEN(p_file_id);
else
return NULL;
end if;
return p_file_id;
1. 在Form文件中的Program Unit中健一个程序如: UPLOAD_XXX_XXX(X根据实际需要转换)
UPLOAD_XXX_XXX 这个文件的需要在实际的应用中作改动,根绝实际的要导入的字段修改程序.主要功能就是从XXX_TEMP_FILES把数据读出,然后根据分割符来,把每个数据对应到form的域中.
如何注册 SSWA jsp 函数 的页面
在功能注册这里选择SSWA jsp 函数 ,然后把Jsp的页面到/app/jssit/jssitcomn/html 目录中,这个目录随各个环境不同也不一定相同,但是和$JAVA_TOP(/app/jssit/jssitcomn/java)这个目录只有最好后一个目录不同.
也可以在/app/jssit/jssitcomn/html 目录下自己建立一个xxx的文件夹,但是这个在功能注册这里 HTML调用 域要输入 xxx/xxx.jsp,前面加上自己建立的目录路径就可以了.
实际上OAF的开发也是要用 SSWA jsp 函数 这个类型来注册,所有OAF的程序都要由OA.jsp这个页面作为入口.所以在 HTML的调用中需要输入:OA.jsp?page=/oracle/apps/fnd/framework/toolbox/tutorial/webui/HelloWorldPG
?后面的就是OA这个页面要调用的参数,实际上就是告诉系统你的HelloWorldPG.xml这个文件的路径,主意系统里面不需要加上xml.
OAF 配置方法
下载jdev 9.03.5带Oracle Applications Extension扩展包!(以下简称 jdev)(login Metalink and search the patch number 4573517)
解压至某目录(我是d:javajdev_oaf)(注意目录中不要带有空格!)
解压后的目录结构是
jdevbin jdev的执行程序所在目录
jdevdoc 开发文档
jdevhome oaf工作目录
配置步骤:
1) 填加环境变量 JDEV_USER_HOME
指向d:javajdev_oafjdevhomejdev
2)配置数据库配置文件,放在
这是一个.dbc文件,在oracle ebs安装目录中找(/u02/prod/inst/apps/PROD_ebs/appl/fnd/12.0.0/secure/PROD.dbc)
也可以在http://yourserveraddress:8000/OA_HTML/jsp/fnd/aoljtest.jsp这里面找,进入TEST页面,connnection Test中的locate bdc File就是,内容如下:
#DB Settings
#Wed Jul 12 11:19:03 CST 2006
GUEST_USER_PWD=GUEST/ORACLE
APPL_SERVER_ID=21352B7FD1D64869B9E073D0BF9C66AB17555619151894333175138346880731
FND_JDBC_BUFFER_DECAY_INTERVAL=300
APPS_JDBC_DRIVER_TYPE=THIN
FND_JDBC_BUFFER_MIN=1
DB_NAME=VIS
GWYUID=APPLSYSPUB/PUB
FND_JDBC_BUFFER_MAX=5
APPS_JDBC_URL=jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=YES)(FAILOVER=YES)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=EBS.ebsserver.com)(PORT=1521)))(CONNECT_DATA=(SID=VIS)))
FND_JDBC_STMT_CACHE_FREE_MEM=TRUE
FND_JDBC_STMT_CACHE_SIZE=0
TWO_TASK=VIS
FND_MAX_JDBC_CONNECTIONS=500
FND_JDBC_USABLE_CHECK=false
FNDNAM=APPS
FND_JDBC_PLSQL_RESET=false
DB_PORT=1521
FND_JDBC_CONTEXT_CHECK=true
FND_JDBC_BUFFER_DECAY_SIZE=5
DB_HOST=ebs.ebsserver.com
d:javajdev_oafjdevhomejdevmyhtmlOA_HTMLsecure目录中
注意,上面的配置文件中,有一名要注释掉,不然有错误,网上有人说这是一个BUG,要下载补丁才能解决,我没有权限下载补丁,注掉吧,就是这句,前面加上#即可
APPS_JDBC_URL=jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=YES)(FAILOVER=YES)(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=EBS.ebsserver.com)(PORT=1521)))(CONNECT_DATA=(SID=VIS)))
3)创建快捷方式
指向d:javajdev_oafdevbinjdevw.exe
此为jdev的启动命令!
4)在oracle ebs配置下面两个职责 给你的开发用户!一般是在application short name (AK)中的职责
OA Framework ToolBox Tutorial (responsibility key is FWK_TBX_TUTORIAL)
OA Framework ToolBox Tutorial Labs (responsibility key is FWK_TOOLBOX_TUTORIAL_LABS)
5)配置数据库连接
打开D:javajdev_oafjdevhomejdevmyprojects下面的toolbox.jws工作空间(扩展名jws为jdev的workspace文件)
在toolbox.jws中,找到Tutorial.jpr(扩展名jpr为jdev的项目文件)这个项目,右键,打开project seting这个命令,在出现的对话框中,选择Oracle Applications 节点下 Runtime Connection.
connection设置为上面的dbc文件
username /password与第四步骤保持一致
职责保持默认。
同样设置LabSolutions.jpr这个项目
配置数据库连接,在与Navigator中,选择Connections下面DataBase节点,填加数据库连接!
配置Tutorial.jpr项目和LabSolutions.jpr项目的project setting中的connect选项的Connection Name为你刚刚配置的数据库连接名
有一个 比较好的OAF的网站:http://oracle.anilpassi.com/oa-framework-tutorials-training.html
PL/SQL中动态掉用存储过程
SQL> set serverout on
SQL> create or replace procedure p_test(a in varchar2,b in varchar2,c out varchar2)
2 is
3 begin
4 c := a||b;
5 end p_test;
6 /
Procedure created
SQL> declare
2 v_sql varchar2(1000);
3 c varchar2(1000);
4 begin
5 v_sql:='begin p_test(:v1,:v2,:v3); end;';
6 execute immediate v_sql using in '1',in '2',out c;
7 dbms_output.put_line(c);
8 end;
9 /
12
PL/SQL procedure successfully completed
shell入门基础
1.建立和运行shell程序
什么是shell程序呢? 简单的说shell程序就是一个包含若干行
shell或者linux命令的文件.
象编写高级语言的程序一样,编写一个shell程序需要一个文本编辑器.如VI等.
在文本编辑环境下,依据shell的语法规则,输入一些shell/linux命令行,形成一个完整
的程序文件.
执行shell程序文件有三种方法
(1)#chmod +x file(在/etc/profile中,加入export PATH=${PATH}:~/yourpath,就可以在命令行下直接运行,像执行普通命令一样)
(2)#sh file
(3)# . file
(4)#source file
在编写shell时,第一行一定要指明系统需要那种shell解释你的shell程序,如:#! /bin/bash,
#! /bin/csh,/bin/tcsh,还是#! /bin/pdksh .
2.shell中的变量
(1)常用系统变量
$ # :保存程序命令行参数的数目
$ ? :保存前一个命令的返回码
$ 0 :保存程序名
$ * :以("$1 $2...")的形式保存所有输入的命令行参数
$ @ :以("$1""$2"...)的形式保存所有输入的命令行参数
(2)定义变量
shell语言是非类型的解释型语言,不象用C++/JAVA语言编程时需要事先声明变量.给一
个变量赋值,实际上就是定义了变量.
在linux支持的所有shell中,都可以用赋值符号(=)为变量赋值.
如:
abc=9 (bash/pdksh不能在等号两侧留下空格 )
set abc = 9 (tcsh/csh)
由于shell程序的变量是无类型的,所以用户可以使用同一个变量时而存放字符时而存放
整数.
如:
name=abc (bash/pdksh)
set name = abc (tcsh)
在变量赋值之后,只需在变量前面加一个$去引用.
如:
echo $abc
(3)位置变量
当运行一个支持多个命令行参数的shell程序时,这些变量的值将分别存放在位置变量里.
其中第一个参数存放在位置变量1,第二个参数存放在位置变量2,依次类推...,shell保留
这些变量,不允许用户以令外的方式定义他们.同别的变量,用$符号引用他们.
3.shell中引号的使用方法
shell使用引号(单引号/双引号)和反斜线("")用于向shell解释器屏蔽一些特殊字符.
反引号(")对shell则有特殊意义.
如:
abc="how are you" (bash/pdksh)
set abc = "how are you" (tcsh)
这个命令行把三个单词组成的字符串how are you作为一个整体赋值给变量abc.
abc1='@LOGNAME,how are you!' (bash/pdksh)
set abc1='$LOGNAME,how are you!' (tcsh)
abc2="$LOGNAME,how are you!" (bash/pdksh)
set abc2="$LOGNAME,how are you!" (tcsh)
LOGNAME变量是保存当前用户名的shell变量,假设他的当前值是:wang.执行完两条命令后,
abc1的内容是:$LOGNAME, how are you!.而abc2的内容是;wang, how are you!.
象单引号一样,反斜线也能屏蔽所有特殊字符.但是他一次只能屏蔽一个字符.而不能屏蔽
一组字符.
反引号的功能不同于以上的三种符号.他不具有屏蔽特殊字符的功能.但是可以通过他将
一个命令的运行结果传递给另外一个命令.
如:
contents=`ls` (bash/pdksh)
set contents = `ls` (tcsh)
4.shell程序中的test命令
在bash/pdksh中,命令test用于计算一个条件表达式的值.他们经常在条件语句和循环
语句中被用来判断某些条件是否满足.
test命令的语法格式:
test expression
或者
[expression]
在test命令中,可以使用很多shell的内部操作符.这些操作符介绍如下:
(1)字符串操作符 用于计算字符串表达式
test命令 | 含义
-----------------------------------------
Str1 = str2 | 当str1与str2相同时,返回True
Str1! = str2| 当str1与str2不同时,返回True
Str | 当str不是空字符时,返回True
-n str | 当str的长度大于0时,返回True
-z str | 当str的长度是0时,返回True
-----------------------------------------
(2)整数操作符具有和字符操作符类似的功能.只是他们的操作是针对整数
test表达式 | 含义
---------------------------------------------
Int1 -eq int2|当int1等于int2时,返回True
Int1 -ge int2|当int1大于/等于int2时,返回True
Int1 -le int2|当int1小于/等于int2时,返回True
Int1 -gt int2|当int1大于int2时,返回True
Int1 -ne int2|当int1不等于int2时,返回True
-----------------------------------------
(3)用于文件操作的操作符,他们能检查:文件是否存在,文件类型等
test表达式 | 含义
------------------------------------------------
-d file |当file是一个目录时,返回 True
-f file |当file是一个普通文件时,返回 True
-r file |当file是一个刻读文件时,返回 True
-s file |当file文件长度大于0时,返回 True
-w file |当file是一个可写文件时,返回 True
-x file |当file是一个可执行文件时,返回 True
------------------------------------------------
(4)shell的逻辑操作符用于修饰/连接包含整数,字符串,文件操作符的表达式
test表达式 | 含义
----------------------------------------------------------
! expr |当expr的值是False时,返回True
Expr1 -a expr2|当expr1,expr2值同为True时,返回True
Expr1 -o expr2|当expr1,expr2的值至少有一个为True时,返回True
-----------------------------------------------------------
注意:
tcsh shell 不使用test命令,但是tcsh中的表达式同样能承担相同的功能.tcsh
支持的表达式于C中的表达式相同.通常使用在if和while命令中.
tcsh表达式 | 含义
-------------------------------------------------------
Int1 <= int2 |当int1小于/等于int2时,返回True
Int1 >= int2 |当int1大于/等于int2时,返回True
Int1 < int2 |当int1小于int2时,返回True
Int1 > int2 |当int1大于int2时,返回True
Str1 == str2 |当str1与str2相同时,返回True
Str1 != str2 |当str1与str2不同时,返回True
-r file |当file是一个可读文件时,返回True
-w file |当file是一个可写文件时,返回True
-x file |当file是一个可执行文件时,返回True
-e file |当file存在时,返回True
-o file |当file文件的所有者是当前用户时,返回True
-z file |当file长度为0时,返回True
-f file |当file是一个普通文件时,返回True
-d file |当file是一个目录时,返回True
Exp1 || exp2 |当exp1和exp2的值至少一个为True时,返回True
Exp1 && exp2 |当exp1和exp2的值同为True时,返回True
! exp |当exp的值为False时,返回True
-------------------------------------------------------
/***************************************************/
先不要管Shell的版本,来看看Shell 变量,在Shell中有三种变量:系统变量,环境变量,用户变量。其中用户变量在编程过程中使用最多,系统变量在对参数判断和命令返回值判断会使用,环境变量主要是在程序运行的时候需要设置。
1 系统变量
Shell常用的系统变量并不多,但却十分有用,特别是在做一些参数检测的时候。下面是Shell常用的系统变量
表示方法 | 描述 |
---|---|
$n | $1 表示第一个参数,$2 表示第二个参数 ... |
$# | 命令行参数的个数 |
$0 | 当前程序的名称 |
$? | 前一个命令或函数的返回码 |
$* | 以"参数1 参数2 ... " 形式保存所有参数 |
$@ | 以"参数1" "参数2" ... 形式保存所有参数 |
$$ | 本程序的(进程ID号)PID |
$! | 上一个命令的PID |
#!/bin/sh #This file is used to explain the shell system variable. echo "the number of parameter is $# "; echo "the return code of last command is $?"; echo "the script name is $0 "; echo "the parameters are $* "; echo "$1 = $1 ; $2 = $2 ";
下面是运行结果:
BeautifierPlugin Error: Unable to handle "bash" syntax.
-bash-2.05b$ ./chapter2.1.sh winter stlchina the number of parameter is 2 the return code of last command is 0 the script name is ./chapter2.1.sh the parameters are winter stlchina $1 = winter ; $2 = stlchina
这个例子太简单了,一点也不实用,下面来个实用的,如果你看不懂,没有关系,后面的内容会有详细解释。 BeautifierPlugin Error: Unable to handle "bash" syntax.
#!/bin/sh if [ $# -ne 2 ] ; then echo "Usage: $0 string file"; exit 1; fi grep $1 $2 ; if [ $? -ne 0 ] ; then echo "Not Found "$1" in $2"; exit 1; fi echo "Found "$1" in $2";
上面的例子中使用了$0 $1 $2 $# $? 等变量,下面是程序的解释:
- 判断运行参数个数,如果不等于2,显示使用"用法帮助", 其中 $0 表示就是脚本自己。
- 用grep 在$2 文件中查找$1 字符串。
- 判断前一个命令运行后的返回值(一般成功都会返回0, 失败都会返回非0)。
- 如果没有成功显示没找到相关信息,否则显示找到了。
- 其中"表示转义,在"" 里面还需要显示"号,则需要加上转义符" .
下面运行的例子:
BeautifierPlugin Error: Unable to handle "bash" syntax.
./chapter2.2.sh usage chapter2.2.sh Not Found "usage" in chapter2.2.sh -bash-2.05b$ ./chapter2.2.sh Usage chapter2.2.sh echo "Usage: $0 string file"; Found "Usage" in chapter2.2.sh
2 Shell用户变量
2.1 基础
不管系统变量有多少,对于需求来说,总是不够的。用户变量是最常用到的变量,使用也十分简单。
用户定义的变量必须由字母数字及下划线组成,并且变量名的第一个字符不能为数字, 与其它UNIX名字一样,变量名是大小写敏感的. 对于用户变量,用户可按如下方式赋值: BeautifierPlugin Error: Unable to handle "bash" syntax.
name="Winter"
在引用变量时,需在前面加$符号,用户也可以在变量间进行相互赋值,如: BeautifierPlugin Error: Unable to handle "bash" syntax.
name="Winter" WINTER=$name echo "Hello $WINTER !"
输出结果应该很清楚:Hello Winter !
这里需要注意一点:变量和'='之间不要有空格,'='和赋值也不要有空格,否则shell不会认为变量被定义。掌握了基本的使用方法,你可以完全开始你的编程工作了。不过有时候需要未雨绸缪,下面介绍用户变量的一些技巧。
2.2 使用技巧
也可以用变量和其他字符组成新的字,这时可能需要把变量用{}括起,如: BeautifierPlugin Error: Unable to handle "bash" syntax.
SAT=Satur echo Today is ${SAT}day
输出结果是: Today is Saturday
有时候为了避免变量名和别的字符产生混淆,你最好养成习惯把变量名用{}括起来。
对于未赋值的变量, Shell以空值对待, 用户也可以用unset命令清除给变量赋的值.看一个例子: BeautifierPlugin Error: Unable to handle "bash" syntax.
#!/bin/sh echo "a=$a" ; a=2 echo "a=$a" ; unset a echo "a=$a" ;
先猜猜结果是什么? BeautifierPlugin Error: Unable to handle "bash" syntax.
-bash-2.05b$ ./test.sh a= a=2 a=
如果你懂C++,你应该知道有个变量修饰符"const",用于避免程序一不小心对变量进行修改。在shell中,对于用户变量,你可以使用同样的修饰符"readonly", 如果我把上面的例子修改成这样: BeautifierPlugin Error: Unable to handle "bash" syntax.
#!/bin/sh echo "a=$a" ; #下面增加了readonly readonly a=2 echo "a=$a" ; unset a echo "a=$a" ;
其结果当然会不一样了: BeautifierPlugin Error: Unable to handle "bash" syntax.
-bash-2.05b$ ./test.sh a= a=2 a=2
2.3 shell 中的数组
shell变量中还能设置数组,但是不同的shell版本有不同数组赋值方法,而bourne shell 中不支持数组方式。因此,如果不是十分需要,还是建议你不要使用数组。若你的数据结构十分复杂,必须要使用数组,那么我建议你还是选择别的语言吧,shell不是万能的。
shell有两种赋值方式,第一种是直接用下标赋值: BeautifierPlugin Error: Unable to handle "bash" syntax.
name[0]="Tom" name[1]="Tomy" name[2]="John" ...
另一种方式对于不同的shell版本不一样。bash中赋值: BeautifierPlugin Error: Unable to handle "bash" syntax.
#!/usr/local/bin/bash name=("Tom" "Tomy" "John") for i in 0 1 2 do echo $i:${name[$i]} ; done;
上面两种赋值方式达到的效果一样。另外,你看见访问数组元素的方法了吗?使用${name[index]}的方式。注意第一行使用的是#!/usr/local/bin/bash, 和以前有些不一样哦。其输出结果是: BeautifierPlugin Error: Unable to handle "bash" syntax.
-bash-2.05b$ ./test.sh 0:Tom 1:Tomy 2:John
3 shell 环境变量
shell 环境变量是所有shell 程序都会接受的参数。shell程序运行时,都会接收一组变量,这组变量就是环境变量。常用的环境变量:
名称 | 描述 |
PATH | 命令搜索路径,以冒号为分隔符.注意与DOS下不同的是, 当前目录不在系统路径里 |
HOME | 用户home目录的路径名,是cd命令的默认参数 |
COLUMNS | 定义了命令编辑模式下可使用命令行的长度 |
EDITOR | 默认的行编辑器 |
VISUAL | 默认的可视编辑器 |
FCEDIT | 命令fc使用的编辑器 |
HISTFILE | 命令历史文件 |
HISTSIZE | 命令历史文件中最多可包含的命令条数 |
HISTFILESIZE | 命令历史文件中包含的最大行数 |
IFS | 定义SHELL使用的分隔符 |
LOGNAME | 用户登录名 |
指向一个需要SHELL监视其修改时间的文件.当该文件修改后, SHELL将发消息You hava mail给用户 | |
MAILCHECK | SHELL检查MAIL文件的周期,单位是秒 |
MAILPATH | 功能与MAIL类似.但可以用一组文件,以冒号分隔,每个文件后可跟一个问号和一条发向用户的消息 |
SHELL | SHELL的路径名 |
TERM | 终端类型 |
TMOUT | SHELL自动退出的时间,单位为秒,若设为0则禁止SHELL自动退出 |
PROMPT_COMMAND | 指定在主命令提示符前应执行的命令 |
PS1 | 主命令提示符 |
PS2 | 二级命令提示符,命令执行过程中要求输入数据时用 |
PS3 | select的命令提示符 |
PS4 | 调试命令提示符 |
MANPATH | 寻找手册页的路径,以冒号分隔 |
LD_LIBRARY_PATH | 寻找库的路径,以冒号分隔 |
这些变量,要关注的最多的就是PATH, 其重要性不要我说了吧?
如果你希望把你定义的变量让其他所有的shell程序都能使用,也就是定义新的环境变量。你只要使用export关键词就可以了。例如: BeautifierPlugin Error: Unable to handle "bash" syntax.
export MY_NAME=Winter export PATH=/home/winter/bin:$PATH
上面的程序中,第一行输出MY_NAME变量,第二行是在环境变量PATH中增加一个路径/home/winter/bin 。如果你希望这些设置在你登陆unix/linux都有效,你需要把他们加入到你的shell启动脚本中, 如果是使用bash BeautifierPlugin Error: Unable to handle "bash" syntax.
~/.bash_profile
其他版本你看一眼就知道了,在你的home目录下,以"."开头的文件,一般都会隐藏起来,你需要使用'ls -al'命令来显示
如何查询视图中哪些字段是允许更新
Name Type Nullable Default Comments
----------- ------------ -------- ------- -------------------------
OWNER VARCHAR2(30) Table owner
TABLE_NAME VARCHAR2(30) Table name
COLUMN_NAME VARCHAR2(30) Column name
UPDATABLE VARCHAR2(3) Y Is the column updatable?
INSERTABLE VARCHAR2(3) Y Is the column insertable?
DELETABLE VARCHAR2(3) Y Is the column deletable?
使用 Select * From user_Updateable_Columns Where Table_name=Upper('YourViewname') 即可查询视图中哪些字段是允许更新的
转载于:https://blog.51cto.com/shaofeng/655690