2007 年 08 月 28日, 星期二

Ie和firefox的Js区别(转载)

1. 对象问题
1.1 Form
对象 现有问题:现有代码这获得form对象通过document.forms("formName"),这样使用在IE 能接受,MF 不能。解决方法改用 作为下标运算。改为document.forms["formName"]备注上述的改用 作为下标运算中的formNameidname

1.2 HTML
对象 现有问题: IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 MF 中不能。
document.all("itemName")
或者document.all("itemId")解决方法:使用对象ID作为对象变量名
document.getElementById("itemId")
备注
document.all
IE自定义的方法,所以请大家尽量不使用。还有一种方式,在IEMF都可以使用
var f = document.forms["formName "];
var o = f. itemId;
 查看全文
wj99898 发表于:2007.08.28 09:36 ::分类: ( oracle专区 ) ::阅读:(400次) :: 评论 (0) :: 引用 (0)

2007 年 08 月 23日, 星期四

div层被select下拉框遮盖

经测试解决代码仅在IE浏览器有效。

由于层与下拉框之间的优先级是:下拉框 > 层,因此在显示的时候,会因为优先级的次序而会出现div层被select下拉框遮盖的问题。(如果几个元素都是层的话,我们可以通过层的 z-index 属性来设置)解决办法就是:给层中放一个优先级比下拉框更高的元素(iframe),从而解决此问题!具体解决代码如下:

<div style="position:absolute; visibility:hidden; top:20px; left:20px; width:100px; height:200px; background-color:#6699cc;">
<table>
<tr><td>item 1</td></tr>
<tr><td>item 2</td></tr>
<tr><td>item 3</td></tr>
<tr><td>item 4</td></tr>
<tr><td>item 5</td></tr>
</table>
<iframe src="javascript:false" style="position:absolute; visibility:inherit; top:0px; left:0px; width:100px; height:200px; z-index:-1; filter='progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';"></iframe>
</div>


wj99898 发表于:2007.08.23 17:51 ::分类: ( oracle专区 ) ::阅读:(136次) :: 评论 (0) :: 引用 (0)

2007 年 04 月 30日, 星期一

在TOOL菜單添加命令

1Program Units中添加包app_special_control,然後在包中添加過程special15,過程代碼如下:

PROCEDURE special15 IS

BEGIN

execute_trigger('QUERY_FIND'); --可以是其它trigger

END special15;

2 FORM 級別新建一下trigger名為SPECIAL15,代碼如下:

app_special_control.special15;

3 FORM 級別的PRE_FORM中加入如下代碼:

app_special.instantiate('SPECIAL15', 'Query Finding..');

其中SPECIAL15triggerQuery Finding..為工具菜單的的命令名。


wj99898 发表于:2007.04.30 10:21 ::分类: ( oracle专区 ) ::阅读:(253次) :: 评论 (0) :: 引用 (0)

2007 年 04 月 29日, 星期日

Form Folder的实现

一新建Form(復制Template.fmb)

1、添加Form Objects(包括WINDOWCANVASBLOCK)(這裡都取名MY_FOLDER

2、修改TriggerProgram Units

Form Level Trigger: PRE-FORM

Program Units:APP_CUSTOM

3、修改其他属性设置

FormConsole Window

FormFirst Navigation Data Block

WindowPrimary Canvas

二、添加Folder相关的Objects

APPSTAND.FMB Object Groups STANDARD_FOLDER

及其相关的对象移至我们自己客制的Form为我们所用。

 查看全文
wj99898 发表于:2007.04.29 15:08 ::分类: ( oracle专区 ) ::阅读:(507次) :: 评论 (0) :: 引用 (0)

2007 年 04 月 27日, 星期五

oracle 表注冊

begin
AD_DD.REGISTER_TABLE ('APP_SHORT_NAME','TAB_NAME','T');

AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','USER_ID', 1, 'NUMBER', 15, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','LINE_ID', 2, 'NUMBER', 15, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','MONEY', 3, 'NUMBER', 50, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','CURRENCY', 4, 'VARCHAR2', 50, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE_CATEGORY', 5, 'VARCHAR2', 40, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE1', 6, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE2', 7, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE3', 8, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE4', 9, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE5', 10, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE6', 11, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE7', 12, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE8', 13, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE9', 14, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE10', 15, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE11', 16, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE12', 17, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE13', 18, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE14', 19, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','ATTRIBUTE15', 20, 'VARCHAR2', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','CREATED_BY', 21, 'NUMBER', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','CREATION_DATE', 22, 'DATE', 9, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','LAST_UPDATED_BY', 23, 'NUMBER', 150, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','LAST_UPDATE_DATE', 24, 'DATE', 9, 'Y', 'N');
AD_DD.REGISTER_COLUMN ('APP_SHORT_NAME', 'TAB_NAME','LAST_UPDATE_LOGIN', 25, 'NUMBER',150 , 'Y', 'N');

commit;
end;


wj99898 发表于:2007.04.27 08:36 ::分类: ( oracle专区 ) ::阅读:(241次) :: 评论 (0) :: 引用 (0)

2007 年 04 月 18日, 星期三

Report Builder 內置包

1 SRW.BREAK:臨時中斷報表的執行,並顯示當前所有列值和參數值,顯示完後,可從中斷點恢復報表咝小?/span>

語法:SRW.BREAK;

2 SRW.DO_SQL:用於在Report Builder中執行指定的SQL語句。

語法:SRW.DO_SQLSQLˍSTATEMENT CHAR;

3 SRW.MESSAGE:用於顯示一條信息,該信息由用戶指定的信息代碼和文本組成。

語法:SRW.MESSAGEMSGˍMUMBER NUMBERMSGˍTEST CHAR);

 查看全文
wj99898 发表于:2007.04.18 09:01 ::分类: ( oracle专区 ) ::阅读:(366次) :: 评论 (0) :: 引用 (0)

2007 年 04 月 16日, 星期一

求出當前日期所有的一個月中的所有星期五的時間(原創)

DECLARE
v_date DATE ;--日期
vv_date date;
v_count NUMBER:=0; --當前月的天數
v_num varchar2(10);--用天存放一周中的天數
BEGIN
v_date := SYSDATE; --將日期傳進來
vv_date := last_day(add_months(v_date, -1)); --算出這個日期所在當月的第一天

--判斷這個月有多少天
IF to_char(SYSDATE, 'mm') IN ('01', '03', '05', '07', '08', '10', '12') THEN
v_count := 31;
ELSIF to_char(SYSDATE, 'mm') = '02' THEN
IF MOD(to_char(SYSDATE, 'yyyy'), 4) = 0 THEN
v_count := 29;
ELSE
v_count := 28;
END IF;
ELSE
v_count := 30;
END IF;

--查找是星期五的時間,如是將其顯示出來
FOR v_nu IN 1 .. v_count LOOP
SELECT to_char(vv_date + v_nu, 'd') INTO v_num FROM dual;
IF v_num = '6' THEN
dbms_output.put_line(vv_date + v_nu);
END IF;
END LOOP;
END;
wj99898 发表于:2007.04.16 17:34 ::分类: ( oracle专区 ) ::阅读:(946次) :: 评论 (0) :: 引用 (0)

2007 年 03 月 07日, 星期三

Form Trigger Execution Sequence (转)

Action                 Trigger Firing Order                    Level
------                 --------------------                    -----
Runform                 1.  Pre-Logon                          Form
                        2.  On-Logon                           Form
                        3.  Post-Logon                         Form
                        4.  Pre-Form                           Form
                        5.  When-Create-Record                 Block
                        6.  Pre-Block                          Block
                        7.  Pre-Record                         Block
                        8.  Pre-Text-Item                      Item
                        9.  When-New-Form-Instance             Form
                        10. When-New-Block-Instance            Block
                        11. When-New-Record-Instance           Block
                        12. When-New-Item-Instance             Item
***********
 查看全文
wj99898 发表于:2007.03.07 15:04 ::分类: ( oracle专区 ) ::阅读:(243次) :: 评论 (0) :: 引用 (0)

2007 年 03 月 05日, 星期一

table()函数用法(转载)

利用table()函数,我们可以将PL/SQL返回的结果集代替table。

1、table()结合数组:create or replace type t_test as object(
id integer,
rq date,
mc varchar2(60)
);

create or replace type t_test_table as table of t_test;

create or replace function f_test_array(n in number default null) return t_test_table
as
v_test t_test_table := t_test_table();
begin
for i in 1 .. nvl(n,100) loop
v_test.extend();
v_test(v_test.count) := t_test(i,sysdate,'mc'||i);
end loop;
return v_test;
end f_test_array;
/

select * from table(f_test_array(10));


2、table()结合PIPELINED函数:

create or replace function f_test_pipe(n in number default null) return t_test_table PIPELINED
as
v_test t_test_table := t_test_table();
begin
for i in 1 .. nvl(n,100) loop
pipe row(t_test(i,sysdate,'mc'||i));
end loop;
return;
end f_test_pipe;
/

select * from table(f_test_pipe(20));

3、table()结合系统包:

create table test (id varchar2(20));
insert into test values('1');
commit;
explain plan for select * from test;
select * from table(dbms_xplan.display);


wj99898 发表于:2007.03.05 10:37 ::分类: ( oracle专区 ) ::阅读:(332次) :: 评论 (0) :: 引用 (0)

2007 年 03 月 01日, 星期四

ESCAPE用法

1.使用 ESCAPE 关键字定义转义符。在模式中,当转义符置于通配符之前时,该通配符就解释为普通字符。

2.ESCAPE 'escape_character'
允许在字符串中搜索通配符而不是将其作为通配符使用。escape_character 是放在通配符前表示此特殊用途的字符。
select * from a WHERE name LIKE '%/%ab' ESCAPE '/'


结果为:
name
----------
11%ab
12%ab

 查看全文

wj99898 发表于:2007.03.01 15:38 ::分类: ( oracle专区 ) ::阅读:(997次) :: 评论 (0) :: 引用 (0)

部分列为空的排序问题

order by A.X desc nulls first

null值排在最前面,其他数值升序排列,使用关键字:desc nulls first

null值排在最前面,其他数值降序排列,使用关键字:asc nulls first 查看全文
wj99898 发表于:2007.03.01 08:55 ::分类: ( oracle专区 ) ::阅读:(302次) :: 评论 (0) :: 引用 (0)

2007 年 02 月 28日, 星期三

在form中如何提示更改组织

增加Choose ORG功能:
(1):首先在parameter中加上CHART_OF_ACCOUNTS_ID,ORG_NAME,ORG_CODE,ORG_ID四个参数
(2):在form level 的trigger中的pre—form中加上FND_ORG.CHOOSE_ORG;
(3):在form level 的trigger中的when—new—form—instance中加上
APP_WINDOW.SET_TITLE('ADJ_RECEIVE',:PARAMETER.ORG_CODE);其中ADJ_RECEIVE是window 的名字,用于设置window的title

 查看全文
wj99898 发表于:2007.02.28 10:50 ::分类: ( oracle专区 ) ::阅读:(284次) :: 评论 (0) :: 引用 (0)

2007 年 02 月 02日, 星期五

去掉字符串中逗号间重复的字符,并按升序排列

FUNCTION getTESTCOUNT(acc_str IN VARCHAR2) RETURN VARCHAR2 IS
v_string VARCHAR2(1000);
v_count NUMBER;
TYPE test_value IS TABLE OF CHAR(4) INDEX BY PLS_INTEGER;
v_test_value test_value;
v_value VARCHAR2(10);
BEGIN
SELECT col
INTO v_string
FROM ( --将字符串中的所有序号进行过滤,使没用重复
SELECT sys_connect_by_path(col, ',') || ',' col, LEVEL
FROM (SELECT col, row_number() over(ORDER BY col) rn
FROM (SELECT DISTINCT substr(col,
instr(col, ',', 1, rownum) + 1,
instr(col, ',', 1, rownum + 1) -
instr(col, ',', 1, rownum) - 1) col
FROM (SELECT acc_str col FROM dual)
CONNECT BY rownum <
length(translate(col, ',' || col, ','))))
CONNECT BY PRIOR rn = rn - 1
ORDER BY LEVEL DESC)
WHERE rownum = 1;
v_count := lengthb(translate(v_string, ',' || v_string, '~')) - 1; --求出字符串中逗号的个数
FOR v_cur IN 1 .. v_count LOOP
--将字符串中的序号取出,分别数组v_test_value
v_test_value(v_cur) := substr(v_string, 2, instr(v_string, ',', 1, 2) - 2);
v_string := substr(v_string,
instr(v_string, ',', 1, 2),
(length(v_string) + 1 - instr(v_string, ',', 1, 2)));
END LOOP;
v_value := NULL;
FOR r_cur IN 1 .. v_count - 1 LOOP
--将数组v_test_value从小到大排序
FOR t_vur IN r_cur + 1 .. v_count LOOP
IF to_number(TRIM(v_test_value(r_cur))) >
to_number(TRIM(v_test_value(t_vur))) THEN
v_value := v_test_value(r_cur);
v_test_value(r_cur) := v_test_value(t_vur);
v_test_value(t_vur) := v_value;
END IF;

END LOOP;

END LOOP;
v_string := ',';
FOR v_cur IN 1 .. v_Count LOOP
--将排序好的数组重新变为字符串不过之间用逗号隔开
v_string := v_string || TRIM(v_test_value(v_cur)) || ',';
END LOOP;
RETURN TRIM(v_string);
END getTESTCOUNT;


wj99898 发表于:2007.02.02 11:10 ::分类: ( oracle专区 ) ::阅读:(2332次) :: 评论 (0) :: 引用 (0)

2007 年 02 月 01日, 星期四

