Profilezhanjie的共享空间PhotosBlogLists Tools Help
July 24

v$sql v$sqlarea v$sqltext

V$SQL       Child cursor details for V$SQLAREA

V$SQLAREA   Shared pool details for statements/anonymous blocks

V$SQLTEXT   SQL text of statements in the shared pool

            都是通过ADDRESSHASH_VALUE可以为一判定一个SQL

            在两个不同的用户里分别建立wwm表,用两个用户分别运行select * from wwm.则在v$sql里是两条记录(两个cursor), ADDRESSHASH_VALUE却是相同的。但在v$sqlarea,v$sqltext却只有一条记录。V$sqlarea v$sql合并cursor后的结果.可以通过v$sqlPLAN_HASH_VALUE来判断两个SQL的执行计划是否相同。

            V$sqltext能查到SQL语句的全部(将一个SQL分为多条记录,每条记录64字节,通过HASH VALUE来判断是否属于一条SQL),但v$sql, v$sqlarea只显示1000字节。所以要访问V$SQLTEXT最好根据piece去排序,来组织正确的SQL

            A用户执行SELECT * FROM WWM ORDER BY ID 1次,用B用户执行SELECT * FROM WWM ORDER BY ID 3次,则

select sql_text,sorts from v$sql

where sql_text like '%wwm%'

SQL_TEXT                                         SORTS

--------------------------------------------------------------------------------

 

select * from wwm order by id           3

select * from wwm order by id           1

 

select sql_text,sorts from v$sqlarea

where sql_text like '%wwm%'

SQL_TEXT                                              SORTS

--------------------------------------------------------------------------------

select * from wwm order by id           4

 

查找耗费资源的SQL

  1  SELECT hash_value, executions, buffer_gets, disk_reads, parse_calls

  2    FROM V$SQLAREA

  3   WHERE buffer_gets > 10000000

  4      OR disk_reads > 1000000

  5*  ORDER BY buffer_gets + 100*disk_reads DESC

SQL> /

 

HASH_VALUE EXECUTIONS BUFFER_GETS DISK_READS PARSE_CALLS

---------- ---------- ----------- ---------- -----------

2653134598          2       73426      33572           2

1813062183       7424     1127737        293        6497

2964631876       9377      818505          5        9365

1169272907      31598      521484          0       12817

 664977058       1202      301733         11           2

3195782399       4209      266893         13        4209

 895481279      15786      236850        227       12853

   3722848       7285      124008          0        5050

 264196705       7285      109275        118        4925

数据类型内部结构存储

SQL> create table wwm( thechar char(10),thevarchar varchar2(20),thenumber number(10,2));

Table created.

SQL> select * from wwm;

 

THECHAR    THEVARCHAR            THENUMBER

---------- -------------------- ----------

dsffg      varchar2                   10.2

wwm        wwmwwm2                   -999.2

charcharch charcharcharcharchar  100000000

  1* select thechar,dump(thechar) from wwm

SQL> /

THECHAR                                                                                             DUMP(THECHAR)

-----------------------------------------------------------

Dsffg                                                                            Typ=96 Len=10: 100,115,102,102,103,32,32,32,32,32

Wwm                                                                           Typ=96 Len=10: 119,119,109,32,32,32,32,32,32,32

Charcharch                                                                    Typ=96 Len=10: 99,104,97,114,99,104,97,114,99,104

可以看到THECHARCHAR Typ=96)类型的(NCHAR也是96),长度是10Len=10),不足长度的补空(32

SQL> select thevarchar,dump(thevarchar) from wwm;

THEVARCHAR                                                                          DUMP(THEVARCHAR)

--------------------------------------------------------------------------------------

varchar2                                                                                    Typ=1 Len=8: 118,97,114,99,104,97,114,50

wwmwwm2                                                                  Typ=1 Len=7: 119,119,109,119,119,109,50

charcharcharcharchar                                         Typ=1 Len=20: 99,104,97,114,99,104,97,114,99,104,97,114,99,104,97,114,99,104,97,114

可以看到THEVARCHARVARCHAR2 Typ=1)类型的,NVARCHAR2也是1

 

SQL> select thenumber,dump(thenumber) from wwm;

 THENUMBER                                                                           DUMP(THENUMBER)

-----------------------------------------------------

      10.2                                                                                                Typ=2 Len=3: 193,11,21

    -999.2                                                                                               Typ=2 Len=5: 61,92,2,81,102

 100000000                                                                                           Typ=2 Len=6: 196,100,100,100,100,100