Connect by 使用方法

connect by prior start with 经常会被用到一个表中存在递归关系的时候。比如我们经常会将一个比较复杂的目录树存储到一个表中。或者将一些部门存储到一个表中,而这些部门互相有隶属关系。这个时候你就会用到connect by prior start with。

例:
SELECT LEVEL || SYS_CONNECT_BY_PATH(a.empno, '->') RESULT
FROM scott.emp a
CONNECT BY a.empno = PRIOR a.mgr
START WITH a.empno = 7369;

SYS_CONNECT_BY_PATH即在相应字段前加'->'符号,LEVEL是级别

结果:

RESULT
11->7369
22->7369->7902
33->7369->7902->7566
44->7369->7902->7566->7839


wj99898 发表于:2007.02.01 09:23 ::分类: ( oracle专区 ) ::阅读:(307次) :: 评论 (0) :: 引用 (0)

2007 年 01 月 31日, 星期三

数字转英文(含小数)函数(转载)

CREATE OR REPLACE FUNCTION Number_To_English(num_to_en NUMBER)RETURN VARCHAR2
IS

temp_ VARCHAR2(100);
integral_ NUMBER;
decimal_ NUMBER;
en_number_ VARCHAR2(100);

BEGIN
temp_ := to_char(num_to_en,'9999999d99'); --- 如果不格式化,123.20 会在转换中自动变成123.2 从而把 twenty cents 翻译成 two

IF instr(num_to_en,'.') = 0 THEN --- 判断是否为整数
SELECT UPPER(to_char(to_date(num_to_en,'J'),'Jsp'))INTO temp_
FROM dual;
ELSE --- 是小数则进行如下转换
integral_ := trunc(num_to_en);
v_num :=length(temp_)-substr(temp_,instr(temp_,'.');
decimal_ := to_number(substr(temp_,instr(temp_,'.')+1,v_num));
SELECT UPPER(to_char(to_date(integral_,'J'),'Jsp')|| ' AND CENTS '||to_char(to_date(decimal_,'J'),'Jsp')) INTO temp_
FROM dual;


END IF;

RETURN temp_;

END Number_To_English;

wj99898 发表于:2007.01.31 08:58 ::分类: ( oracle专区 ) ::阅读:(12930次) :: 评论 (0) :: 引用 (0)

2006 年 12 月 25日, 星期一

用Oracle闪回功能恢复偶然丢失的数据

人为的错误是数据库系统失败的重要原因之一,根据调查约40%的系统问题是操作失误或者用户错误引起的,这些人为的错误又特别难以避免。传统上当发生数据丢失、数据错误问题时,解决的主要方法就是数据的导入/导出、备份/恢复技术。这些方法都需要发生数据错误之前有一个正确的备份,才能进行恢复。恢复时不取决于错误程度,而只取决于备份/恢复策略。这种方法既耗时又使数据库系统不能提供服务,对于一些用户偶然地删除数据这类小错误来说显得有些"大材小用"。那么如何来恢复这种偶然的错误操作造成的数据丢失呢?从Oracle 9i开始提供了基于回滚段的闪回查询(Flashback Query)功能,可用于恢复错误的DML操作。在Oracle 10g中对闪回查询做了较大改进,不再局限于闪回查询,还可用于恢复错误的DDL(Drop)操作、闪回表、闪回数据库等。 查看全文
wj99898 发表于:2006.12.25 11:57 ::分类: ( oracle专区 ) ::阅读:(304次) :: 评论 (0) :: 引用 (0)

2006 年 11 月 30日, 星期四

关于PL/SQL报表链接问题:

报表链接分两种,一种锚点链接,一种是跨报表链接

锚点链接:

起始:<a href="#' ||链接属性|| '">' ||'链接描述' ||'</a>

终止:<a name="' ||链接属性|| '">' ||'链接描述'||'</a>'

跨报表链接:

1通过去时 SELECT fnd_profile.VALUE('apps_web_agent') into rout FROM dual;

找到EBS的根目录,赋给变量rout

2在程序包中建立要链接到报表的存储过程,注要加入

IF NOT icx_sec.validatesession THEN
RETURN;
END IF;

限制安全性,这样就算知道网址没有权限也不能打开网页

3起始:'<a href="' || v_rout ||'/程序包.存储过程?p_item_id=' ||过程参数1||'&p_schedule=' ||过程参数2|| '">'||'链接描述' ||'</a>'


wj99898 发表于:2006.11.30 14:59 ::分类: ( oracle专区 ) ::阅读:(344次) :: 评论 (0) :: 引用 (0)

2006 年 11 月 22日, 星期三

FORM中常用控件对应的子类信息

文本项 TEXT_ITEM
显示项 DISPLAY_ITEM
列表项 LIST
复选框 CHECKBOX
单选组 RADIO_GROUP
按钮项 BUTTON
画布 CANVAS
窗口 WINDOW
块 BLOCK
弹性域 TEXT_ITEM_DESC_FLEX
当前记录开始项 CURRENT_RECORD_INDICATOR
只显示文本项 TEXT_ITEM_DISPLAY_ONLY
时间文本项 TEXT_ITEM_DATE


wj99898 发表于:2006.11.22 09:07 ::分类: ( oracle专区 ) ::阅读:(561次) :: 评论 (0) :: 引用 (0)

2006 年 11 月 05日, 星期日

OACLE SQL性能优化

1、用EXISTS替代IN,NOT EXISTS替代NOT IN: 在子查询中,NOT 在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率.

SELECT *
FROM EMP (基础表)
WHERE EMPNO > 0
AND EXISTS (SELECT ‘X'
FROM DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
AND LOC = ‘MELB')

2、用Where子句替换HAVING子句:
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销.
例如:
低效:
SELECT REGION,AVG(LOG_SIZE)
FROM LOCATION
GROUP BY REGION
HAVING REGION REGION != ‘SYDNEY'
AND REGION != ‘PERTH'
高效
SELECT REGION,AVG(LOG_SIZE)
FROM LOCATION
WHERE REGION REGION != ‘SYDNEY'
AND REGION != ‘PERTH'
GROUP BY REGION

 查看全文
wj99898 发表于:2006.11.05 09:21 ::分类: ( oracle专区 ) ::阅读:(477次) :: 评论 (0) :: 引用 (0)

2006 年 11 月 02日, 星期四

怎么在Oracle中发邮件

/*---------------------------------------------------------------
Rcpter in varchar2 接收者邮箱
Mail_Content in Varchar2 邮件内容
desc: 发送邮件到指定邮箱
只能指定一个邮箱,如果需要发送到多个邮箱,需要另外的辅助程序
-----------------------------------------------------------------*/
CREATE OR REPLACE PROCEDURE sp_send_mail(

rcpter IN VARCHAR2

, mail_content IN VARCHAR2)

IS
conn utl_smtp.connection;
--write title
PROCEDURE send_header(NAME IN VARCHAR2,
HEADER IN VARCHAR2) AS
BEGIN
utl_smtp.write_data(conn, NAME || ': ' || HEADER || utl_tcp.CRLF);
END;
BEGIN
--opne connect
conn := utl_smtp.open_connection('smtp.com');
utl_smtp.helo(conn, 'oracle');
utl_smtp.mail(conn, 'oracle info');
utl_smtp.rcpt(conn, Rcpter);
utl_smtp.open_data(conn);
--write title
send_header('From', 'Oracle Database');
send_header('To', '"Recipient" <' || rcpter || '>');
send_header('Subject', 'DB Info');
--write mail content
utl_smtp.write_data(conn, utl_tcp.crlf || mail_content);
--close connect
utl_smtp.close_data(conn);
utl_smtp.quit(conn);
EXCEPTION
WHEN utl_smtp.transient_error OR utl_smtp.permanent_error THEN
BEGIN
utl_smtp.quit(conn);
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
WHEN OTHERS THEN
NULL;
END sp_send_mail;


wj99898 发表于:2006.11.02 14:06 ::分类: ( oracle专区 ) ::阅读:(317次) :: 评论 (0) :: 引用 (0)

怎么样把相邻记录合并到一条记录

8i以上版本,分析函数lag与lead可以提取后一条或前一天记录到本记录。

如:SELECT a.deptno, a.empno, a.hiredate
FROM scott.emp a ORDER BY a.deptno, a.empno;

DEPTNOEMPNOHIREDATE
1077821981-6-9
1078391981-11-17
1079341982-1-23
2073691980-12-17
2075661981-4-2
2077881982-12-9
2078761983-1-12
2079021981-12-3
3074991981-2-20
3075211981-2-22
3076541981-9-28
3076981981-5-1
3078441981-9-8
3079001981-12-3

合并:
SELECT a.deptno, a.empno, a.hiredate,lag(a.hiredate,1,Null) over (Partition By a.deptno order By a.hiredate,a.ename) "merge"
FROM scott.emp a ORDER BY a.deptno, a.empno;

DEPTNOEMPNOHIREDATEmerge
1077821981-6-9 
1078391981-11-171981-6-9
1079341982-1-231981-11-17
2073691980-12-17 
2075661981-4-21980-12-17
2077881982-12-91981-12-3
2078761983-1-121982-12-9
2079021981-12-31981-4-2
3074991981-2-20 
3075211981-2-221981-2-20
3076541981-9-281981-9-8
3076981981-5-11981-2-22
3078441981-9-81981-5-1
3079001981-12-31981-9-28


wj99898 发表于:2006.11.02 13:41 ::分类: ( oracle专区 ) ::阅读:(268次) :: 评论 (0) :: 引用 (0)

十进制与十六进制的转换

8i以上版本:

十进制-->十六进制
select to_char(100,'XX') from dual;

十六进制-->十进制
select to_number('4D','XX') from dual;


wj99898 发表于:2006.11.02 11:23 ::分类: ( oracle专区 ) ::阅读:(449次) :: 评论 (0) :: 引用 (0)

2006 年 11 月 01日, 星期三

在b/s开发中经常用到的javaScript技术

一、验证类
1、数字验证内
1.1 整数
1.2 大于0的整数 (用于传来的ID的验证)
1.3 负整数的验证
1.4 整数不能大于iMax
1.5 整数不能小于iMin
2、时间类
2.1 短时间,形如 (13:04:06)
2.2 短日期,形如 (2003-12-05)
2.3 长时间,形如 (2003-12-05 13:04:06)
2.4 只有年和月。形如(2003-05,或者2003-5)
2.5 只有小时和分钟,形如(12:03)
3、表单类
3.1 所有的表单的值都不能为空
3.2 多行文本框的值不能为空。
3.3 多行文本框的值不能超过sMaxStrleng
3.4 多行文本框的值不能少于sMixStrleng
3.5 判断单选框是否选择。
3.6 判断复选框是否选择.
3.7 复选框的全选,多选,全不选,反选
3.8 文件上传过程中判断文件类型
4、字符类
4.1 判断字符全部由a-Z或者是A-Z的字字母组成
4.2 判断字符由字母和数字组成。
4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
4.4 字符串替换函数.Replace();
5、浏览器类
5.1 判断浏览器的类型
5.2 判断ie的版本
5.3 判断客户端的分辨率

6、结合类
6.1 email的判断。
6.2 手机号码的验证
6.3 身份证的验证

二、功能类

1、时间与相关控件类
1.1 日历
1.2 时间控件
1.3 万年历
1.4 显示动态显示时钟效果(文本,如OA中时间)
1.5 显示动态显示时钟效果 (图像,像手表)
2、表单类
2.1 自动生成表单
2.2 动态添加,修改,删除下拉框中的元素
2.3 可以输入内容的下拉框
2.4 多行文本框中只能输入iMax文字。如果多输入了,自动减少到iMax个文字(多用于短信发送)

3、打印类
3.1 打印控件
4、事件类
4.1 屏蔽右键
4.2 屏蔽所有功能键
4.3 --> 和<-- F5 F11,F9,F1
4.4 屏蔽组合键ctrl+N
5、网页设计类
5.1 连续滚动的文字,图片(注意是连续的,两段文字和图片中没有空白出现)
5.2 html编辑控件类
5.3 颜色选取框控件
5.4 下拉菜单
5.5 两层或多层次的下拉菜单
5.6 仿IE菜单的按钮。(效果如rongshuxa.com的导航栏目)
5.7 状态栏,title栏的动态效果(例子很多,可以研究一下)
5.8 双击后,网页自动滚屏
6、树型结构。
6.1 asp+SQL版
6.2 asp+xml+sql版
6.3 java+sql或者java+sql+xml
7、无边框效果的制作
8、连动下拉框技术
9、文本排序


一、验证类
1、数字验证内
1.1 整数
/^(-|+)?d+$/.test(str)
1.2 大于0的整数 (用于传来的ID的验证)
/^d+$/.test(str)
1.3 负整数的验证
/^-d+$/.test(str)
2、时间类
2.1 短时间,形如 (13:04:06)
function isTime(str)
{
var a = str.match(/^(d{1,2})(:)?(d{1,2})2(d{1,2})$/);
if (a == null) {alert('输入的参数不是时间格式'); return false;}
if (a[1]>24 || a[3]>60 || a[4]>60)
{
alert("时间格式不对");
return false
}
return true;
}
2.2 短日期,形如 (2003-12-05)
function strDateTime(str)
{
var r = str.match(/^(d{1,4})(-|/)(d{1,2})2(d{1,2})$/);
if(r==null)return false;
var d= new Date(r[1], r[3]-1, r[4]);
return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]);
}
2.3 长时间,形如 (2003-12-05 13:04:06)
function strDateTime(str)
{
var reg = /^(d{1,4})(-|/)(d{1,2})2(d{1,2}) (d{1,2}):(d{1,2}):(d{1,2})$/;
var r = str.match(reg);
if(r==null)return false;
var d= new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]);
return (d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]);
}
2.4 只有年和月。形如(2003-05,或者2003-5)
2.5 只有小时和分钟,形如(12:03)
3、表单类
3.1 所有的表单的值都不能为空
<input onblur="if(this.value.replace(/^s+|s+$/g,'')=='')alert('不能为空!')">
3.2 多行文本框的值不能为空。
3.3 多行文本框的值不能超过sMaxStrleng
3.4 多行文本框的值不能少于sMixStrleng
3.5 判断单选框是否选择。
3.6 判断复选框是否选择.
3.7 复选框的全选,多选,全不选,反选
3.8 文件上传过程中判断文件类型
4、字符类
4.1 判断字符全部由a-Z或者是A-Z的字字母组成
<input onblur="if(/[^a-zA-Z]/g.test(this.value))alert('有错')">
4.2 判断字符由字母和数字组成。
<input onblur="if(/[^0-9a-zA-Z]/g.test(this.value))alert('有错')">
4.3 判断字符由字母和数字,下划线,点号组成.且开头的只能是下划线和字母
/^([a-zA-z_]{1})([w]*)$/g.test(str)
4.4 字符串替换函数.Replace();
5、浏览器类
5.1 判断浏览器的类型
window.navigator.appName
5.2 判断ie的版本
window.navigator.appVersion
5.3 判断客户端的分辨率
window.screen.height; window.screen.width;

6、结合类
6.1 email的判断。
function ismail(mail)
{
return(new RegExp(/^w+((-w+)|(.w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$/).test(mail));
}
6.2 手机号码的验证
6.3 身份证的验证
function isIdCardNo(num)
{
if (isNaN(num)) {alert("输入的不是数字!"); return false;}
var len = num.length, re;
if (len == 15)
re = new RegExp(/^(d{6})()?(d{2})(d{2})(d{2})(d{3})$/);
else if (len == 18)
re = new RegExp(/^(d{6})()?(d{4})(d{2})(d{2})(d{3})(d)$/);
else {alert("输入的数字位数不对!"); return false;}
var a = num.match(re);
if (a != null)
{
if (len==15)
{
var D = new Date("19"+a[3]+"/"+a[4]+"/"+a[5]);
var B = D.getYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
}
else
{
var D = new Date(a[3]+"/"+a[4]+"/"+a[5]);
var B = D.getFullYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5];
}
if (!B) {alert("输入的身份证号 "+ a[0] +" 里出生日期不对!"); return false;}
}
return true;
}

3.7 复选框的全选,多选,全不选,反选
<form name=hrong>
<input type=checkbox name=All onclick="checkAll('mm')">全选<br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/>
<input type=checkbox name=mm onclick="checkItem('All')"><br/><br/>


<input type=checkbox name=All2 onclick="checkAll('mm2')">全选<br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>
<input type=checkbox name=mm2 onclick="checkItem('All2')"><br/>

</form>

<SCRIPT LANGUAGE="javascript">
function checkAll(str)
{
var a = document.getElementsByName(str);
var n = a.length;
for (var i=0; i<n; i++)
a[i].checked = window.event.srcElement.checked;
}
function checkItem(str)
{
var e = window.event.srcElement;
var all = eval("document.hrong."+ str);
if (e.checked)
{
var a = document.getElementsByName(e.name);
all.checked = true;
for (var i=0; i<a.length; i++)
{
if (!a[i].checked){ all.checked = false; break;}
}
}
else all.checked = false;
}
</SCRIPT>

3.8 文件上传过程中判断文件类型
<input type=file onchange="alert(this.value.match(/^(.*)(.)(.{1,8})$/)[3])">

画图:
<OBJECT
id=S
style="LEFT: 0px; WIDTH: 392px; TOP: 0px; HEIGHT: 240px"
height=240
width=392
classid="clsid:369303C2-D7AC-11D0-89D5-00A0C90833E6">
</OBJECT>
<SCRIPT>
S.DrawingSurface.ArcDegrees(0,0,0,30,50,60);
S.DrawingSurface.ArcRadians(30,0,0,30,50,60);
S.DrawingSurface.Line(10,10,100,100);
</SCRIPT>

写注册表:
<SCRIPT>
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.RegWrite ("HKCUSoftwareACMEFortuneTeller", 1, "REG_BINARY");
WshShell.RegWrite ("HKCUSoftwareACMEFortuneTellerMindReader", "Goocher!", "REG_SZ");
var bKey = WshShell.RegRead ("HKCUSoftwareACMEFortuneTeller");
WScript.Echo (WshShell.RegRead ("HKCUSoftwareACMEFortuneTellerMindReader"));
WshShell.RegDelete ("HKCUSoftwareACMEFortuneTellerMindReader");
WshShell.RegDelete ("HKCUSoftwareACMEFortuneTeller");
WshShell.RegDelete ("HKCUSoftwareACME");
</SCRIPT>

TABLAE相关(客户端动态增加行列)
<HTML>
<SCRIPT LANGUAGE="JScript">
function numberCells() {
var count=0;
for (i=0; i < document.all.mytable.rows.length; i++) {
for (j=0; j < document.all.mytable.rows(i).cells.length; j++) {
document.all.mytable.rows(i).cells(j).innerText = count;
count++;
}
}
}
</SCRIPT>
<BODY onload="numberCells()">
<TABLE id=mytable border=1>
<TR><TH> </TH><TH> </TH><TH> </TH><TH> </TH></TR>
<TR><TD> </TD><TD> </TD><TD> </TD><TD> </TD></TR>
<TR><TD> </TD><TD> </TD><TD> </TD><TD> </TD></TR>
</TABLE>
</BODY>
</HTML>

1.身份证严格验证:

<script>
var aCity={11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外"}

function cidInfo(sId){
var iSum=0
var info=""
if(!/^d{17}(d|x)$/i.test(sId))return false;
sId=sId.replace(/x$/i,"a");
if(aCity[parseInt(sId.substr(0,2))]==null)return "Error:非法地区";
sBirthday=sId.substr(6,4)+"-"+Number(sId.substr(10,2))+"-"+Number(sId.substr(12,2));
var d=new Date(sBirthday.replace(/-/g,"/"))
if(sBirthday!=(d.getFullYear()+"-"+ (d.getMonth()+1) + "-" + d.getDate()))return "Error:非法生日";
for(var i = 17;i>=0;i --) iSum += (Math.pow(2,i) % 11) * parseInt(sId.charAt(17 - i),11)
if(iSum%11!=1)return "Error:非法证号";
return aCity[parseInt(sId.substr(0,2))]+","+sBirthday+","+(sId.substr(16,1)%2?"男":"女")
}

document.write(cidInfo("380524198002300016"),"<br/>");
document.write(cidInfo("340524198002300019"),"<br/>")
document.write(cidInfo("340524197711111111"),"<br/>")
document.write(cidInfo("34052419800101001x"),"<br/>");
</script>

2.验证IP地址
<SCRIPT LANGUAGE="javascript">
function isip(s){
var check=function(v){try{return (v<=255 && v>=0)}catch(x){return false}};
var re=s.split(".")
return (re.length==4)?(check(re[0]) && check(re[1]) && check(re[2]) && check(re[3])):false
}

var s="202.197.78.129";
alert(isip(s))
</SCRIPT>

3.加sp1后还能用的无边框窗口!!
<HTML XMLNS:IE>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<IE:Download ID="include" STYLE="behavior:url(#default#download)" />
<title>Chromeless Window</title>

<SCRIPT LANGUAGE="JScript">
/*--- Special Thanks For andot ---*/

/*
This following code are designed and writen by Windy_sk <seasonx@163.net>
You can use it freely, but u must held all the copyright items!
*/

/*--- Thanks For andot Again ---*/

var CW_width = 400;
var CW_height = 300;
var CW_top = 100;
var CW_left = 100;
var CW_url = "/";
var New_CW = window.createPopup();
var CW_Body = New_CW.document.body;
var content = "";
var CSStext = "margin:1px;color:black; border:2px outset;border-style:expression(onmouseout=onmouseup=function(){this.style.borderStyle='outset'}, onmousedown=function(){if(event.button!=2)this.style.borderStyle='inset'});background-color:buttonface;width:16px;height:14px;font-size:12px;line-height:11px;cursor:Default;";

//Build Window
include.startDownload(CW_url, function(source){content=source});

function insert_content(){
var temp = "";
CW_Body.style.overflow = "hidden";
CW_Body.style.backgroundColor = "white";
CW_Body.style.border = "solid black 1px";
content = content.replace(/<a ([^>]*)>/g,"<a onclick='parent.open(this.href);return false' $1>");
temp += "<table width=100% height=100% cellpadding=0 cellspacing=0 border=0>";
temp += "<tr style=';font-size:12px;background:#0099CC;height:20;cursor:default' ondblclick="Max.innerText=Max.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();" onmouseup='parent.drag_up(event)' onmousemove='parent.drag_move(event)' onmousedown='parent.drag_down(event)' onselectstart='return false' oncontextmenu='return false'>";
temp += "<td style='color:#ffffff;padding-left:5px'>Chromeless Window For IE6 SP1</td>";
temp += "<td style='color:#ffffff;padding-right:5px;' align=right>";
temp += "<span id=Help onclick="alert('Chromeless Window For IE6 SP1 - Ver 1.0nnCode By Windy_sknnSpecial Thanks For andot')" style=""+CSStext+"font-family:System;padding-right:2px;">?</span>";
temp += "<span id=Min onclick='parent.New_CW.hide();parent.blur()' style=""+CSStext+"font-family:Webdings;" title='Minimum'>0</span>";
temp += "<span id=Max onclick="this.innerText=this.innerText=='1'?'2':'1';parent.if_max=!parent.if_max;parent.show_CW();" style=""+CSStext+"font-family:Webdings;" title='Maximum'>1</span>";
temp += "<span id=Close onclick='parent.opener=null;parent.close()' style=""+CSStext+"font-family:System;padding-right:2px;" title='Close'>x</span>";
temp += "</td></tr><tr><td colspan=2>";
temp += "<div id=include style='overflow:scroll;overflow-x:hidden;overflow-y:auto; HEIGHT: 100%; width:"+CW_width+"'>";
temp += content;
temp += "</div>";
temp += "</td></tr></table>";
CW_Body.innerHTML = temp;
}

setTimeout("insert_content()",1000);

var if_max = true;
function show_CW(){
window.moveTo(10000, 10000);
if(if_max){
New_CW.show(CW_top, CW_left, CW_width, CW_height);
if(typeof(New_CW.document.all.include)!="undefined"){
New_CW.document.all.include.style.width = CW_width;
New_CW.document.all.Max.innerText = "1";
}

}else{
New_CW.show(0, 0, screen.width, screen.height);
New_CW.document.all.include.style.width = screen.width;
}
}

window.onfocus = show_CW;
window.onresize = show_CW;

// Move Window
var drag_x,drag_y,draging=false

function drag_move(e){
if (draging){
New_CW.show(e.screenX-drag_x, e.screenY-drag_y, CW_width, CW_height);
return false;
}
}

function drag_down(e){
if(e.button==2)return;
if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height)return;
drag_x=e.clientX;
drag_y=e.clientY;
draging=true;
e.srcElement.setCapture();
}

function drag_up(e){
draging=false;
e.srcElement.releaseCapture();
if(New_CW.document.body.offsetWidth==screen.width && New_CW.document.body.offsetHeight==screen.height) return;
CW_top = e.screenX-drag_x;
CW_left = e.screenY-drag_y;
}

</SCRIPT>
</HTML>

电话号码的验证

要求:
  (1)电话号码由数字、"("、")"和"-"构成
  (2)电话号码为3到8位
  (3)如果电话号码中包含有区号,那么区号为三位或四位
  (4)区号用"("、")"或"-"和其他部分隔开
  (5)移动电话号码为11或12位,如果为12位,那么第一位为0
  (6)11位移动电话号码的第一位和第二位为"13"
  (7)12位移动电话号码的第二位和第三位为"13"
  根据这几条规则,可以与出以下正则表达式:
  (^[0-9]{3,4}-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^([0-9]{3,4})[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)


<script language="javascript">
function PhoneCheck(s) {
var str=s;
var reg=/(^[0-9]{3,4}-[0-9]{3,8}$)|(^[0-9]{3,8}$)|(^([0-9]{3,4})[0-9]{3,8}$)|(^0{0,1}13[0-9]{9}$)/
alert(reg.test(str));
}
</script>
<input type=text name="iphone">
<input type=button onclick="PhoneCheck(document.all.iphone.value)" value="Check">

具有在输入非数字字符不回显的效果,即对非数字字符的输入不作反应。
function numbersonly(field,event){
var key,keychar;
if(window.event){
key = window.event.keyCode;
}
else if (event){
key = event.which;
}
else{
return true
}
keychar = String.fromCharCode(key);
if((key == null)||(key == 0)||(key == 8)||(key == 9)||(key == 13)||(key == 27)){
return true;
}
else if(("0123456789.").indexOf(keychar)>-1){
window.status = "";
return true;
}
else {
window.status = "Field excepts numbers only";
return false;
}
}

验证ip

str=document.RegExpDemo.txtIP.value;
if(/^(d{1,3}).(d{1,3}).(d{1,3}).(d{1,3})$/.test(str)==false)
{
window.alert('错误的IP地址格式');
document.RegExpDemo.txtIP.select();
document.RegExpDemo.txtIP.focus();
return;
}
if(RegExp.$1<1 || RegExp.$1>254||RegExp.$2<0||RegExp.$2>254||RegExp.$3<0||RegExp.$3>254||RegExp.$4<1||RegExp.$4>254)
{
window.alert('错误的IP地址');
document.RegExpDemo.txtIP.select();
document.RegExpDemo.txtIP.focus();
return;
}
//剔除 如 010.020.020.03 前面 的0
var str=str.replace(/0(d)/g,"$1");
str=str.replace(/0(d)/g,"$1");
window.alert(str);


wj99898 发表于:2006.11.01 16:17 ::分类: ( oracle专区 ) ::阅读:(254次) :: 评论 (0) :: 引用 (0)

2006 年 10 月 28日, 星期六

ORDER BY 之应用

Select a.deptno,a.ename From scott.emp a
Union
Select b.deptno,b.dname From scott.dept b
Order By 1

将复合查询的结果按第一列排序。


wj99898 发表于:2006.10.28 14:56 ::分类: ( oracle专区 ) ::阅读:(332次) :: 评论 (0) :: 引用 (0)

ORCLE分析函数

一、rank 函数、dense_rank 函数、row_number函数

例:从

DOC_IDITEM_IDB
117111
1172
1163
1114
1105
2571
2552
2373
2134
215
418431
4512
4143
434
415

DOC_IDITEM_IDB
117111
1172
1163
2571
2552
2373
418431
4512
4143
59281
59242
59173

SELECT *
FROM (SELECT t.doc_id
,t.item_id
,(row_number() over(PARTITION BY t.doc_id ORDER BY t.item_id DESC)) AS b
FROM test t) ff
WHERE ff.b <= 3;

或:

SELECT *
FROM (SELECT t.doc_id
,t.item_id
,(dense_rank() over(PARTITION BY t.doc_id ORDER BY t.item_id DESC)) AS b
FROM test t) ff
WHERE ff.b <= 3;

二、rollup函数、cube函数和grouping函数:求出汇总数据。

如:
Select a.ename,a.mgr From scott.emp a ;

ENAMEMGR
SMITH7902
ALLEN7698
WARD7698
JONES7839
MARTIN7698
BLAKE7839
CLARK7839
SCOTT7566
KING 
TURNER7698
ADAMS7788
JAMES7698
FORD7566
MILLER7782

汇总后:
Select nvl(a.ename,'合计') ename,sum(nvl(a.mgr,0)) From scott.emp a Group By Rollup( a.ename );

ENAMESUM(NVL(A.MGR,0))
ADAMS7788
ALLEN7698
BLAKE7839
CLARK7839
FORD7566
JAMES7698
JONES7839
KING0
MARTIN7698
MILLER7782
SCOTT7566
SMITH7902
TURNER7698
WARD7698
合计100611

ROLLUP函数只对列求出汇总数据,而CUBE可分别对多行汇总数据,在CUBE汇总数据时空列GROUPING返回1,否则返回0;

Select decode(grouping(a.ename),1,'第一列汇总',a.ename) ename,decode(grouping(a.job),1,'第二列汇总',a.job),sum(nvl(a.mgr,0)) From scott.emp a Group By Cube( a.ename,a.job );


wj99898 发表于:2006.10.28 14:14 ::分类: ( oracle专区 ) ::阅读:(419次) :: 评论 (0) :: 引用 (0)

2006 年 10 月 24日, 星期二

LPAD和RPAD的用法

SELECT LPAD('A',10,'-') FROM DUAL;

A的右边插入10个'-'字符.

SELECT RPAD('A',10,'-') FROM DUAL;

A的左边插入10个'-'字符.


wj99898 发表于:2006.10.24 16:36 ::分类: ( oracle专区 ) ::阅读:(696次) :: 评论 (0) :: 引用 (0)

2006 年 09 月 08日, 星期五

创建弹性域方法

1、切换到“应用开发员”责任,弹性域-注册,选择应用产品、表应用、表名、输入名称、标题等,单击“列”,设置相应的表字段

2、切换到“系统管理员”责任,应用-弹性域-段,为注册的弹性域添加段,输入段代码、名称、说明,单击“段”,设置段名称、窗口提示、选择相应的表字段和什值集,并启用。
3、若值集没有定义,可单击窗口下的“值集”按钮,在弹出的值集窗口里,输入值集名、说明等。(注:值集设定了段中列的范围)


wj99898 发表于:2006.09.08 13:49 ::分类: ( oracle专区 ) ::阅读:(394次) :: 评论 (0) :: 引用 (0)

2006 年 09 月 05日, 星期二

如何用科学计算法把数值显示出来

如果一个数为15468,将其显示为1.5468E+04select to_char(15468,'S9.9999EEEE') from dual;

 查看全文
wj99898 发表于:2006.09.05 11:39 ::分类: ( oracle专区 ) ::阅读:(619次) :: 评论 (0) :: 引用 (0)

2006 年 08 月 29日, 星期二

提取字符串中某个字符的个数

select lengthb(translate('123aa','a'||'123aa','~')) from dual
这里~必须是字符串中不存在的字符,该语句是得到a的个数

wj99898 发表于:2006.08.29 12:36 ::分类: ( oracle专区 ) ::阅读:(374次) :: 评论 (0) :: 引用 (0)

2006 年 08 月 21日, 星期一

SQL查询语句中,any和all有什么区别?

any要求你的结果等于任何一个就可以了。
all是所有的

例:
从销货表中挑出订单金额大于“E0013这位业务员在1996/11/10这天所接的任一张订单的金额”的所有订单,并显示相关字段信息
select sale_id, tot_amt
from sales
where tot_amt > any
(select tot_amt from sales
where sale_id='e0013'
and order _date='1996/11/10')


把ANY换成ALL时,语句表示的意思就是订单金额大于“E0013这位业务员在1996/11/10这天所接的每一张订单的金额”的所有订单


wj99898 发表于:2006.08.21 09:54 ::分类: ( oracle专区 ) ::阅读:(810次) :: 评论 (0) :: 引用 (0)

2006 年 08 月 19日, 星期六

独立的函数嵌套

SQL> SELECT CONCAT(UPPER(last_name),

2 SUBSTR(title,3)) ”Vice Presidents”

3 FROM s_emp

4 WHERE title LIKE ’VP%’;

* 嵌套可以进行到任意深度,从内向外计算。

例:

SQL> SELECT TO_CHAR(NEXT_DAY(ADD_MONTHS

2 (date_ordered,6),’FRIDAY’),

3 ’fmDay, Month ddth, YYYY’)

4 ”New 6 Month Review”

5 FROM s_ord

6 ORDER BY date_ordered;

SQL> SELECT last_name,

2 NVL(TO_CHAR(manager_id),’No Manager’)

3 FROM s_emp

4 WHERE manager_id IS NULL;


wj99898 发表于:2006.08.19 12:00 ::分类: ( oracle专区 ) ::阅读:(13038次) :: 评论 (0) :: 引用 (0)

转换函数

1、TO_CHAR

使一个数字或日期转换为CHAR


2、TO_NUMBER

把字符转换为NUMBER


3、TO_DATE

字符转换为日期

这几个函数较为简单,但要多多实践,多看复杂的实例。

SQL> SELECT ID,TO_CHAR(date_ordered,’MM/YY’) ORDERED

2 FROM s_ord

3 WHERE sales_rep_id = 11;

转换时,要注意正确的缺省格式:

SELECT TO_DATE('03-MAR-92') CORRECT FROM DUAL;//正确

SELECT TO_DATE('031092') CORRECT FROM DUAL;//不正确

SELECT TO_DATE('031095','MMDDYY') ERRORR FROM DUAL

输出 3月10日

SELECT TO_DATE('031095','DDMMYY') ERRORR FROM DUAL

输出 10月3日

4、实例:

select to_char(sysdate,'fmDDSPTH "of" MONTH YYYY AM') TODAYS FROM DUAL;

TODAYS

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

SIXTEENTH of 11月 2001 下午

大小写没有什么影响,引号中间的是不参与运算。

实例 :

SELECT ROUND(SALARY*1.25) FROM ONE_TABLE;

意义:涨25%工资后,去除小数位。在现实操作中,很有意义。

5、混合实例:

SQL> SELECT last_name, TO_CHAR(start_date,

2 ’fmDD ”of” Month YYYY’) HIREDATE

3 FROM s_emp

4 WHERE start_date LIKE ’%91’;

LAST_NAME HIREDATE

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

Nagayama 17 of June 1991

Urguhart 18 of January 1991

Havel 27 of February 1991

这里要注意:fmDD 和 fmDDSPTH之间的区别。

SQL> SELECT id, total, date_ordered

2 FROM s_ord

3 WHERE date_ordered =

4 TO_DATE(’September 7, 1992’,’Month dd, YYYY’);


wj99898 发表于:2006.08.19 11:57 ::分类: ( oracle专区 ) ::阅读:(12975次) :: 评论 (0) :: 引用 (0)

ORACLE 日期格式和日期型函数

1、默认格式为DD-MON-YY.

2、SYSDATE是一个求系统时间的函数

3、DUAL['dju:el] 是一个伪表,有人称之为空表,但不确切。

SQL> SELECT SYSDATE

2 FROM SYS.DUAL;

4、日期中应用的算术运算符

例:SQL> SELECT last_name, (SYSDATE-start_date)/7 WEEKS

2 FROM s_emp

3 WHERE dept_id = 43;

DATE+ NUMBER = DATE

DATE-DATE= NUMBER OF DAYS

DATE + (NUMBER/24) = 加1小时

5、函数:

MONTHS_BETWEEN(date1, date2) 月份间隔,可正,可负,也可是小数

ADD_MONTHS(date,n) 加上N个月,这是一个整数,但可以为负

NEXT_DAY(date,‘char’) 如:NEXT_DAY (restock_date,’FRIDAY’),从此日起下个周五。

ROUND(date[,‘fmt’])

TRUNC(date[,‘fmt’])

解释下面的例子:

SQL> SELECT id, start_date,

2 MONTHS_BETWEEN (SYSDATE,start_date) TENURE,

3 ADD_MONTHS(start_date,6) REVIEW

4 FROM s_emp

5 WHERE MONTHS_BETWEEN (SYSDATE,start_date)<48;

我们看到: MONTHS_BETWEEN (SYSDATE,start_date)<48,说明至今工作未满一年的员工。

LAST_DAY (restock_date) 返回本月的最后一天

Select Last_Day(add_months(Sysdate,-1)) From dual 上个月的最后一天

SQL> select round(sysdate,'MONTH') from dual

ROUND(SYSD

----------

01-11月-01

round(sysdate,'YEAR') = 01-1月 -02

ROUND 之后的值比基值大的最小符合值,大家可以用更改系统时间的方法测试,以15天为分界线,也是非常形象的四舍五入,而TRUNC恰好相反,是对现有的日期的截取。

other:

select TO_CHAR(sysdate,'yyyymmdd hh24:mi:ss') from dual
select TO_CHAR(sysdate,'d') from dual --一周中的星期几
select TO_CHAR(sysdate,'dd') from dual --一月中的几天
select TO_CHAR(sysdate,'ddd') from dual --一年中的几天
select TO_CHAR(sysdate,'dy') from dual --星期的簡寫名
select TO_CHAR(sysdate,'IW') from dual --一年中的几周
select TO_CHAR(sysdate,'W') from dual --該月的第几周
Select Sysdate - TO_CHAR(sysdate,'d') +2 From dual --本周的星期一

 查看全文
wj99898 发表于:2006.08.19 11:54 ::分类: ( oracle专区 ) ::阅读:(723次) :: 评论 (0) :: 引用 (0)

数学运算函数

1、ROUND

四舍五入:ROUND(45.923,2) = 45.92

ROUND(45.923,0) = 46

ROUND(45.923,-1) = 50

2、TRUNC

截取函数

TRUNC(45.923,2)= 45.92

TRUNC(45.923)= 45

TRUNC(45.923,-1)= 40

3、MOD 余除

MOD(1600,300)

实例:

SQL> SELECT ROUND(45.923,2), ROUND(45.923,0),

2 ROUND(45.923,-1)

3 FROM SYS.DUAL;


wj99898 发表于:2006.08.19 11:52 ::分类: ( oracle专区 ) ::阅读:(12993次) :: 评论 (0) :: 引用 (0)

字符型函数

1、LOWER 转小写

2、UPPER

3、INITCAP 首字母大写

4、CONCAT 连接字符,相当于 ||

5、SUBSTR SUBSTR(column|expression,m[,n])

6、LENGTH 返回字符串的长度

7、NVL 转换空值

其中,1、2经常用来排杂,也就是排除插入值的大小写混用的干扰,如:

SQL> SELECT first_name, last_name

2 FROM s_emp

3 WHERE UPPER(last_name) = ’PATEL’;

FIRST_NAME LAST_NAME

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

Vikram Patel

Radha Patel


wj99898 发表于:2006.08.19 11:51 ::分类: ( oracle专区 ) ::阅读:(12991次) :: 评论 (0) :: 引用 (0)

创建报表模板

1、1、 安装XMLP_Desktop_R550

2 2、打开WORD,创建相应模板的表格,打开“窗体”

3、3、 在每个字段里添加“文字型窗体域”,相应代码:<?G_ORDER_NUM?>,注意G_ORDER_NUMREPORT BUILD 组里面的字段的XML标记值。

4、4、若有循环,则在相应字段里多添加一个START“文字型窗体域”,相应代码:<?for-each:G_ITEM_NO?>G_ITEM_NO为组的XML标记值,同时还在表格外添加一个END “文字型窗体域” 相应代码:<?end for-each?>

5、5、做好后,保存,文件类型为.RTF

6、6、打开ORACLE EBS,切换到“Oracle XML Publisher 管理员”责任。

7、7、创建“数据定义”,输入名称、代码、应用产品和起始日期,注代码为并发程序的简称。

8、8、创建“模板”,输入名称、代码、应用产品、数据定义(7建好的数据源)、类型、起始日期、文件(模板文件)、语言和地区,应用完成。


wj99898 发表于:2006.08.19 11:10 ::分类: ( oracle专区 ) ::阅读:(410次) :: 评论 (0) :: 引用 (0)

2006 年 08 月 17日, 星期四

弹性域建立步骤

1、规划使用地方,使用的字段数量,在建立表的时候建立相应字段 ATTRIBUTE_CATEGORY,ATTRIBUTEN

2、注册你的弹性域表

3、将弹性域字段加人表单块并增加显示项

4、在画布上布置弹性域

5、在 WHEN–NEW–FORM–INSTANCE 里增加弹性域定义
FND_DESCR_FLEX.DEFINE(
BLOCK=>'ORD_HEADERS',
FIELD=>'DESC_FLEX',
APPL_SHORT_NAME=>'CUX',
DESC_FLEX_NAME=>'CUX_SAMPLE_ORDER_FLEX');

6、在 TRIGGER 里增加弹性域过程

PRE-QUERY FND_FLEX.EVENT(’PRE–QUERY’);
POST–QUERY FND_FLEX.EVENT(’POST–QUERY’);
PRE–INSERT FND_FLEX.EVENT(’PRE–INSERT’);
PRE–UPDATE FND_FLEX.EVENT(’PRE–UPDATE’);
WHEN–VALIDATE–RECORD FND_FLEX.EVENT(’WHEN–VALIDATE–RECORD’);
WHEN–NEW–ITEM–INSTANCE FND_FLEX.EVENT(’WHEN–NEW–ITEM–INSTANCE’);
WHEN–VALIDATE–ITEM FND_FLEX.EVENT(’WHEN–VALIDATE–ITEM’);

7、注册弹性域


wj99898 发表于:2006.08.17 19:12 ::分类: ( oracle专区 ) ::阅读:(407次) :: 评论 (0) :: 引用 (0)

建立FIND_WINDOW 的步骤

1、从 APPSTAND 中 拷贝 QUERY_FIND 对象组

2、修改BLOCK,CANVAS,WINDOW 名字

3、修改 NEW 按扭 的TRIGGER

4、修改 FIND 按扭 的TRIGGER

5、设置块导航顺序

6、修改FIND WINDOW 标题

7、在FIND 增加查询字段

8、排列布局

9、在 目标块的 PRE_QUERY 里增加控制代码
IF :parameter.G_query_find = ’TRUE’ THEN
COPY (<find Window field>,’<results field>’);

APP_FIND.QUERY_RANGE(:QUERY_FIND.DATE_F,
:QUERY_FIND.DATE_T,
'TEST_OTHER.START_DATE');
:parameter.G_query_find := ’FALSE’;
END IF;

10 自定义 QUERY_FIND trigger
APP_FIND.QUERY_FIND(’<results block window>’,
’<Find window>’,
’<Find window block>’);


wj99898 发表于:2006.08.17 19:09 ::分类: ( oracle专区 ) ::阅读:(449次) :: 评论 (0) :: 引用 (0)

FORM的一般流程

1.用FTP将/home/oracle/vis/visappl/au/11.5.0/中的forms AND resource下传至本机。

2 在HKEY_LOCAL_MACHINE
SOFTWARE
ORACLE
FORMS60_PATH 中设置路径。

3:复制forms中的TEMPLATE,重命名,修改。

4:用FTP将/home/oracle/vis/visappl/cux/1.0.0/forms/ZHS/

5: 编译FORMS

cmd

telnet

open 192.168.01.**

source .app

cd $AU_TOP/forms/ZHS

f60gen $CUX_TOP/forms/ZHS/CUXORDLQ.fmb apps/apps output_file=$CUX_TOP/forms/ZHS/CUXORDLQ.fmx

5: 在EBS中建立表单

6:在EBS中建立功能

7: 分配到菜单

8:分配到责任

9:分配到用户


wj99898 发表于:2006.08.17 19:05 ::分类: ( oracle专区 ) ::阅读:(113375次) :: 评论 (0) :: 引用 (0)

DATE 函数

MONTHS_BETWEENNumber of months between two dates

ADD_MONTHSAdd calendar months to date

NEXT_DAY Next day of the date specified

LAST_DAYLast day of the month

ROUND Round date

TRUNC Truncate date

1

MONTHS_BETWEEN ('01-SEP-95','11-JAN-94') ---------19.6774194

ADD_MONTHS ('11-JAN-94',6)----------- '11-JUL-94'

NEXT_DAY ('01-SEP-95','FRIDAY') ----------'08-SEP-95'

LAST_DAY('01-SEP-95')-------------'30-SEP-95'

2:求出从当前时间到6个月后的第一个星期一的时间

select Next_day(add_months(sysdate,6),2) from dual


wj99898 发表于:2006.08.17 18:46 ::分类: ( oracle专区 ) ::阅读:(289次) :: 评论 (0) :: 引用 (0)

2006 年 08 月 12日, 星期六

oracle的nvl函数的用法

通过查询获得某个字段的合计值,如果这个值位null将给出一个预设的默认值
select nvl(sum(t.dwxhl),1) from tb_jhde t where zydm=-1这里关心的nvl的用法,nvl(arg,value)代表如果前面的arg的值为null那么返回的值为后面的value

另一个有关的有用方法
declare
i integer
select nvl(sum(t.dwxhl),1) into i from tb_jhde t where zydm=-1
这样就可以把获得的合计值存储到变量i中,如果查询的值为null就把它的值设置为默认的1


wj99898 发表于:2006.08.12 09:45 ::分类: ( oracle专区 ) ::阅读:(3069次) :: 评论 (0) :: 引用 (0)

2006 年 08 月 05日, 星期六

使用SQL MERGE语句组合表

MERGE語句是Oracle9i新增的語法,用來合併UPDATE和INSERT語句。
通過MERGE語句,根據一張表或子查詢的連接條件對另外一張表進行查詢,
連接條件匹配上的進行UPDATE,無法匹配的執行INSERT。
這個語法僅需要一次全表掃描就完成了全部工作,執行效率要高於INSERT+UPDATE。
下面看個具體的例子:


--1.來源表
CREATE TABLE T AS SELECT ROWNUM ID, A.* FROM USER_OBJECTS A;

--2.目標表
CREATE TABLE T1 AS
SELECT ROWNUM ID, TABLE_NAME, CAST('TABLE' AS VARCHAR2(100)) OBJECT_TYPE
FROM USER_TABLES;

--3.根據來源表UPDATE和INSERT目標表
MERGE INTO T1 USING T
ON (T.OBJECT_NAME = T1.TABLE_NAME AND T.OBJECT_TYPE = T1.OBJECT_TYPE)
WHEN MATCHED THEN UPDATE SET T1.ID = T.ID
WHEN NOT MATCHED THEN INSERT VALUES (T.ID, T.OBJECT_NAME, T.OBJECT_TYPE);

--4.比較來源表和目標表
SELECT ID, OBJECT_NAME, OBJECT_TYPE FROM T
MINUS
SELECT * FROM T1;

MERGE語句中必須指定一個WHEN MATCHED和一個WHEN NOT MATHCED語句。如果除這兩種情況之外還有別的情況,你可能就需要使用一個常規的INSERT或者UPDATE語句。

另外一點是MERGE語句一次只能修改一行記錄,而且不能修改在ON子句中引用的列。

MERGE語句的目標表(target table)必須是一個可以使用INSERT語句進行插入或者UPDATE語句進行更新的表或者視圖。源表(source table)可以是任何的查詢表,比如說外部表或者管道化表函數。


wj99898 发表于:2006.08.05 16:53 ::分类: ( oracle专区 ) ::阅读:(345次) :: 评论 (0) :: 引用 (0)

2006 年 07 月 21日, 星期五

PL/SQL内置包(65个)

1. DBMS_ALERT

2. DBMS_APPLICATION_INFO

3. DBMS_AQ

4. DBMS_AQADM

5. DBMS_BACKUP_RESTORE

6. DBMS_DDL

7. DBMS_DEBUG

8. DBMS_DEFER

9. DBMS_DEFER_QUERY

10. DBMS_DEFER_SYS

11. DBMS_DESCRIBE

12. DBMS_DISTRIBUTED_TRUST_ADMIN

13. DBMS_HS

14. DBMS_HS_PASSTHROUGH

15. DBMS_IOT

16. DBMS_JOB

17. DBMS_LOB

18. DBMS_LOCK

19. DBMS_LOGMNR

20. DBMS_LOGMNR_D

21. DBMS_MVIEW

22. DBMS_OBFUSCATION_TOOLKIT

23. DBMS_OFFLINE_OG

24. DBMS_OFFLINE_SNAPSHOT

25. DBMS_OLAP

26. DBMS_ORACLE_TRACE_AGENT

27. DBMS_ORACLE_TRACE_USER

28. DBMS_OUTPUT

29. DBMS_PCLXUTIL

30. DBMS_PIPE

31. DBMS_PROFILER

32. DBMS_RANDOM

33. DBMS_RECTIFIER_DIFF

34. DBMS_REFRESH

35. DBMS_REPAIR

36. DBMS_REPCAT

37. DBMS_REPCAT_ADMIN

38. DBMS_REPCAT_INSTANTIATE

39. DBMS_REPCAT_RGT

40. DBMS_REPUTIL

41. DBMS_RESOURCE_MANAGER

42. DBMS_RESOURCE_MANAGER_PRIVS

43. DBMS_RLS

44. DBMS_ROWID

45. DBMS_SESSION

46. DBMS_SHARED_POOL

47. DBMS_SNAPSHOT

48. DBMS_SPACE

49. DBMS_SPACE_ADMIN

50. DBMS_SQL

51. DBMS_STATS

52. DBMS_TRACE

53. DBMS_TRANSACTION

54. DBMS_TTS

55. DBMS_UTILITY

56. DEBUG_EXTPROC

57. OUTLN_PKG

58. UTL_COLL

59. UTL_FILE

60. UTL_HTTP

61. UTL_INADDR

62. UTL_RAW

63. UTL_REF

64. UTL_SMTP

65. UTL_TCP


wj99898 发表于:2006.07.21 10:03 ::分类: ( oracle专区 ) ::阅读:(324次) :: 评论 (0) :: 引用 (0)

几个SQL语句的区别

表t1和表t2(其他字段可以不想同)


1 select * from t1,t2 where t1.id = t2.id

2 SELECT * FROM t1 JOIN t2 ON t1.id=t2.id;

3 SELECT * FROM t1 JOIN t2 using (id)

结果1和2相同,3使用using的语句using里面的字段只显示一次。


wj99898 发表于:2006.07.21 09:05 ::分类: ( oracle专区 ) ::阅读:(263次) :: 评论 (0) :: 引用 (0)

2006 年 07 月 20日, 星期四

分区

一、表分区:

1、优点:

  • 增强可用性,如果表的一个分区由于系统故障或者维护而得不到使用时,表的其余部分仍是可用的

  • 减少关闭时间,如果系统故障只影响表的某部分,那么只有这部分需要修复,因此修复工作量减少,所以更快地完成

  • 维护轻松,如果需重新连表,那么独立地管理而不是单个大型表的操作要轻松得多。

  • 均衡的IO,可以把不同分区映射到磁盘以平衡IO并显著改善性能。

  • 改善性能,对已分区对象的某些查询可以运行更快,因为搜索仅限于关心的分区。

2、限制:

l 存在于oracle8簇(cluster)中的表不能被分区

l 如果一个表包含非结构性数据,则这个表不能被分区,下面的数据类型就不能进行分区:

1) LOBS

2) LONG RAW

3)对象类型

l 索引组织的表不能被分区。

3、3、分区方法:

范 范围分区:根据表中列值的范围进行分区

l 散列(hash)分区:如果数据不容易进行范围分区,而出现性能原因时就要进行散列分区。

l 复合分区:分区数据使用范围分区法,而在每个分区或子分区内使用散列分区。

4、创建表的分区:

1)范围分区法:

a 表的单列分区

create table students

(

student_id integer not null,

student_first_name varchar2(25),

student_last_name varchar2(25),

student_dept_id integer,

student_address varchar2(50),

student_city varchar2(25),

)constraint Dept_id_pk primary key (student_dept_id)

partition By Range (student_dept_id)

(partition Dept_id_1 values less than(100) tablespace om1,

partition Dept_id_2 values less than (250) tablespace om2,

partition Dept_id_3 values less than (500) tablespace om3

partition Dept_id_4 values less than (750) tablespace om4

partition Dept_id_5 values less than (max value)table space om5);

b 表的多列分区

oracle8i把多列分区码值作为向量来决定一行应放在哪个分区,如:

1

create table students

(

student_id integer not null,

student_first_name varchar2(25),

student_last_name varchar2(25),

student_dept_id integer,

student_address varchar2(50),

student_city varchar2(25),

)constraint Dept_id_pk primary key (student_dept_id)

partition By Range (student_id,student_Dept_id)

partition Dept_id_1 values less than(1000,100)tablespace om1,

partition Dept_id_2 values less than(2000,250)tablespace om2,

partition Dept_id_3 values less than(3000,500)tablespace om3,

partition Dept_id_1 values less than(4000,750)tablespace om4,

partition Dept_id_1 values less than(MAXVALUE,MAXVALUE)tablespace om5)