可以看到thenumberNUMBER Typ=2)类型的(FLOAT也是2),

 

select dump(address,16) from v$sqlarea where rownum = 1;

DUMP(ADDRESS,16)

--------------------------------------------------------------------------------

Typ=23 Len=8: 7,0,0,0,47,c9,a4,98

RAW     Typ=23

 

  1* select thedate,dump(thedate) from wwm6

THEDATE                                                                     DUMP(THEDATE)

--------------------------------------------------------------------------------

05-JUN-06                                                                    Typ=12 Len=7: 120,106,6,5,17,16,11

DATE类型Typ=12

CENTURY120-100=20

Year:       106-100=06

Month=6

Day=5

Hours=17-1=16

Minutes=16-1=16

Seconds=11-1=10

 

SQL> select sysdate,dump(sysdate) from dual;

SYSDATE                                                                     DUMP(SYSDATE)

---------------------------------------------------------

07-6 -06                                                                    Typ=13 Len=8: 214,7,6,7,14,57,43,0

SYSDATETyp=13

 

排序,加减等操作就是根据DUMP的结果来排序的(会经过与或等运算,但基数不同,不在这里讨论),

 

这里只是列出了常用的类型,希望大家以后在读内部结构的时候发现Typ=XX时会想起这篇文章。谢谢

ORA-03237: Initial Extent of specified size cannot be allocated in tablespace

问题是在建立LOB字段时发生的,用 dmsdeuser1用户执行

SQL> connect dmsdeuser1/pass@sid

SQL> CREATE TABLE CONTENT  (

  2     MSG_ID               CHAR(100)                       NOT NULL,

  3     MSG_DATA             BLOB,

  4     CONSTRAINT PK_CONTENT PRIMARY KEY (MSG_ID)

  5  );