c 等同分区

把表对应的索引按照表的分区确定索引的分区称等同分区,students表使用

student_idstudent_Dept_id来分区,则该表的索引也使用这二列来分区.优点有:

l oracle8i在复杂的连接,排序操作中改善分区表的执行计划。

l 由于相关表和索引可同时恢复,减少介质恢复时间。

2)使用散列分区法:

使用 CREATE TABLE 语句加PARTITION BY HASH 子句可以指定所建的表被散列分区。

下面例子创建一个散列分区。分区列为ID,创建了四个分区并分配了由系统生成的分区名,它们被放置在四个被命名的表空间gear1,gear2,gear3,gear4上。

1

CREATE TABLE scubagear

( id NUMBER,

name VARCHAR2(60)

)

PARTITION BY HASH(id)

PARTITIONS 4

STORE IN ( gear1,gear2,gear3,gear4);

散列分区表的每个分区内保存在不同的节中,且散列数据被放在缺省表空间中。

2

CREATE TABLE ( deptno NUMBER,deptname VARCHAR2(32))

STORAGE( INITIAL 10k )

PARTITION BY HASH(deptno)

(

PARTITION p1 TABLESPACE ts1,

PARTITION p2 TABLESPACE ts2,

PARTITION p3 TABLESPACE ts1,

PARTITION p4 TABLESPACE ts3

);

3)复合分区方法:

例:下面例子创建了三个范围分区,每个分区又包含八个子分区,子分区没有名字,所以赋予它们系统生成的名字,“STORE IN”子句将它们分布在四个指定的表空间 ts1,ts2,ts3,ts4中。

CREATE TABLE scubager(equipno NUMBER,equipname VARCHAR(32),price NUMBER)

PARTITION BY RANGE(equipno)SUBPARTITION BY HASH(equipname)

SUBPARTITIONS 8 STORE IN ( ts1,ts2,ts3,ts4)

(

PARTITION p1 VALUES LESS THAN(1000),

PARTITION p2 VALUES LESS THAN(2000),

PARTITION p3 VALUES LESS THAN(MAXVALUE)

);

4)对表分区小结

把表的数据范围(range)进行分区存储;

只需在Create tableAlter table命令中指定即可;

分区名在Create tableAlter table中指定(给出)即可,不需在任何另外的地方预先说明。

l 建立表结构时指定区

Create table emp

(emp_no number(5),

dept varchar2
(2),

name varchar2(30))

storage(initial 100k next 50k) logging

PARTITION BY RANAE (enp_no)

(PARTITION acct values less than (1000) tablespace ts1,

PARTITION sales values less than (2000) tablespace ts2,

PARTITION edue values less than (3000))

Insent into emp values (1226, sa,smith);

Insent into emp values (2100, ed,jones);

l 对具有分区的表更新,有以下不足:

1) 不能进行的更新

up date emp set emp _no=1500 where name= JONES;

此条语句将不能运行(引起错误),原因是′Jones′原来是(emp_no=2100)对应的分区为educ,而现要将其从educ分区移至sales中,所以不能垮分区修改。

2) 不指定分区的更新(影响效率)

update emp set emp_no=1356 where name = SMITH′;

3) 指定分区的更新(提高效率)

update sale partition (feb96)

set s.account_name=upper(s.account_name);

l 对具有分区的表进行删除(指定分区效率更高)

Delete From sales Partition (nov96)

Where amount_of_sale !=0

l 对具有分区的表进行查询

Select * from emp partition acct

Where emp_no=999

l 用日期字段作分区条件(详细见《oracle8 sql Reference》 )

Create table stock_xaction

(stock_symbot CHAR(5),

stock_series CHAR(1),

num_shares Number(10)

price Number(5,2)

trade_date Date

Storage (inltial 100k next 50k)logging

PARTITION By range (trade_date)

(PARTITION sx1992 values less than (to_date(01-JAN-1993,

DD-MON-YYYY))Tablespace tso Nologging,

PARTITION sx1993 values less than(To-date(01-JAN-1994,

DD-MON-YYYY))Tablespace ts1,

PARTITION sx1994 values less than (To-date(01-JAN-1995,

DD-MON-YYYY))Tablespace ts2);

l Alter对表进行分区

可以用下面语句实现分区指定:

MODIFY PARTITION partition-name [phsical-attributes-clause]

二、索引分区:

1、可以创建两种类型的索引分区

l 局部索引

l 全部索引

2、这两种均遵从下列原则:

l 分区的索引表不能应用聚类表

l 位图索引必须为局部索引

l 分区和未分区的索引可以应用于分区或未分区的表

3、 局部索引

根据表的分区个数来建立同样的索引分区叫局部索引,如:

( create index Dept_id_1 tablespace om1,

create index Dept_id_2 tablespace om2,

create index Dept_id_3 tablespace om3,

create index Dept_id_4 tablespace om4

create index Dept_id_5 tablespace om5

)

4、全局索引分区

对表的多个分区建立索引分区叫全局索引(分区)一般可以这样认为,未作分区的索引被认为是全局索引如:

create index Dept_idx on students(student_dept_id)

GLOBAL partition By range (student_dept_id)

(partition Dept_id_1 values less than (1000,100) tablespace om1,

partition Dept_id_2 values less than (2000,250) tablespace om2,

partition Dept_id_3 values less than (3000,500) tablespace om3,

partition Dept_id_4 values less than (4000,750) tablespace om4,

partition Dept_id_5 values less than (MAXVALUE,MAXVALUE) tablespace om5);

4、相关的数据字典

DBA_IND_PARTITIONS

DBA_TAB_PARTITIONS

DBA_PART_COL_STATISTICS

USER_TAB_PARTITONS

USER_PART_COL_STATISTICS

USER_IND_PARTITIONS

ALL_TAB_PARTITIONS

ALL_IND_PARTITIONS

ALL_PART_COL_STATISTICS

 查看全文
wj99898 发表于:2006.07.20 10:45 ::分类: ( oracle专区 ) ::阅读:(13298次) :: 评论 (0) :: 引用 (0)

簇(Cluster)

1 簇概念:

是一组表,如果应用程序中的SQL 语句经常联结两个或多个表,可以把这些表以簇方式进行创建以改善性能。簇中的表存储在相同的数据块中,并且各个表中的相同的列值只存储一个。

簇(Cluster)就是将一组有机联系的表在物理上存放在一起并且相同的关键列的值只存储一份,用于提高处理效率的一项技术

2 限制:

l 簇中的每个表必须有一列与簇中指定的列的 大小和类型匹配;

l 簇码中可用列的最大数目是16,即一个簇最多有16列作为簇码;

l 列的最大长度为239字节;

l LONG LONG RAW 不能作为簇列码。

3 3 建立簇:

1) 创建簇语法

CREATE CLUSTER cluster

( column datatype[,colmn datatype])

[PCTUSED 40|intger] [ PCTFREE 10| intger]

[ SIZE intger ]

[INITRANS 1|intger] [MAXTRANS 255|intger]

[TABLESPACE tablespace]

[STORAGE storage]

2)创建簇及其表的步骤:

l CREATE CLUSTER创建簇

l CREATE INDEX创建簇索引

l CREATE TABLE 创建表,并指定簇

l 插入数据并进行DML 操作

4 改变簇:

在用户具有 ALTER ANY CLUSTER 的权限情况下,可以对已建好的簇(CLUSTER )改变其设置,如:

l 物理属性:PCTFREE,PCTUSED,INITRANS,MAXTRANSSTORAGE;

l CLUSTER 关键字值存储所有行所需的一般空间容量;

l 缺省平行度。

命令语法:

ALTER CLUSTER Cluster_name

{ PCTUSED integer

| PCTFREE integer

| SIZE integer

| INITRANS integer

| MAXTRANS integer

| STORAGE Cluase

}

5 删除簇:

只要用户具有 DROP ANY CLUSTER权限均可以对所有的CLUSTER进行删除。

语法如下:

DROP CLUSTER [user.]cluster [INCLUDING TABLES]

6 收集簇信息:

删除簇索引:一个簇的索引可以被删除而不影响表的数据,但是当簇的索引被删除后,属于该簇的表就变为不可用,所以当删除簇的索引后还须再建立该簇的索引才行。有时为了消除盘空间的碎片我们常进行删除簇索引操作。

l DBA_CLU_COLUMNS USER_CLU_COLUMNS

l DBA_CLUSTERSUSER_CLUSTER


wj99898 发表于:2006.07.20 10:25 ::分类: ( oracle专区 ) ::阅读:(250次) :: 评论 (0) :: 引用 (0)

触发器

触发器在数据库里以独立的对象存储,它与存储过程不同的是,存储过程通过其它程序来启动运行或直接启动运行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动地隐式运行。并且,触发器不能接收参数。所以运行触发器就叫触发或点火(firing)。

三种类型的触发器:DML触发器、替代触发器、系统触发器。

1 创建触发器的一般语法是:

CREATE [ OR REPLACE]TRIGGER trigger_name

[ BEFORE|AFTER ]trigger_event ON table_reference

[ FOR EACH ROW [WHEN trigger_condition] ]

trigger_body;

每张表最多可建立 12 个触发器,它们是:

before insert

before insert for each row

after insert

after insert for each row

before update

before update for each row

after update

after update for each row

before delete

before delete for each row

after delete

after delete for each row

2 触发器的限制:

。触发器中不能使用控制语句 COMMIT,ROLLBACK, SVAEPOINT 语句;

。由触发器所调用的过程或函数也不能使用控制语句;

。触发器中不能使用LONG,LONG RAW 类型;

。触发器所访问的表受到远表的约束限制,即后面的“变化表”。

3 触发器实例:

1)实现: :new 修饰符访问操作完成后列的值

:old 修饰符访问操作完成前列的值

建立一个触发器,当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去.

create or replace trigger scott.del_emp

before delete on scott.emp for each row

begin

insert into emp_his( deptno , empno, ename , job ,mgr , sal , comm , hiredate )

values( :old.deptno, :old.empno, :old.ename , :old.job,

:old.mgr, :old.sal, :old.comm, :old.hiredate );

end;

2)通过删除表行来删除视图行:

CREATE TRIGGER room_summary_delete

INSTEAD OF DELETE ON room_summary

FOR EACH ROW

BEGIN

-- 删除表 room 中行,这些行构成单个视图行。

DELETE FROM rooms WHERE building = :old.building;

END room_summary_delete;

3)建立一个当用户USERB登录时,自动记录一些信息的触发器:

CREATE OR REPLACE TRIGGER loguserAconnects

AFTER LOGON ON SCHEMA

BEGIN

INSERT INTO example.temp_table

VALUES(2,’LogUserAConnects fired!’);

END loguserBconnects;

4 触发器触发次序对事件的触发共有16种,但是它们的触发是有次序的,基本触发次序如下:

Oracle

1 1) 执行 BEFORE语句级触发器;

2 2)对与受语句影响的每一行:

a) 执行 BEFORE语句行级触发器

b) 执行 DML语句

c) 执行 AFTER行级触发器

3)执行 AFTER语句级触发器

5 删除和使能触发器

1)删除触发器的命令语法如下:

DROP TRIGGER trigger_name;

2)使触发器无效的命令是ALTER TRIGGER,它的语法如下:

ALTER TRIGGER triiger_name [DISABLE | ENABLE ];

总之,变异表是那些具有主系关系的表,对于这样的表,在Oracle触发器里进行DML操作会受到限制。

6 变异表:( mutating table ) 是被DML语句正在进行UPDATE, DELETEINSERT的表。对于触发器而言该表是定义触发器的表。

例子:

CREATE OR REPLACE TRIGGER Emp_count

AFTER DELETE ON Emp_tab

FOR EACH ROW

DECLARE

n INTEGER;

BEGIN

SELECT COUNT(*) INTO n FROM Emp_tab;

DBMS_OUTPUT.PUT_LINE( There are now || n ||

employees.);

END;

当我们输入下面语句时,会出现错误:

DELETE FROM Emp_tab WHERE Empno = 7499;

ORA-04091: table SCOTT.Emp_tab is mutating, trigger/function may not see it

7 与触发器有关的数据字典有:

user_triggers

all_triggers

dba_triggers


wj99898 发表于:2006.07.20 08:07 ::分类: ( oracle专区 ) ::阅读:(13050次) :: 评论 (0) :: 引用 (0)

2006 年 07 月 19日, 星期三

一些常见问题及技巧

常用问题

1 Oracle2000年问题

l oracle 约定

l oracle在系统中一直用YYYY:MM:DD HH24:MI:SS表示日期和时间

l ORACLE7 serverORACLE8 server提供一种年格式掩码RR

规则转换如下表:

当前年度(最后两位数) 指定的两位数年

(机器设置为)

RR返回的年

0~49 0~49

50~99 0~49

0~49 50~99

50~99 50~99

当前世纪(19XX

下个世纪(20XX

上个世纪(18XX

当前世纪(19XX

l 当前年是在5099后半世纪

1)如果输入0099之间,oracle将被记为下个世纪,如在1996年输02,则被记为2002年。

2)如果输入5099之间,oracle将被记为当前世纪,如在1996年输97,则被记为1997年。

l 当前年是在0049前半世纪

1)如果输入0049之间,oracle将被记为当前世纪,如在2001年时输02,则被记为2002年。

2)如果输入的两位年在5099之间,oracle将被记为上个世纪,如在2001年输97,则被记为1997年。

l 例子

Create table abc(datefld date)

Insert into abc Value('01-JAN-11')

Insert into abc Value('01-JAN-90')

转换成1911年和1990

Update abc

Set Datefld(d=To_date(To_datefld,'DD-MON-YY HH24:MI:SS')

'DD_MON_RR HH24:MI:SS')

Select To_char(Datefld,'DD-MON-YYYY') Datefld from abc

01-JAN-2011

01-JAN-1990

建议:2000年问题在开发中的建议任何时应采用4位年表示如果用两位一定用YYRR表示输入界面最好作判断和提示。