CREATE TABLE CONTENT  (

ERROR at line 1:

ORA-03237: Initial Extent of specified size cannot be allocated in tablespace

(DATA01)

 dmsdeuser1用户默认表空间是DATA01,是UNLIMITED

首先看表空间是否有空余空间

SQL> SELECT A.TABLESPACE_NAME,A.BYTES TOTAL,B.BYTES USED, C.BYTES FREE,

  (B.BYTES*100)/A.BYTES "% USED",(C.BYTES*100)/A.BYTES "% FREE"

  FROM SYS.SM$TS_AVAIL A,SYS.SM$TS_USED B,SYS.SM$TS_FREE C

  WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME AND A.TABLESPACE_NAME=C.TABLESPACE_NAME;

 

TABLESPACE_NAME                                                   TOTAL

------------------------------------------------------------ ----------

      USED       FREE     % USED     % FREE

---------- ---------- ---------- ----------

 DATA01                                                       2147483648

   1081344 2146336768 .050354004 99.9465942

 

SYSTEM                                                        419430400

 416677888    2686976   99.34375    .640625

 

UNDOTBS1                                                      209715200

   4898816  204668928  2.3359375   97.59375

 

 虽然DATA01空间是够的,但还是做了一下扩展,SYSTEM表空间将要用尽,也扩展下。

 alter database datafile 'D:\ORACLE\ORADATA\DE2\SYSTEM01.DBF' resize 600M;

alter database datafile 'D:\ORACLE\ORADATA\DE2\DATA01' resize 3000M;
错误依旧
select * from dba_tablespace;

TABLESPACE_NAME                                              BLOCK_SIZE

------------------------------------------------------------ ----------

INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE MIN_EXTLEN

-------------- ----------- ----------- ----------- ------------ ----------

STATUS             CONTENTS           LOGGING            FORCE_

------------------ ------------------ ------------------ ------

EXTENT_MANAGEMENT    ALLOCATION_TYPE    PLUGGE SEGMENT_SPAC

-------------------- ------------------ ------ ------------

SYSTEM                                                             8192

         65536                       1  2147483645                   65536

ONLINE             PERMANENT          LOGGING            NO

LOCAL                SYSTEM             NO     MANUAL

 

DATA01                                                             8192

         16384       16384           1  2147483645            0      16384

ONLINE             PERMANENT          LOGGING            NO

LOCAL                UNIFORM            NO     MANUAL

 

DATA02                                                             8192

       1048576     1048576           1  2147483645            0    1048576

ONLINE             PERMANENT          LOGGING            NO

LOCAL                UNIFORM            NO     AUTO

 

SQL> show parameter block

 

NAME                                 TYPE

------------------------------------ ----------------------

VALUE

------------------------------

db_block_size                        integer

8192

 问题就在这里了,平常,数据库分配的最小EXTENT是两个BLOCK_SIZE,也就是16K,而DATA01表空间的INITIAL EXTENT正好是16K,不会出什么问题。但是LOB等需要至少3个BLOGKS,而RBS需要4个。所以在DATA01表空间是无法建立LOG字段的。

  1  create  tablespace data02  datafile 'D:\ORACLE\ORADATA\DE2\DATA02' size 2000M

  2* extent management local uniform size 1M segment space management auto

SQL> /

 Tablespace created.

 SQL> alter user dmsdeuser1 default tablespace data02;

 User altered.

 SQL> alter user dmsdeuser1 quota unlimited on data02;

 User altered.

 

SQL> connect dmsdeuser1/pass1@sid

Connected.

SQL> CREATE TABLE CONTENT  (

  2     MSG_ID               CHAR(100)                       NOT NULL,

  3     MSG_DATA             BLOB,

  4     CONSTRAINT PK_CONTENT PRIMARY KEY (MSG_ID)

  5  )

  6  /

 Table created.

ORACLE CPU过高的一次调整过程

发现CPU占用率一般都维持在90%以上,由于大量使用FOR UPDATE,造成大量LATCH等等待现象,其中某些多线程SQL又运行非常频繁。很久以前就发现这些问题,给出相对意见,建议不采用FOR UPDATE或在FOR UPDATE上加NOWAIT(见http://spaces.msn.com/sunmoonking/blog/cns!E3BD9CBED01777CA!318.entry   “ELECT FOR UPDATE 相关的知识”一章  ),由于项目进程问题一直没进行程序修改,决定在这次解决掉,以解后顾之忧。
 
调整前要知道如下问题
      1,CPU是多少MHZ
      2,SERVER 端的CPU是否有负荷较重
      3,CLIENT 端的CPU是否有负荷较重
      4,空闲时间(如半夜)CPU使用率是否超过15%,如果超过则需要特别注意了
      5,CPU的PEAK LOAD
      6,CPU的IDLE STATE
 
影响CPU的因素
1,高的无必要的解析会代价昂贵。
     发现那些SQL运行了大量的PARSE
     select sql_text, parse_calls, executions from v$sqlarea order by parse_calls desc;
     SYS的总的PARSE情况
     select name, value from v$sysstat where name = ’parse count%’;
     只有硬解析才能减少,可以绑定变量,或增加每一个SESSION的CACHED CURSORS。
2,导致大量I/O的SQL也会明显占用CPU,如没有INDEX。BUFFER GETS一般会同CPU一块增长。可以通过v$sqlarea发现buffer_gets
3,其他等待时间,可以通过v$sesstat,v$sysstat查看
 
#VMSTAT 5 5 的CPU部分
      us  user用掉的
      sy  system用掉的
      id  空闲
 
调整前
TOPAS
      Name            PID  CPU%  PgSp Owner
      oracle       688416  25.2   4.6 orasbp
      oracle       569658  24.9   4.5 orasbp
      topas        676210   0.1   2.9 root
      syncd         77964   0.0   0.5 root
      hatsd        159792   0.0   8.3 root
或者ps aux|head
检查CPU数量
      /usr/sbin/bindprocessor -q
      The available processors are:  0 1 2 3
 
STATSPACK的信息
                                                     Total Wait   wait    Waits
Event                               Waits   Timeouts   Time (s)   (ms)     /txn
---------------------------- ------------ ---------- ---------- ------ --------
enqueue                             5,465        121      1,793    328      0.6
latch free                          2,986      2,669         21      7      0.3
根据消耗最多CPU的进程PID来得到SID详细信息
select s.sid from v$process p, v$session s
where s.paddr=p.addr and p.spid =  &your_spid;
根据SID查SQL
SELECT SQL_TEXT from V$SQLTEXT_WITH_NEWLINES where HASH_VALUE
= (select sql_hash_value from v$session
where SID = <problem_SID_you_got_from_last_step>) ;
还有
select n.name,s.value
from v$statname n,V$sesstat s
where n.statistic# = s.statistic#
and value > 0
and s.sid = (select a.sid from v$process p,v$session a
where p.addr =a.paddr
and a.terminal = userenv(’terminal’))
order by n.class,n.name
用以上SQL完成SHELL(shell信息在后面whoit.sh),运行
sh whoit.sh 688416  来根据PID得到用户信息和SQL语句
 
在STATSPACK和我的whoit.sh都指定是这个SQL的问题
SELECT demessageid, fromid, apptype, demessage,appversion,vovers
ion ,toid,tag FROM de_receivelog  WHERE (status = :1 and rownum<
=1 and (dealtime is null or dealtime<sysdate) and delock=0) or (
delock=1 and Update_Date<sysdate-2/24) order by RECEIVETIME for
update
 
再看等待事件
 select sid||' '||event||' '|| total_waits||' '||average_wait               from v$session_event where sid=25
SQL> /
SID||''||EVENT||''||TOTAL_WAITS||''||AVERAGE_WAIT
--------------------------------------------------------------------------------
25 latch free 46180 1
25 control file sequential read 4 0
25 log file sync 1 0
25 db file sequential read 202 0
25 db file scattered read 445 1
25 SQL*Net message to client 22 0
25 SQL*Net message from client 22 0
 
只有一个DEFAULT 池
NAME                                      HIT_RATIO
---------------------------------------- ----------
DEFAULT                                   .88042806
 
设置db_keep_cache_size池,并KEEP表
ALTER  TABLE customer STORAGE (BUFFER_POOL  RECYCLE|KEEP|DFAULT)
SQL> analyze table sbpopt.de_receivelog compute statistics;
建立相关索引
alter table  TI_REPAIR_DEED storage(buffer_pool keep);
alter table  de_receivelog  storage(buffer_pool keep);

 
看到相关的等待都是LATCH FREE,enqueue,估计是由于SELECT FOR UPDATE并且全表扫描造成的
查看每个Session的CPU利用情况:
select ss.sid||' '||se.command||' '||ss.value CPU ||' '||se.username||' '||se.program
from v$sesstat ss, v$session se
where ss.statistic# in
(select statistic#
from v$statname
where name = 'CPU used by this session')
and se.sid=ss.sid
and ss.sid>6
order by ss.value
 
根据STATSPACK的HASH VALUE 用SQL>@sprepsql得到
STATSPACK SQL report for Hash Value: 1710202187  Module: JDBC Thin Client
DB Name         DB Id    Instance     Inst Num Release     Cluster Host
------------ ----------- ------------ -------- ----------- ------- ------------
SBP           3008872479 SBP                 1 9.2.0.6.0   NO      svodbp01
 Start Id     Start Time         End Id      End Time       Duration(mins)
--------- ------------------- --------- ------------------- --------------
       44 23-May-06 14:13:01         45 23-May-06 14:28:00           14.98
SQL Statistics
~~~~~~~~~~~~~~
-> CPU and Elapsed Time are in seconds (s) for Statement Total and in
   milliseconds (ms) for Per Execute
                                                       % Snap
                     Statement Total      Per Execute   Total
                     ---------------  ---------------  ------
        Buffer Gets:       6,938,821          7,608.4   63.34
         Disk Reads:               0              0.0     .00
     Rows processed:             197              0.2
     CPU Time(s/ms):             508            557.2
 Elapsed Time(s/ms):             607            665.8
              Sorts:           1,292              1.4
        Parse Calls:             191               .2
      Invalidations:               0
      Version count:               1
    Sharable Mem(K):              22
         Executions:             912
SQL Text
~~~~~~~~
SELECT demessageid, fromid, apptype, demessage,appversion,vovers
ion ,toid,tag FROM de_receivelog  WHERE (status = :1 and rownum<
=1 and (dealtime is null or dealtime<sysdate) and delock=0) or (
delock=1 and Update_Date<sysdate-2/24) order by RECEIVETIME for
update nowait
===============================================================
15分钟内执行了912次,占用22K内存(不多),每次执行1.4个排序,共花了508秒,由于已经采取措施将此表KEEP与内存中,因此没有磁盘读,但每次的逻辑读7,608.4个块
 
然后将SQL语句的FOR UPDATE改成 FOR UPDATE NOWAIT;     这才是真正解决问题的地方
至此,通过观察CPU一般维持在25%以内。
 
等待事件
enqueue(队列)  Indicates waits associated with internal queuing mechanism for locking various resources and components of Oracle. Please refer to Appendix B of the Oracle8i Reference Manual for the complete list of enqueues in Oracle.是一种保护共享资源的琐,锁可以保护纪录里面数据一类的共享资源,防止两个人同时修改该纪录,fifo,enqueue等待通常是 ST enqueue,HW enqueue ,TX4 enqueue。ST enqueue在数据字典管理方式表空间的物理空间分配和管理上发挥作用。当有此问题时可以转变为本地管理表空间或预先分配扩展。HW enqueue同段的高水位线一起使用,手工分配扩展可避免其上的等待。TX4 是最常见的,1,唯一索引的重复,需要COMMIT/ROLLBACK来释放ENQUEUE。2,多个并发的对同一位图索引片的修改,同上。3,多用户同时修改相同的数据块,如果已经没有空闲的ITL槽,则会引发一数据块的锁,运用增大initrans或maxtrans以容纳更多ITL槽的方法来解决,或增大PCTFREE。(ST:使用本地表空间或预先分配大扩展,HW预先分配扩展于高水水位线之上,TX4增大表或索引的initrans和maxtrans,TM为外键建立索引,察看日志放在快速磁盘上)
latch free(锁存器空闲,拴空闲) Indicates latch contention for the latch# that is being waited on. Ensure that you already have tuned the number of latches to their allowed maximums by setting the relevant init.ora parameters. If the problem persists, you should determine what is causing the contention for the latch and fix the underlying problem. Your goal should be to cure the disease not the symptom. A latch free event is a symptom of a bigger problem. For example, if the latch# derived from this is a library cache latch (assuming that the shared pool is configured appropriately), it may indicate a significant amount of hard parsing. This usually is a problem with applications that have hard-coded values in them. Either rewrite them with bind variables or upgrade to Oracle8i and use CURSOR_SHARING=force (or just look the other way).Latch Free是一种低级的同步锁机制,用以维持某些访寻和执行操作的顺序。Oracle通过enqueue来达成对重做线程/表/事务一类对象的并发使用,而通过Latch来达成对SGA中共享内存结构的保护。Latch速度快而成本低,往往通过单个的内存单元来实现。大部分Latch是互斥的。共享型Latch许可对其内存结构的并发读操作。当请求得到Latch但它已被其它进程占住时,将产生一条Latch free miss的纪录。大多数Latch问题关联到不使用绑定变量(Library Cache Latch),重做日志生成中问题(Redo Allocation Latch),内存缓冲区竞争问题(Cache Buffers LRU Chain)和内存缓冲区中‘热块’的数据块(Cache Buffers Chain)。也有一些Latch Waits是由软件错误而造成的。    首先确认足够的LATCH数,然后确认那个锁存器(V$SESSION_WAIT的P2),再确认是什么引起的.
 
#cat whoit.sh
sqlplus /nolog <<EOF
   connect / as sysdba
   col machine format a30
   col program format a40
   set line 200
   select sid,serial# ,username,osuser,machine,program,process,to_char(logon_time,'yyyy/mm/dd hh24:mi:ss')
            from v\$session where paddr in
            ( select addr from v\$process where spid in($1));
   select sql_text from v\$sqltext_with_newlines  
            where hash_value in       
            (select SQL_HASH_VALUE from v\$session where       
                 paddr in (select addr from v\$process where spid=$1)   
          )         
            order by piece;         
 exit;
 EOF

PROCEDURE行变列与输出

CREATE OR REPLACE procedure get_activity_code(in_activity_code in tm_recall_activity.activity_code%type,out_curEmp out SYS_REFCURSOR)
IS
     Col_c2 VARCHAR2(4000);
     Col_maxday number(5);
     the_day_count number(5);
     the_sql varchar2(4000);
BEGIN
     the_day_count:='1';                     --计数器
     select max(floor(c.repair_date-e.startdate)) INTO  Col_maxday         --计算最大列数,因为列数是不固定的,比如此处是38
          from tt_activity_vehicle c,tm_recall_activity e
          where e.recall_activity_id=c.recall_activity_id and e.activity_code='L001';
     IF  Col_maxday IS NULL THEN
          dbms_output.put_line('NO MAXDAY');
     END IF;
     the_sql:='select b.rssc_name as rssc,d.labor_no as type ';
     while the_day_count<=Col_maxday LOOP            --循环拼语句
          the_sql:=the_sql||',decode(floor(c.repair_date-e.startdate),'||the_day_count||',count(*),0)';
          the_day_count:=the_day_count+1;                   --加一,要拼出满足需要的列来,比如循环38次
     END LOOP;
     the_sql:=the_sql||' from tm_sst a,tm_rssc b,tt_activity_vehicle c,ti_workitem_detail           d,tm_recall_activity e
          where c.operate_sst_code=a.sst_code and a.rssc_id=b.rssc_id
          and e.recall_activity_id=c.recall_activity_id
          and e.activity_code='''||in_activity_code||'''                      --参数
          and d.labor_no in           (''MFJC0000'',''WXBY0000'',''WXBY1000'',''JCWB0000'',''JWBL0000'',''LP000000'',''JCDQ0000'')
          and c.operate_sst_code=d.sst_code and c.bill_no=d.bill_no
          group by b.rssc_name,(c.repair_date-e.startdate),d.labor_no order by           b.rssc_name,d.labor_no,floor(c.repair_date-e.startdate)';
--execute immediate the_sql;
     open out_curEmp for the_sql;                                            --PROCEDURE的输出关键
     EXCEPTION
     WHEN OTHERS THEN
          raise_application_error(-200020,'Error in get_activity_code'||SQLCODE);
     end get_activity_code;
/
 
----------------------------------------------------------------------------------------------------------------------
运行
SQL> var rset refcursor;
SQL> exec get_activity_code('L001',:rset);
SQL> print rset;
-----------------------------------------------------------------------------------------------------------------------
原来的SQL是这个样子
  1  select b.rssc_name as rssc,d.labor_no as type ,count(*) as num ,floor(c.repair_date-e.startdate) as xday
  2  from tm_sst a,tm_rssc b,tt_activity_vehicle c,ti_workitem_detail d,tm_recall_activity e
  3  where c.operate_sst_code=a.sst_code and a.rssc_id=b.rssc_id
  4  and e.recall_activity_id=c.recall_activity_id
  5  and e.activity_code='L001'
  6  and d.labor_no in ('MFJC0000','WXBY0000','WXBY1000','JCWB0000','JWBL0000','LP000000','JCDQ0000') and c.operate_sst_code=d.sst_code and c.bill_no=d.bill_no
  7* group by b.rssc_name,(c.repair_date-e.startdate),d.labor_no order by b.rssc_name,xday
SQL> /
辽宁分销中心   MFJC0000                  1          2
辽宁分销中心   JCDQ0000                  1         38
辽宁分销中心   MFJC0000                  1         38
 
前两列不说了,第三列是数量,第四列是距离开始的天数(用来定位第三列应该显示的列的位置,比如第四列是38,则第三列的1应该在第38列处(不算前两列))
 
---------------------------------------------------------------------------------------------------------------------------------
最后拼出的SQL是这个样子
select b.rssc_name as rssc,d.labor_no as type
,decode(floor(c.repair_date-e.startdate),1,count(*),0),decode(floor(c.repair_date-e.startdate),2,count(*),0),
decode(floor(c.repair_date-e.startdate),3,count(*)),decode(floor(c.repair_date-e.startdate),4,count(*)),
decode(floor(c.repair_date-e.startdate),5,count(*)),decode(floor(c.repair_date-e.startdate),6,count(*)),
decode(floor(c.repair_date-e.startdate),7,count(*)),decode(floor(c.repair_date-e.startdate),8,count(*)),
decode(floor(c.repair_date-e.startdate),9,count(*)),decode(floor(c.repair_date-e.startdate),10,count(*)),
decode(floor(c.repair_date-e.startdate),11,count(*)),decode(floor(c.repair_date-e.startdate),12,count(*)),
decode(floor(c.repair_date-e.startdate),13,count(*)),decode(floor(c.repair_date-e.startdate),14,count(*)),
decode(floor(c.repair_date-e.startdate),15,count(*)),decode(floor(c.repair_date-e.startdate),16,count(*)),
decode(floor(c.repair_date-e.startdate),17,count(*)),decode(floor(c.repair_date-e.startdate),18,count(*)),
decode(floor(c.repair_date-e.startdate),19,count(*)),decode(floor(c.repair_date-e.startdate),20,count(*)),
decode(floor(c.repair_date-e.startdate),21,count(*)),decode(floor(c.repair_date-e.startdate),22,count(*)),
decode(floor(c.repair_date-e.startdate),23,count(*)),decode(floor(c.repair_date-e.startdate),24,count(*)),
decode(floor(c.repair_date-e.startdate),25,count(*)),decode(floor(c.repair_date-e.startdate),26,count(*)),
decode(floor(c.repair_date-e.startdate),27,count(*)),decode(floor(c.repair_date-e.startdate),28,count(*)),
decode(floor(c.repair_date-e.startdate),29,count(*)),decode(floor(c.repair_date-e.startdate),30,count(*)),
decode(floor(c.repair_date-e.startdate),31,count(*)),decode(floor(c.repair_date-e.startdate),32,count(*)),
decode(floor(c.repair_date-e.startdate),33,count(*)),decode(floor(c.repair_date-e.startdate),34,count(*)),
decode(floor(c.repair_date-e.startdate),35,count(*)),decode(floor(c.repair_date-e.startdate),36,count(*)),
decode(floor(c.repair_date-e.startdate),37,count(*)),decode(floor(c.repair_date-e.startdate),38,count(*))
 from  tm_sst a,tm_rssc b,tt_activity_vehicle c,ti_workitem_detail
d,tm_recall_activity e
where c.operate_sst_code=a.sst_code
and a.rssc_id=b.rssc_id
and e.recall_activity_id=c.recall_activity_id
and
e.activity_code='L001'
and d.labor_no in
('MFJC0000','WXBY0000','WXBY1000','JCWB0000','JWBL0000','LP000000','JCDQ0000')
and c.operate_sst_code=d.sst_code and c.bill_no=d.bill_no
group by b.rssc_name,(c.repair_date-e.startdate),d.labor_no order by
b.rssc_name,d.labor_no,floor(c.repair_date-e.startdate);
 
----------------------------------------------------------------------------------------------------------------------------
结果是
第一行
辽宁分销中心
JCDQ0000         0
0
0
0
0
0
0
0
0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 1
第二行
辽宁分销中心
MFJC0000         0
1
0
0
0
0
0
0
0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 0
 
直接COPY的结果,没有修改,大家看起来可能困难些,见量吧。里面SQL也没修改,以后有时间再写个明白的吧
 
 
=======================================================
类似

CREATE OR REPLACE  PACKAGE PKG_JCCTEST1                          
AS

  type rc_class is ref cursor;

。。。。。。。。。。。。。。

procedure GetSubAndSum2(p1 number,p2  number ,
              ResultCursor out rc_class);

程序调用'{call PKG_JCCTEST1.GetSubAndSum2(?,?)}'
==========================================================
以下是COPY别人JAVA的脚本。

CREATE OR REPLACE PACKAGE TESTPACKAGE  AS

 TYPE Test_CURSOR IS REF CURSOR;

end TESTPACKAGE;

 

CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR) IS

BEGIN

    OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;

END TESTC;

 

package com.hyq.src;

import java.sql.*;

import java.io.OutputStream;

import java.io.Writer;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import oracle.jdbc.driver.*;

 

 

public class TestProcedureTHREE {

  public TestProcedureTHREE() {

  }

  public static void main(String[] args ){

    String driver = "oracle.jdbc.driver.OracleDriver";

    String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";

    Statement stmt = null;

    ResultSet rs = null;

    Connection conn = null;

 

    try {

      Class.forName(driver);

      conn =  DriverManager.getConnection(strUrl, "hyq", "hyq");

 

      CallableStatement proc = null;

      proc = conn.prepareCall("{ call hyq.testc(?) }");

      proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);

      proc.execute();

      rs = (ResultSet)proc.getObject(1);

 

      while(rs.next())

      {

          System.out.println("<tr><td>" + rs.getString(1) + "</td><td>"+rs.getString(2)+"</td></tr>");

      }

    }

    catch (SQLException ex2) {

      ex2.printStackTrace();

    }

    catch (Exception ex2) {

      ex2.printStackTrace();

    }

    finally{

      try {

        if(rs != null){

          rs.close();

          if(stmt!=null){

            stmt.close();

          }

          if(conn!=null){

            conn.close();

          }

        }

      }

      catch (SQLException ex1) {

      }

    }

  }

}

在这里要注意,在执行前一定要先把oracle的驱动包放到class路径里,否则会报错的。

 

Feed

The owner hasn't specified a feed for this module yet.
No list items have been added yet.
No list items have been added yet.
There are no photo albums.