2 如何正确插入日期数据

许多初学者都可能遇到这样的问题,就是往DATE类型的列插入日期数据时,经常被提示错误。

比如有下面的ABC表结构:

SQL> desc abc

名称 ? 类型

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

RQ DATE

NAME VARCHAR2(20)

当用下面命令插入数据到ABC表时,系统提示如下信息:

SQL> insert into abc values('02-JAN-2002','赵元杰');

insert into abc values('02-JAN-2002','赵元杰')

*

ERROR 位于第 1 :

ORA-01843: 无效的月份

这是由于系统安装时的默认字符集引起的。虽然上面语句看上去没有错误,但是它不符合当前系统的日期格式要求。那么当前系统的日期格式是什么呢?我们可以用下面语句来查询:

SQL> select sysdate from dual;

SYSDATE

----------

01-2 -02

既然系统的日期格式是中文的月份,则将上面语句改为中文的月即可:

SQL> insert into abc values('02-2-2002','赵元杰');

已创建 1 行。

当然,你可以用alter session命令修改当前系统的日期格式为你喜欢的格式,如:

SQL> alter session set nls_date_format='yyyy/mm/dd';

会话已更改。

SQL> insert into abc values('2002/02/02','赵元杰');

已创建 1 行。

SQL> select * from abc;

RQ NAME

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

2002/02/02 赵元杰

2002/02/02 赵元杰

关于日期格式的有关资料,请参见《Oracle8I数据库管理员》--赵元杰著

3 在查询中只返回满足条件的部分记录

有时,我们关心的查询结果不是所有的记录,而是关心所查询的内容的存在性。如果我们不加特别的限制,满足条件的所有记录会源源不断地显示在屏幕上。为了只显示少量的内容,oracle提供rownum伪列来限制在查询时返回的记录数。例如:

Select * from dict where rownum < 10

Rownum是要显示的记录数

注意:

l 该用法在PL/SQLPro*C中常常不能用 ;

l 在条件中可以用 <= ,但不能用 = > 作判断。

4 快速大量删除数据Truncate

在数据库管理操作中,经常需要将某个表的所有记录都删除而只保留表结构,这样的要求如果用delete 进行删除的话,Oracle系统会自动为该操作分配回滚段。如果回滚段较小,则可能导致操作失败。即使回滚段足够大,删除操作也需要较长的时间才能完成。为了加快删除操作,Oracle提供了一个特别的命令TRUNCATE,可以快速地完成对某个表的所有记录的删除。TRUNCATE的语法如下:

TRUNCATE [TABLE | CLUSTER]

schema.[table][cluster] [DROP | REUSE STORAGE]

删除表中或簇中的所有行,REUSE STORAGE保留被删除的空间作为该表的新行使用:缺省为DROP storge 即收回被删除的空间给系统。

特点:不可恢复。即不需rollback segment,不在日志文件中记录信息。

5 Rowid的使用

l oracle为每个表的每一条记录赋予一个唯一的标识号rowid

l 它是一个伪列,虽然在定义表结构时并不声明它,但它自动地建立;

l desc查看表结构时并不显示该字段;

l ROWID 在进行UPDATEDELETE操作中速度最快;

l Oracle7Oracle8ROWID不同。

SQL>select namesexsalrowid from emp

SQL>delete from emp where rowid='...XXXX.XX.XXXX'

l Oracle7Rowid 由三个部分组成,结构为:

block.row.file

格式为:

BBBBBBBB.RRRR.FFFF

BBBBBBBB 是文件的块号;RRRR 块中的行号;FFFF是文件的绝对号。

0000000F.0000.00002

15数据块.1.第二个数据文件

l Oracle8Oracle8i/9iRowid 由四个部分组成,结构为:

OOOOOOFFFBBBBBBRRR

格式为:

l OOOOOO代表数据对象号,它表示数据库段的编号;

l FFF 代表在表空间中的相对文件号;

l BBBBBB代表在一个文件中的块号,块号与数据文件有关,与表空间无关;

l RRR代表块中行的位置号。

1:查询记录中的ROWID列的值:

SQL> select * from emp;

ENAME SAL DEPTNO TEL

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

赵元杰 9999.12 10 1360 136 5681

赵元杰 9999.12 10 1360 136 5681

2:使用ROWID删除重复的记录。由于记录每个列的值完全一样,where 条件无法辨别,但是两条记录的ROWID号是不一样的。所以可以用ROWID作为条件。详细操作如下:

1)先查出记录:

SQL> select ename,sal,deptno,tel,rowid from emp;

ENAME SAL DEPTNO TEL ROWID

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

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAB

2)看到两条记录的rowid不一样,可以使用chartorowid函数和rowid值完成删除操作:

SQL> delete from emp where rowid = chartorowid('AAAFyUAADAAAAADAAB');

已删除 1 行。

3)删除操作完成,再查看emp表的数据:

SQL> select ename,sal,deptno,tel,rowid from emp;

ENAME SAL DEPTNO TEL ROWID

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

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA

从例子中可以看出,rowid 的优势,建议在PL/SQL中的循环操作使用ROWID来提高处理速度。

6 在查询中不让记录被更新

要保证在统计(查询)执行过程中,记录不被其他用户更新,则可以使用For update子句进行加锁。这样在这个锁释放前其他用户不能对这些记录作updatedelete和加锁。

SQL>Select daptno from dept

Where deptno=25 For update

如果你使用了FOR UPDATE来对表进行加锁,组必须用commit来释放加锁的记录。

7 EXCEPTIONS(违反完整性)问题

前面介绍的主键的创建方法,如果我们对表创建了主键后,那么在查入记录时,Oracle会自动对插入数据进行唯一性检查,当出现有数据违反唯一性限定的情况时,一般用户可能只看到ORA-0001 Dup_val_on_index ( 试图破坏一个唯一性限制 ) 类似的提示,而没有看是哪条记录违反唯一性限定。为了使用户有针对性地修改违反唯一性限定的记录,Oracle提供了一种方法可以容许用户捕获那些导致限定产生失败的行的信息。方法是:

l 用户生成一个列为EXCEPTION的表,创建该表的脚本是UTLEXCPT.SQL,你可以从oracle.../rdbms/admin目录中找。如:

SQL> start c:oracleora81rdbmsadminutlexcpt

表已创建。

l 在建表时声明EXCEPTIONS

l 激活EXCEPTIONS,如:

Alter table newspaper enable primary key

Exceptions into EXCEPTIONS

EXCEPTIONS 表有四个列:

Row_ID 违反限定的各行

Ower 违反限定的拥有者

Table_name 违反限定所在的表

Constraint 行所在的限定

l 查看违反完整性的记录:

Select * form Newspaper

Where Rowid in (select Row_id from EXCEPTIONS)

注:可能原版资料上将例外的表拼写成为 except_table ,其实脚本并不是这样。下面是原版资料的例子:

ALTER TABLE emp

ENABLE VALIDATE CONSTRAINT fk_deptno

EXCEPTIONS INTO except_table;

SELECT emp.*

FROM emp e, except_table ex

WHERE e.row_id = ex.row_id

AND ex.table_name = ’EMP’

AND ex.constraint = ’FK_DEPTNO’;

8 Not inNot Exists

一般来说,在处理存在性检查中,用户都会看到Not in Not Exists 两个判断语句,但是它们在处理速度上有些不同。

Not in 速度慢

Not Exists 速度较快。

SQL>select name,depart,zip

From export

Where name not in (select name from xxx not exists

Item_application where ) and rownum<6

Order by score

9 关于 COPY命令

可以弥补 create table ... as select ... from ...的和imp,exp 的不足,主要功能有:

1) 从一个本地数据库将一个或多个表拷贝到一个远程数据库;

2) 将一个表的一些记录拷贝到远程或本地库的其它表中;

3) 将包含 long 类型的表的一些列拷贝到其他表中;

4) 从一个oracle 数据库向一个非oracle数据库的拷贝表。

wj99898 发表于:2006.07.19 13:49 ::分类: ( oracle专区 ) ::阅读:(12930次) :: 评论 (0) :: 引用 (0)

一些常见问题及技巧

常用问题

1 Oracle2000年问题

l oracle 约定

l oracle在系统中一直用YYYY:MM:DD HH24:MI:SS表示日期和时间

l ORACLE7 serverORACLE8 server提供一种年格式掩码RR

规则转换如下表:

当前年度(最后两位数) 指定的两位数年

(机器设置为)

RR返回的年

0~49 0~49

50~99 0~49

0~49 50~99

50~99 50~99

当前世纪(19XX

下个世纪(20XX

上个世纪(18XX

当前世纪(19XX

l 当前年是在5099后半世纪

1)如果输入0099之间,oracle将被记为下个世纪,如在1996年输02,则被记为2002年。

2)如果输入5099之间,oracle将被记为当前世纪,如在1996年输97,则被记为1997年。

l 当前年是在0049前半世纪

1)如果输入0049之间,oracle将被记为当前世纪,如在2001年时输02,则被记为2002年。

2)如果输入的两位年在5099之间,oracle将被记为上个世纪,如在2001年输97,则被记为1997年。

l 例子

Create table abc(datefld date)

Insert into abc Value('01-JAN-11')

Insert into abc Value('01-JAN-90')

转换成1911年和1990

Update abc

Set Datefld(d=To_date(To_datefld,'DD-MON-YY HH24:MI:SS')

'DD_MON_RR HH24:MI:SS')

Select To_char(Datefld,'DD-MON-YYYY') Datefld from abc

01-JAN-2011

01-JAN-1990

建议:2000年问题在开发中的建议任何时应采用4位年表示如果用两位一定用YYRR表示输入界面最好作判断和提示。

2 如何正确插入日期数据

许多初学者都可能遇到这样的问题,就是往DATE类型的列插入日期数据时,经常被提示错误。

比如有下面的ABC表结构:

SQL> desc abc

名称 ? 类型

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

RQ DATE

NAME VARCHAR2(20)

当用下面命令插入数据到ABC表时,系统提示如下信息:

SQL> insert into abc values('02-JAN-2002','赵元杰');

insert into abc values('02-JAN-2002','赵元杰')

*

ERROR 位于第 1 :

ORA-01843: 无效的月份

这是由于系统安装时的默认字符集引起的。虽然上面语句看上去没有错误,但是它不符合当前系统的日期格式要求。那么当前系统的日期格式是什么呢?我们可以用下面语句来查询:

SQL> select sysdate from dual;

SYSDATE

----------

01-2 -02

既然系统的日期格式是中文的月份,则将上面语句改为中文的月即可:

SQL> insert into abc values('02-2-2002','赵元杰');

已创建 1 行。

当然,你可以用alter session命令修改当前系统的日期格式为你喜欢的格式,如:

SQL> alter session set nls_date_format='yyyy/mm/dd';

会话已更改。

SQL> insert into abc values('2002/02/02','赵元杰');

已创建 1 行。

SQL> select * from abc;

RQ NAME

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

2002/02/02 赵元杰

2002/02/02 赵元杰

关于日期格式的有关资料,请参见《Oracle8I数据库管理员》--赵元杰著

3 在查询中只返回满足条件的部分记录

有时,我们关心的查询结果不是所有的记录,而是关心所查询的内容的存在性。如果我们不加特别的限制,满足条件的所有记录会源源不断地显示在屏幕上。为了只显示少量的内容,oracle提供rownum伪列来限制在查询时返回的记录数。例如:

Select * from dict where rownum < 10

Rownum是要显示的记录数

注意:

l 该用法在PL/SQLPro*C中常常不能用 ;

l 在条件中可以用 <= ,但不能用 = > 作判断。

4 快速大量删除数据Truncate

在数据库管理操作中,经常需要将某个表的所有记录都删除而只保留表结构,这样的要求如果用delete 进行删除的话,Oracle系统会自动为该操作分配回滚段。如果回滚段较小,则可能导致操作失败。即使回滚段足够大,删除操作也需要较长的时间才能完成。为了加快删除操作,Oracle提供了一个特别的命令TRUNCATE,可以快速地完成对某个表的所有记录的删除。TRUNCATE的语法如下:

TRUNCATE [TABLE | CLUSTER]

schema.[table][cluster] [DROP | REUSE STORAGE]

删除表中或簇中的所有行,REUSE STORAGE保留被删除的空间作为该表的新行使用:缺省为DROP storge 即收回被删除的空间给系统。

特点:不可恢复。即不需rollback segment,不在日志文件中记录信息。

5 Rowid的使用

l oracle为每个表的每一条记录赋予一个唯一的标识号rowid

l 它是一个伪列,虽然在定义表结构时并不声明它,但它自动地建立;

l desc查看表结构时并不显示该字段;

l ROWID 在进行UPDATEDELETE操作中速度最快;

l Oracle7Oracle8ROWID不同。

SQL>select namesexsalrowid from emp

SQL>delete from emp where rowid='...XXXX.XX.XXXX'

l Oracle7Rowid 由三个部分组成,结构为:

block.row.file

格式为:

BBBBBBBB.RRRR.FFFF

BBBBBBBB 是文件的块号;RRRR 块中的行号;FFFF是文件的绝对号。

0000000F.0000.00002

15数据块.1.第二个数据文件

l Oracle8Oracle8i/9iRowid 由四个部分组成,结构为:

OOOOOOFFFBBBBBBRRR

格式为:

l OOOOOO代表数据对象号,它表示数据库段的编号;

l FFF 代表在表空间中的相对文件号;

l BBBBBB代表在一个文件中的块号,块号与数据文件有关,与表空间无关;

l RRR代表块中行的位置号。

1:查询记录中的ROWID列的值:

SQL> select * from emp;

ENAME SAL DEPTNO TEL

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

赵元杰 9999.12 10 1360 136 5681

赵元杰 9999.12 10 1360 136 5681

2:使用ROWID删除重复的记录。由于记录每个列的值完全一样,where 条件无法辨别,但是两条记录的ROWID号是不一样的。所以可以用ROWID作为条件。详细操作如下:

1)先查出记录:

SQL> select ename,sal,deptno,tel,rowid from emp;

ENAME SAL DEPTNO TEL ROWID

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

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAB

2)看到两条记录的rowid不一样,可以使用chartorowid函数和rowid值完成删除操作:

SQL> delete from emp where rowid = chartorowid('AAAFyUAADAAAAADAAB');

已删除 1 行。

3)删除操作完成,再查看emp表的数据:

SQL> select ename,sal,deptno,tel,rowid from emp;

ENAME SAL DEPTNO TEL ROWID

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

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA

从例子中可以看出,rowid 的优势,建议在PL/SQL中的循环操作使用ROWID来提高处理速度。

6 在查询中不让记录被更新

要保证在统计(查询)执行过程中,记录不被其他用户更新,则可以使用For update子句进行加锁。这样在这个锁释放前其他用户不能对这些记录作updatedelete和加锁。

SQL>Select daptno from dept

Where deptno=25 For update

如果你使用了FOR UPDATE来对表进行加锁,组必须用commit来释放加锁的记录。

7 EXCEPTIONS(违反完整性)问题

前面介绍的主键的创建方法,如果我们对表创建了主键后,那么在查入记录时,Oracle会自动对插入数据进行唯一性检查,当出现有数据违反唯一性限定的情况时,一般用户可能只看到ORA-0001 Dup_val_on_index ( 试图破坏一个唯一性限制 ) 类似的提示,而没有看是哪条记录违反唯一性限定。为了使用户有针对性地修改违反唯一性限定的记录,Oracle提供了一种方法可以容许用户捕获那些导致限定产生失败的行的信息。方法是:

l 用户生成一个列为EXCEPTION的表,创建该表的脚本是UTLEXCPT.SQL,你可以从oracle.../rdbms/admin目录中找。如:

SQL> start c:oracleora81rdbmsadminutlexcpt

表已创建。

l 在建表时声明EXCEPTIONS

l 激活EXCEPTIONS,如:

Alter table newspaper enable primary key

Exceptions into EXCEPTIONS

EXCEPTIONS 表有四个列:

Row_ID 违反限定的各行

Ower 违反限定的拥有者

Table_name 违反限定所在的表

Constraint 行所在的限定

l 查看违反完整性的记录:

Select * form Newspaper

Where Rowid in (select Row_id from EXCEPTIONS)

注:可能原版资料上将例外的表拼写成为 except_table ,其实脚本并不是这样。下面是原版资料的例子:

ALTER TABLE emp

ENABLE VALIDATE CONSTRAINT fk_deptno

EXCEPTIONS INTO except_table;

SELECT emp.*

FROM emp e, except_table ex

WHERE e.row_id = ex.row_id

AND ex.table_name = ’EMP’

AND ex.constraint = ’FK_DEPTNO’;

8 Not inNot Exists

一般来说,在处理存在性检查中,用户都会看到Not in Not Exists 两个判断语句,但是它们在处理速度上有些不同。

Not in 速度慢

Not Exists 速度较快。

SQL>select name,depart,zip

From export

Where name not in (select name from xxx not exists

Item_application where ) and rownum<6

Order by score

9 关于 COPY命令

可以弥补 create table ... as select ... from ...的和imp,exp 的不足,主要功能有:

1) 从一个本地数据库将一个或多个表拷贝到一个远程数据库;

2) 将一个表的一些记录拷贝到远程或本地库的其它表中;

3) 将包含 long 类型的表的一些列拷贝到其他表中;

4) 从一个oracle 数据库向一个非oracle数据库的拷贝表。

wj99898 发表于:2006.07.19 13:49 ::分类: ( oracle专区 ) ::阅读:(12926次) :: 评论 (0) :: 引用 (0)

一些常见问题及技巧

常用问题

1 Oracle2000年问题

l oracle 约定

l oracle在系统中一直用YYYY:MM:DD HH24:MI:SS表示日期和时间

l ORACLE7 serverORACLE8 server提供一种年格式掩码RR

规则转换如下表:

当前年度(最后两位数) 指定的两位数年

(机器设置为)

RR返回的年

0~49 0~49

50~99 0~49

0~49 50~99

50~99 50~99

当前世纪(19XX

下个世纪(20XX

上个世纪(18XX

当前世纪(19XX

l 当前年是在5099后半世纪

1)如果输入0099之间,oracle将被记为下个世纪,如在1996年输02,则被记为2002年。

2)如果输入5099之间,oracle将被记为当前世纪,如在1996年输97,则被记为1997年。

l 当前年是在0049前半世纪

1)如果输入0049之间,oracle将被记为当前世纪,如在2001年时输02,则被记为2002年。

2)如果输入的两位年在5099之间,oracle将被记为上个世纪,如在2001年输97,则被记为1997年。

l 例子

Create table abc(datefld date)

Insert into abc Value('01-JAN-11')

Insert into abc Value('01-JAN-90')

转换成1911年和1990

Update abc

Set Datefld(d=To_date(To_datefld,'DD-MON-YY HH24:MI:SS')

'DD_MON_RR HH24:MI:SS')

Select To_char(Datefld,'DD-MON-YYYY') Datefld from abc

01-JAN-2011

01-JAN-1990

建议:2000年问题在开发中的建议任何时应采用4位年表示如果用两位一定用YYRR表示输入界面最好作判断和提示。

2 如何正确插入日期数据

许多初学者都可能遇到这样的问题,就是往DATE类型的列插入日期数据时,经常被提示错误。

比如有下面的ABC表结构:

SQL> desc abc

名称 ? 类型

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

RQ DATE

NAME VARCHAR2(20)

当用下面命令插入数据到ABC表时,系统提示如下信息:

SQL> insert into abc values('02-JAN-2002','赵元杰');

insert into abc values('02-JAN-2002','赵元杰')

*

ERROR 位于第 1 :

ORA-01843: 无效的月份

这是由于系统安装时的默认字符集引起的。虽然上面语句看上去没有错误,但是它不符合当前系统的日期格式要求。那么当前系统的日期格式是什么呢?我们可以用下面语句来查询:

SQL> select sysdate from dual;

SYSDATE

----------

01-2 -02

既然系统的日期格式是中文的月份,则将上面语句改为中文的月即可:

SQL> insert into abc values('02-2-2002','赵元杰');

已创建 1 行。

当然,你可以用alter session命令修改当前系统的日期格式为你喜欢的格式,如:

SQL> alter session set nls_date_format='yyyy/mm/dd';

会话已更改。

SQL> insert into abc values('2002/02/02','赵元杰');

已创建 1 行。

SQL> select * from abc;

RQ NAME

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

2002/02/02 赵元杰

2002/02/02 赵元杰

关于日期格式的有关资料,请参见《Oracle8I数据库管理员》--赵元杰著

3 在查询中只返回满足条件的部分记录

有时,我们关心的查询结果不是所有的记录,而是关心所查询的内容的存在性。如果我们不加特别的限制,满足条件的所有记录会源源不断地显示在屏幕上。为了只显示少量的内容,oracle提供rownum伪列来限制在查询时返回的记录数。例如:

Select * from dict where rownum < 10

Rownum是要显示的记录数

注意:

l 该用法在PL/SQLPro*C中常常不能用 ;

l 在条件中可以用 <= ,但不能用 = > 作判断。

4 快速大量删除数据Truncate

在数据库管理操作中,经常需要将某个表的所有记录都删除而只保留表结构,这样的要求如果用delete 进行删除的话,Oracle系统会自动为该操作分配回滚段。如果回滚段较小,则可能导致操作失败。即使回滚段足够大,删除操作也需要较长的时间才能完成。为了加快删除操作,Oracle提供了一个特别的命令TRUNCATE,可以快速地完成对某个表的所有记录的删除。TRUNCATE的语法如下:

TRUNCATE [TABLE | CLUSTER]

schema.[table][cluster] [DROP | REUSE STORAGE]

删除表中或簇中的所有行,REUSE STORAGE保留被删除的空间作为该表的新行使用:缺省为DROP storge 即收回被删除的空间给系统。

特点:不可恢复。即不需rollback segment,不在日志文件中记录信息。

5 Rowid的使用

l oracle为每个表的每一条记录赋予一个唯一的标识号rowid

l 它是一个伪列,虽然在定义表结构时并不声明它,但它自动地建立;

l desc查看表结构时并不显示该字段;

l ROWID 在进行UPDATEDELETE操作中速度最快;

l Oracle7Oracle8ROWID不同。

SQL>select namesexsalrowid from emp

SQL>delete from emp where rowid='...XXXX.XX.XXXX'

l Oracle7Rowid 由三个部分组成,结构为:

block.row.file

格式为:

BBBBBBBB.RRRR.FFFF

BBBBBBBB 是文件的块号;RRRR 块中的行号;FFFF是文件的绝对号。

0000000F.0000.00002

15数据块.1.第二个数据文件

l Oracle8Oracle8i/9iRowid 由四个部分组成,结构为:

OOOOOOFFFBBBBBBRRR

格式为:

l OOOOOO代表数据对象号,它表示数据库段的编号;

l FFF 代表在表空间中的相对文件号;

l BBBBBB代表在一个文件中的块号,块号与数据文件有关,与表空间无关;

l RRR代表块中行的位置号。

1:查询记录中的ROWID列的值:

SQL> select * from emp;

ENAME SAL DEPTNO TEL

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

赵元杰 9999.12 10 1360 136 5681

赵元杰 9999.12 10 1360 136 5681

2:使用ROWID删除重复的记录。由于记录每个列的值完全一样,where 条件无法辨别,但是两条记录的ROWID号是不一样的。所以可以用ROWID作为条件。详细操作如下:

1)先查出记录:

SQL> select ename,sal,deptno,tel,rowid from emp;

ENAME SAL DEPTNO TEL ROWID

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

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAB

2)看到两条记录的rowid不一样,可以使用chartorowid函数和rowid值完成删除操作:

SQL> delete from emp where rowid = chartorowid('AAAFyUAADAAAAADAAB');

已删除 1 行。

3)删除操作完成,再查看emp表的数据:

SQL> select ename,sal,deptno,tel,rowid from emp;

ENAME SAL DEPTNO TEL ROWID

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

赵元杰 9999.12 10 1360 136 5681 AAAFyUAADAAAAADAAA

从例子中可以看出,rowid 的优势,建议在PL/SQL中的循环操作使用ROWID来提高处理速度。

6 在查询中不让记录被更新

要保证在统计(查询)执行过程中,记录不被其他用户更新,则可以使用For update子句进行加锁。这样在这个锁释放前其他用户不能对这些记录作updatedelete和加锁。

SQL>Select daptno from dept

Where deptno=25 For update

如果你使用了FOR UPDATE来对表进行加锁,组必须用commit来释放加锁的记录。

7 EXCEPTIONS(违反完整性)问题

前面介绍的主键的创建方法,如果我们对表创建了主键后,那么在查入记录时,Oracle会自动对插入数据进行唯一性检查,当出现有数据违反唯一性限定的情况时,一般用户可能只看到ORA-0001 Dup_val_on_index ( 试图破坏一个唯一性限制 ) 类似的提示,而没有看是哪条记录违反唯一性限定。为了使用户有针对性地修改违反唯一性限定的记录,Oracle提供了一种方法可以容许用户捕获那些导致限定产生失败的行的信息。方法是:

l 用户生成一个列为EXCEPTION的表,创建该表的脚本是UTLEXCPT.SQL,你可以从oracle.../rdbms/admin目录中找。如:

SQL> start c:oracleora81rdbmsadminutlexcpt

表已创建。

l 在建表时声明EXCEPTIONS

l 激活EXCEPTIONS,如:

Alter table newspaper enable primary key

Exceptions into EXCEPTIONS

EXCEPTIONS 表有四个列:

Row_ID 违反限定的各行

Ower 违反限定的拥有者

Table_name 违反限定所在的表

Constraint 行所在的限定

l 查看违反完整性的记录:

Select * form Newspaper

Where Rowid in (select Row_id from EXCEPTIONS)

注:可能原版资料上将例外的表拼写成为 except_table ,其实脚本并不是这样。下面是原版资料的例子:

ALTER TABLE emp

ENABLE VALIDATE CONSTRAINT fk_deptno

EXCEPTIONS INTO except_table;

SELECT emp.*

FROM emp e, except_table ex

WHERE e.row_id = ex.row_id

AND ex.table_name = ’EMP’

AND ex.constraint = ’FK_DEPTNO’;

8 Not inNot Exists

一般来说,在处理存在性检查中,用户都会看到Not in Not Exists 两个判断语句,但是它们在处理速度上有些不同。

Not in 速度慢

Not Exists 速度较快。

SQL>select name,depart,zip

From export

Where name not in (select name from xxx not exists

Item_application where ) and rownum<6

Order by score

9 关于 COPY命令

可以弥补 create table ... as select ... from ...的和imp,exp 的不足,主要功能有:

1) 从一个本地数据库将一个或多个表拷贝到一个远程数据库;

2) 将一个表的一些记录拷贝到远程或本地库的其它表中;

3) 将包含 long 类型的表的一些列拷贝到其他表中;

4) 从一个oracle 数据库向一个非oracle数据库的拷贝表。

wj99898 发表于:2006.07.19 13:49 ::分类: ( oracle专区 ) ::阅读:(13004次) :: 评论 (0) ::