|
常用鏈接
留言簿
隨筆檔案
搜索
最新評(píng)論

閱讀排行榜
評(píng)論排行榜
Powered by: 博客園
模板提供:滬江博客
|
|
|
|
|
發(fā)新文章 |
|
|
2012年11月21日
我能抽象出整個(gè)世界..  . 但是我卻不能抽象出你... 你肯定是一個(gè)單例,因?yàn)槟闶悄菢拥莫?dú)一無(wú)二... 所以我的世界并不完整... 我可以重載甚至覆蓋這個(gè)世界里的任何一種方法... 但是卻不能覆蓋對(duì)你的思念... 也許命中注定了 你與我存在于不同的包里... 在你的世界里,你被烙上了私有的屬性... 我用盡全身力氣,也找不到訪問(wèn)你的接口... 我不愿就此甘心,找到了藏身在javaeye神殿的巫師,教會(huì)了我穿越時(shí)空的方法... 終于,我用反射這把利劍,打開(kāi)了你空間的缺口... 并發(fā)現(xiàn)了接近你的秘密... 當(dāng)我迫不及待地調(diào)用了愛(ài)你這個(gè)方法... 并義無(wú)返顧的把自己作為參數(shù)傳進(jìn)這個(gè)方法時(shí)... 我才發(fā)現(xiàn)愛(ài)上你是一個(gè)沒(méi)有終止條件的遞歸... 它不停的返回我對(duì)你的思念并壓入我心里的堆棧... 在這無(wú)盡的黑夜中 , tb終于體驗(yàn)到你對(duì)我愛(ài)的回調(diào)... 我的內(nèi)存里已經(jīng)再也裝不下別人... 當(dāng)我以為將與你在這個(gè)死循環(huán)中天荒地老時(shí)... 萬(wàn)惡的系統(tǒng)拋出了愛(ài)的異常... 此刻我才發(fā)現(xiàn),我不過(guò)是操縱于虛擬機(jī)下的一個(gè)線程,你也是... 但我毫不后悔,因?yàn)樵趷?ài)的洗禮之后... 我看見(jiàn)了一個(gè)新的生命,那是我們的, 繼承
2012年11月5日
線程是Java語(yǔ)言的一個(gè)部分,而且是Java的最強(qiáng)大的功能之一。究竟什么是線程,為什么要開(kāi)發(fā)基于線程的應(yīng)用程序?在本文中,我們將深入了解一下線程的用法,以及使用線程的一些技術(shù)。在我們開(kāi)始講述線程之前,最好先了解一下有關(guān)背景知識(shí)和分析一下線程的工作原理。
當(dāng)程序員一開(kāi)始開(kāi)發(fā)應(yīng)用程序時(shí),這些應(yīng)用程序只能在一個(gè)時(shí)間內(nèi)完成一件事情。應(yīng)用程序從主程序開(kāi)始執(zhí)行,直到運(yùn)行結(jié)束,像 Fortran/Cobol/Basic這些語(yǔ)言均是如此。
隨著時(shí)間的推移,計(jì)算機(jī)發(fā)展到可以在同一時(shí)間段內(nèi)運(yùn)行不止一個(gè)應(yīng)用程序的時(shí)代了,但是應(yīng)用程序運(yùn)行時(shí)仍然是串行的,即從開(kāi)始運(yùn)行到結(jié)束,下一條指令接著上一條指令執(zhí)行。到最近,程序發(fā)展到可以在執(zhí)行時(shí),以若干個(gè)線程的形式運(yùn)行。Java就具有運(yùn)行多線程的能力,可以在同一時(shí)間段內(nèi)進(jìn)行幾個(gè)操作,這就意味著給定的操作不必等到另外一個(gè)操作結(jié)束之后,才能開(kāi)始。而且對(duì)某個(gè)操作可以指定更高一級(jí)的優(yōu)先級(jí)。
不少程序語(yǔ)言,包括ADA, Modula-2和C/C++,已經(jīng)可以提供對(duì)線程的支持。同這些語(yǔ)言相比,Java的特點(diǎn)是從最底層開(kāi)始就對(duì)線程提供支持。除此以外,標(biāo)準(zhǔn)的Java類(lèi)是可重入的,允許在一個(gè)給定的應(yīng)用程序中由多個(gè)線程調(diào)用同一方法,tb而線程彼此之間又互不干擾。Java的這些特點(diǎn)為多線程應(yīng)用程序的設(shè)計(jì)奠定了基礎(chǔ)。
什么是線程?
究竟什么是線程呢?正如在圖A中所示,一個(gè)線程是給定的指令的序列 (你所編寫(xiě)的代碼),一個(gè)棧(在給定的方法中定義的變量),以及一些共享數(shù)據(jù)(類(lèi)一級(jí)的變量)。線程也可以從全局類(lèi)中訪問(wèn)靜態(tài)數(shù)據(jù)。
#g_kclist{font-size:12px;width:570px;float:none; margin-top:5px; clear:right}
#g_kclist a{color:#000; text-decoration:none}
#g_kclist h2{margin:0px;padding:0px;font-size:14px; text-align:center;background:url(http://www.thea.cn/zt/zt_img/zczhongduan.gif) no-repeat;line-height:31px;color:#fff}
#g_kclist table{line-height:25px;background:#B0DA90;margin-top:8px}
#g_kclist table td{ text-align:center;background:#fff}
#g_kclist table td.td1 a{color:#f00}
#g_kclist table th{background:#F2F7ED;color:#525F46}
2012年10月23日
有多種方法的,我只說(shuō)兩種最簡(jiǎn)單的。 一、定義數(shù)據(jù)源sql時(shí),定義一個(gè)變量:xb,然后數(shù)據(jù)源寫(xiě)成: select * from [運(yùn)動(dòng)員表] where [性別]=:xb 再?gòu)拇翱诘膐pen事件中寫(xiě): dw_1.settransobject(sqlca) dw_1.retrieve('男')//把變量傳給數(shù)據(jù)窗口,只刷出男生。 即可實(shí)現(xiàn)。 二、定義數(shù)據(jù)源sql時(shí),直接寫(xiě)成: select * from [運(yùn)動(dòng)員表] 窗口的open事件中寫(xiě): dw_1.settransobejct(sqlca) dw_1.retrieve()//這句是刷新出所有的運(yùn)動(dòng)員,包括男女 dw_1.setfilter("[性別]='男'")//為數(shù)據(jù)窗口設(shè)置過(guò)濾 dw_1.filter()//使用過(guò)濾字符串過(guò)濾數(shù)據(jù) 也可以實(shí)現(xiàn)你所要求的。 是不是數(shù)據(jù)窗口的行高不夠(這個(gè)會(huì)擋住每行數(shù)據(jù)的一點(diǎn)點(diǎn)), 還有可能是details的band tb向下拖拖 多放點(diǎn)空間 (這個(gè)肯能擋住最下面的數(shù)據(jù))
2012年10月17日
找到了問(wèn)題產(chǎn)生的原因后,下面來(lái)討論如何解決該問(wèn)題。對(duì)于Oracle Enterprise Manager中的所有工具,有一個(gè)配置文件名為dbappscfg.properties,修改該文件即可解決上述問(wèn)題。這個(gè)文件的位置在$ORACLE_HOME\sysman\config目錄下,用任何的文本編輯器打開(kāi)該文件,在這個(gè)文件里面,找到這樣一項(xiàng),
# SQLPLUS_NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
去掉注釋符#,同時(shí)將其修改為
SQLPLUS_NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
對(duì)于Windows操作系統(tǒng),還需要修改一項(xiàng),在文件中找到# SQLPLUS_SYSTEMROOT=c:\\WINNT40,去掉注釋符,將其修改為你所在機(jī)器的操作系統(tǒng)主目錄。如操作系統(tǒng)的主目錄在D盤(pán)的Winnt下,則將其修改為
SQLPLUS_SYSTEMROOT=d:\\WINNT。
對(duì)于后面一項(xiàng)的修改只對(duì)Windows操作系統(tǒng)進(jìn)行,對(duì)UNIX操作系統(tǒng)則不需要。如果在Windows操作系統(tǒng)中不修改該項(xiàng),在Oracle Enterprise Manager中,連接系統(tǒng)時(shí),會(huì)提示如下的錯(cuò)誤:
ORA-12560 TNS:protocol adapter error
或者
ORA-12545 Connect failed because target host or objectb does not exist
修改完成后,保存文件,退出編輯。重新連接SQL PLUS Worksheet,字符集亂碼問(wèn)題得到解決,顯示正確的簡(jiǎn)體中文字符集。
.item-area{width:578px;margin:15px auto;border-top:1px solid #ddd;color:#666}
.item-area a,.item-area a:link,.item-area a:visited{color:#666;text-decoration:none}
.item-area a:hover{color:#3a7ad9;text-decoration:underline;}
a img{border:none;vertical-align:middle}
.item-area h2,.item-area h3{float:none;font-size:100%;font-weight:normal;}
.item-area .h2{height:25px;margin:10px 0;padding-left:35px;*float:left;font:bold 14px/25px "宋體";background:url(http://sns.thea.cn/module/images/icos.png) no-repeat 0 0}
.item-area span.more{float:right;font:normal 12px/25px "宋體"}
.item-area a.more{float:right;font:normal 12px/25px "宋體"}
.item-a{margin-bottom:15px}
.item-a .h-ksrm{background-position:0 0}
.item-a li{*display:inline;overflow:hidden;zoom:1;line-height:2em;padding-left:35px;font-size:14px;background: url(http://sns.thea.cn/module/images/btns.png) no-repeat -1px -28px;}
.item-a li a{float:left;}
.item-a .testBtn{float:right;width:58px;height:21px;line-height:21px;font-size:12px;margin-top:5px;margin-top:3px;text-align:center;background:url(http://sns.thea.cn/module/images/btns.png) no-repeat -1px -1px; color:#FFFFFF;}
.item-a a.freeBtn{width:20px;margin:0 0 0 6px;line-height:28px;color:#fff;font-size:12px;text-indent:-9999px;background: url(http://sns.thea.cn/module/images/icos.png) no-repeat 0 -131px;}
.item-a li.hots a.freeBtn{background-position:0 -105px}
.item-a a.examnum em{font-style:normal;color:red;font-weight:bold;}
.item-b {padding:5px 0 20px;border-top:1px dashed #ddd;border-bottom:1px dashed #ddd}
.xsjl-list-col3s li{display:table-cell;*display:inline;zoom:1;vertical-align:top;width:182px;padding-right:10px;line-height:150%;font-size:12px;}
.item-b .h-xsjl{background-position:0 -26px}
.item-b .pic{float:left;margin:3px 10px 0 0;}
.item-b em{font-style:normal;color:#dc2c2c}
.item-b a.join{display:inline-block;padding-left:20px;background:url(http://sns.thea.cn/module/images/icos.png) no-repeat 0 -160px}
.item-b .xsjl-list-col3s h3 a{display:inline-block;width:120px;overflow:hidden;white-space:nowrap;color:#3a7ad9}
.item-b .xsjl-list-col3s h3{text-align:left;line-height:150%;font-family:"宋體","微軟雅黑"}
2012年9月21日
我的myoracle.txt腳本內(nèi)容如下:
drop procedure PRO_RECEIPTSTOCK_5D19A;
create or replace procedure PRO_RECEIPTSTOCK_5D19A IS
v_STOCKID NUMBER(13);
v_STARTNO VARCHAR2(10);
v_ENDNO VARCHAR2(10);
v_RECEIPTTYPE NUMBER(13);
v_STATUS CHAR(1);
v_COUNT NUMBER(13);
v_UNITID NUMBER(13);
V_RELATEUSERNAME VARCHAR2(150);
V_GLIDENUM NUMBER(20);
V_FLAG VARCHAR2(2);
V_PROCTM DATE;
V_SPROCTM VARCHAR2(30);
V_REGISTERTM DATE;
V_SREGISTERTM VARCHAR2(30);
V_DBUSER VARCHAR2(20);
V_CURSQL VARCHAR2(4000);
V_MYCOUNT NUMBER;
CURSOR C_RECEIPTSTOCK_TMP IS
SELECT
STOCKID,
STARTNO,
ENDNO,
RECEIPTTYPE,
STATUS,
COUNT,
UNITID,
RELATEUSERNAME,
GLIDENUM,
FLAG,
PROCTM,
REGISTERTM,
DBUSER
FROM GFMIS_ALL.RECEIPTSTOCK_5D19A_TMP
WHERE
ZTOF_STATUS = '1'
AND DBUSER IS NOT NULL;
begin
--把票據(jù)類(lèi)型為5D的繳款書(shū)在庫(kù)存中更新成一般繳款書(shū)
UPDATE GFMIS_ALL.RECEIPTSTOCK T SET T.RECEIPTTYPE=4765 WHERE EXISTS (SELECT 1 FROM GFMIS_ALL.RECEIPTSTOCK_5D19A_TMP TT WHERE TT.STOCKID = substr(T.STOCKID, 4, length(TRIM(T.STOCKID))) AND TT.ZTOF_STATUS = '1' AND TT.RECEIPTTYPE=11533);
OPEN C_RECEIPTSTOCK_TMP;
LOOP
FETCH C_RECEIPTSTOCK_TMP INTO v_STOCKID,
v_STARTNO,
v_ENDNO,
v_RECEIPTTYPE,
v_STATUS,
v_COUNT,
v_UNITID,
V_RELATEUSERNAME,
V_GLIDENUM,
V_FLAG,
V_PROCTM,
V_REGISTERTM,
V_DBUSER;
EXIT WHEN C_RECEIPTSTOCK_TMP%NOTFOUND;
V_CURSQL := 'SELECT COUNT(1) FROM ' || V_DBUSER || '.RECEIPTSTOCK WHERE STOCKID = ' || v_STOCKID;
EXECUTE IMMEDIATE V_CURSQL INTO V_MYCOUNT;
IF (V_MYCOUNT = 0) THEN
V_SPROCTM :=TO_CHAR(V_PROCTM,'YYYY-MM-DD HH24:MI:SS');
V_SREGISTERTM :=TO_CHAR(V_REGISTERTM,'YYYY-MM-DD HH24:MI:SS');
IF (v_RECEIPTTYPE = 11533) THEN
v_RECEIPTTYPE := 4765;
END IF;
V_CURSQL :='INSERT INTO ' || V_DBUSER || '.RECEIPTSTOCK (STOCKID,STARTNO,ENDNO,RECEIPTTYPE,STATUS,COUNT,UNITID,RELATEUSERNAME,GLIDENUM,FLAG,PROCTM,REGISTERTM) VALUES (' || v_STOCKID || ',''' || v_STARTNO || ''',''' || v_ENDNO || ''',' || v_RECEIPTTYPE || ',''' || v_STATUS || ''',' || v_COUNT || ',' || 1 || ',''' || V_RELATEUSERNAME || ''',' || NVL(V_GLIDENUM, 0) || ',''' || V_FLAG || ''', TO_DATE(''' || V_SPROCTM || ''',''YYYY-MM-DD HH24:MI:SS''), TO_DATE(''' || V_SREGISTERTM || ''',''YYYY-MM-DD HH24:MI:SS''))';
EXECUTE IMMEDIATE V_CURSQL;
UPDATE GFMIS_ALL.RECEIPTSTOCK_5D19A_TMP T SET T.ZTOF_STATUS = '0' WHERE T.STOCKID = v_STOCKID AND T.ZTOF_STATUS = '1';
DELETE FROM GFMIS.RECEIPTSTOCK WHERE STOCKID = v_STOCKID;
END IF;
END LOOP;
UPDATE GFMIS_ALL.RECEIPTSTOCK_5D19A_TMP T SET T.ZTOF_STATUS = '0' WHERE T.ZTOF_STATUS = '1' AND T.RECEIPTTYPE=11533;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
CLOSE C_RECEIPTSTOCK_TMP;
dbms_output.put_line(SQLERRM);
IF C_RECEIPTSTOCK_TMP%ISOPEN THEN
CLOSE C_RECEIPTSTOCK_TMP;
END IF;
RAISE;
end PRO_RECEIPTSTOCK_5D19A;
/
DROP TRIGGER TRI_RECEIPTSTOCK_CHG_AFT;
CREATE OR REPLACE TRIGGER TRI_RECEIPTSTOCK_CHG_AFT
AFTER DELETE OR INSERT OR UPDATE
ON RECEIPTSTOCK
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
curTable varchar2(50);
curType char(1);
curTime TimeStamp;
id number(13);
curID number(13);
curSQL varchar2(4000);
curUser varchar2(30);
v_distno varchar2(30);
v_dbuser varchar2(30);
v_mycount number(13);
BEGIN
IF (INSERTING) THEN
--把票據(jù)類(lèi)型為5DTB的繳款書(shū)在庫(kù)存中更新成一般繳款書(shū) 或者 把指定的19個(gè)單位的庫(kù)存移到分庫(kù)里面
SELECT COUNT(1) INTO v_mycount FROM GFMIS_ALL.RECEIPTSTOCK_DISTRICT T WHERE T.UNITID = :NEW.UNITID;
IF (v_mycount > 0) THEN
SELECT T.DBUSER INTO v_dbuser FROM GFMIS_ALL.RECEIPTSTOCK_DISTRICT T WHERE T.UNITID = :NEW.UNITID;
curSQL := 'SELECT COUNT(1) FROM ' || v_dbuser || '.RECEIPTSTOCK WHERE UNITID = ' || substr(:NEW.UNITID, 4, length(TRIM(:NEW.UNITID))) || ' AND RECEIPTTYPE = ' || :NEW.RECEIPTTYPE || ' AND STARTNO <= ''' || :NEW.STARTNO || ''' AND ENDNO >= ''' || :NEW.ENDNO || '';
EXECUTE IMMEDIATE curSQL INTO v_mycount;
if (v_mycount = 0) then
INSERT INTO GFMIS_ALL.RECEIPTSTOCK_5D19A_TMP (STOCKID,STARTNO,ENDNO,RECEIPTTYPE,STATUS,COUNT,UNITID,RELATEUSERNAME,GLIDENUM,FLAG,PROCTM,REGISTERTM,DBUSER,ZTOF_STATUS) VALUES (substr(:NEW.STOCKID, 4, length(TRIM(:NEW.STOCKID))),:NEW.STARTNO,:NEW.ENDNO,:NEW.RECEIPTTYPE,:NEW.STATUS,:NEW.COUNT,substr(:NEW.UNITID, 4, length(TRIM(:NEW.UNITID))),:NEW.RELATEUSERNAME,:NEW.GLIDENUM,:NEW.FLAG,:NEW.PROCTM,:NEW.REGISTERTM,v_dbuser,'1');
end if;
END IF;
IF (:NEW.RECEIPTTYPE = 11533) THEN
INSERT INTO GFMIS_ALL.RECEIPTSTOCK_5D19A_TMP (STOCKID,STARTNO,ENDNO,RECEIPTTYPE,STATUS,COUNT,UNITID,RELATEUSERNAME,GLIDENUM,FLAG,PROCTM,REGISTERTM,DBUSER,ZTOF_STATUS) VALUES (substr(:NEW.STOCKID, 4, length(TRIM(:NEW.STOCKID))),:NEW.STARTNO,:NEW.ENDNO,:NEW.RECEIPTTYPE,:NEW.STATUS,:NEW.COUNT,substr(:NEW.UNITID, 4, length(TRIM(:NEW.UNITID))),:NEW.RELATEUSERNAME,:NEW.GLIDENUM,:NEW.FLAG,:NEW.PROCTM,:NEW.REGISTERTM,NULL,'1');
END IF;
END IF;
select seq_exchange_temp.nextval into id from dual;
curUser :=lower(SYS_CONTEXT('userenv', 'session_user'));
if (curUser != 'all_exchange_user') then
SELECT CURRENT_TIMESTAMP INTO curTime FROM DUAL;
curTable := 'RECEIPTSTOCK';
if (deleting) then
v_distno:=substr(:OLD.STOCKID,2,2);
select dbuser into v_dbuser from GFMIS_ALL.DISTRICT where distno=v_distno;
curType := '3';
curID := :OLD.stockid;
if (curUser = 'gfmis_all') then
curSQL := 'SP_EX_RECEIPTSTOCK_DEL(''' || :OLD.STOCKID || ''')';
else
curSQL := 'SP_EX_RECEIPTSTOCK_DEL(''' || substr(:OLD.STOCKID,4) || ''')';
end if;
end if;
if (updating) then
v_distno:=substr(:OLD.STOCKID,2,2);
select dbuser into v_dbuser from GFMIS_ALL.DISTRICT where distno=v_distno;
curType := '2';
curID := :OLD.stockid;
if (curUser = 'gfmis_all') then
curSQL := 'SP_EX_RECEIPTSTOCK_UPD(''' || :OLD.STOCKID || ''', ''' || :NEW.COUNT || ''', ''' || FN_FMT_SQL(:NEW.ENDNO) || ''', ''' || FN_FMT_SQL(:NEW.FLAG) || ''', ''' || :NEW.GLIDENUM || ''', ''' || TO_CHAR(:NEW.PROCTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || :NEW.RECEIPTTYPE || ''', ''' || TO_CHAR(:NEW.REGISTERTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || FN_FMT_SQL(:NEW.RELATEUSERNAME) || ''', ''' || FN_FMT_SQL(:NEW.STARTNO) || ''', ''' || FN_FMT_SQL(:NEW.STATUS) || ''', ''' || :NEW.STOCKID || ''', ''' || :NEW.UNITID || ''')';
else
curSQL := 'SP_EX_RECEIPTSTOCK_UPD(''' || substr(:OLD.STOCKID,4) || ''', ''' || :NEW.COUNT || ''', ''' || FN_FMT_SQL(:NEW.ENDNO) || ''', ''' || FN_FMT_SQL(:NEW.FLAG) || ''', ''' || :NEW.GLIDENUM || ''', ''' || TO_CHAR(:NEW.PROCTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || :NEW.RECEIPTTYPE || ''', ''' || TO_CHAR(:NEW.REGISTERTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || FN_FMT_SQL(:NEW.RELATEUSERNAME) || ''', ''' || FN_FMT_SQL(:NEW.STARTNO) || ''', ''' || FN_FMT_SQL(:NEW.STATUS) || ''', ''' || substr(:NEW.STOCKID ,4) || ''', ''' || substr(:NEW.UNITID ,4) || ''')';
end if;
end if;
if (inserting) then
v_distno:=substr(:NEW.STOCKID,2,2);
select dbuser into v_dbuser from GFMIS_ALL.DISTRICT where distno=v_distno;
curType := '1';
curID := :NEW.stockid;
if (curUser = 'gfmis_all') then
curSQL := 'SP_EX_RECEIPTSTOCK_INS(''' || :NEW.COUNT || ''', ''' || FN_FMT_SQL(:NEW.ENDNO) || ''', ''' || FN_FMT_SQL(:NEW.FLAG) || ''', ''' || :NEW.GLIDENUM || ''', ''' || TO_CHAR(:NEW.PROCTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || :NEW.RECEIPTTYPE || ''', ''' || TO_CHAR(:NEW.REGISTERTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || FN_FMT_SQL(:NEW.RELATEUSERNAME) || ''', ''' || FN_FMT_SQL(:NEW.STARTNO) || ''', ''' || FN_FMT_SQL(:NEW.STATUS) || ''', ''' || :NEW.STOCKID || ''', ''' || :NEW.UNITID || ''')';
else
curSQL := 'SP_EX_RECEIPTSTOCK_INS(''' || :NEW.COUNT || ''', ''' || FN_FMT_SQL(:NEW.ENDNO) || ''', ''' || FN_FMT_SQL(:NEW.FLAG) || ''', ''' || :NEW.GLIDENUM || ''', ''' || TO_CHAR(:NEW.PROCTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || :NEW.RECEIPTTYPE || ''', ''' || TO_CHAR(:NEW.REGISTERTM,'YYYY-MM-DD HH24:MI:SS') || ''', ''' || FN_FMT_SQL(:NEW.RELATEUSERNAME) || ''', ''' || FN_FMT_SQL(:NEW.STARTNO) || ''', ''' || FN_FMT_SQL(:NEW.STATUS) || ''', ''' || substr(:NEW.STOCKID ,4) || ''', ''' || substr(:NEW.UNITID ,4) || ''')';
end if;
end if;
if (curUser = 'gfmis_all') then
INSERT INTO exchange_temp (ID,SEQID, TABLENAME, GENSQL, TYPE, DT, STATUS,ZKSTATUS,DBUSER)
VALUES (id, curID,curTable, curSQL, curType, curTime, '2','1',v_dbuser );
else
INSERT INTO exchange_temp (ID,SEQID, TABLENAME, GENSQL, TYPE, DT, STATUS,ZKSTATUS,DBUSER)
VALUES (id, curID,curTable, curSQL, curType, curTime, '2','0',v_dbuser );
end if;
end if;
EXCEPTION
WHEN OTHERS THEN
RAISE;
end TRI_RECEIPTSTOCK_CHG_AFT;
/
commit;
【注】:在每一個(gè)DROP語(yǔ)句后面不能加/,而在創(chuàng)建PROCEDURE和TRIGGER的之后必須加/符號(hào),否則下面的腳本會(huì)
執(zhí)行失敗的。
執(zhí)行txt和sql的腳本寫(xiě)法如下:
SQL> @D:\myoracle.txt;
Procedure dropped
Procedure created
Trigger dropped
Trigger created
Commit complete
SQL>
exec后面執(zhí)行跟存儲(chǔ)過(guò)程名或函數(shù)名[exec只能在命令行執(zhí)行,call可以在任何環(huán)境下執(zhí)行]。
1.dbms_random.value方法
dbms_random是一個(gè)可以生成隨機(jī)數(shù)值或者字符串的程序包。這個(gè)包有initialize()、seed()、terminate()、value()、normal()、random()、string()等幾個(gè)函數(shù),但value()是最常用的,value()的用法一般有兩個(gè)種,第一 function value return number; 這種用法沒(méi)有參數(shù),會(huì)返回一個(gè)具有38位精度的數(shù)值,范圍從0.0到1.0,但不包括1.0,如下示例: SQL> set serverout on SQL> begin 2 for i in 1..10 loop 3 dbms_output.put_line(round(dbms_random.value*100)); 4 end loop; 5 end; 6 / 46 19 45 37 33 57 61 20 82 8 PL/SQL 過(guò)程已成功完成。 SQL> 第二種value帶有兩個(gè)參數(shù),第一個(gè)指下限,第二個(gè)指上限,將會(huì)生成下限到上限之間的數(shù)字,但不包含上限,“學(xué)無(wú)止境”兄說(shuō)的就是第二種,如下: SQL> begin 2 for i in 1..10 loop 3 dbms_output.put_line(trunc(dbms_random.value(1,101))); 4 end loop; 5 end; 6 / 97 77 13 86 68 16 55 36 54 46 PL/SQL 過(guò)程已成功完成。
2. dbms_random.string 方法
某些用戶管理程序可能需要為用戶創(chuàng)建隨機(jī)的密碼。使用10G下的dbms_random.string 可以實(shí)現(xiàn)這樣的功能。
例如:
SQL> select dbms_random.string('P',8 ) from dual ;
DBMS_RANDOM.STRING('P',8)
--------------------------------------------------------------------------------
3q<M"yf[
第一個(gè)參數(shù)的含義:
■ 'u', 'U' - returning string in uppercase alpha characters
■ 'l', 'L' - returning string in lowercase alpha characters
■ 'a', 'A' - returning string in mixed case alpha characters
■ 'x', 'X' - returning string in uppercase alpha-numeric
characters
■ 'p', 'P' - returning string in any printable characters.
Otherwise the returning string is in uppercase alpha
characters.
P 表示 printable,即字符串由任意可打印字符構(gòu)成
而第二個(gè)參數(shù)表示返回的字符串長(zhǎng)度。
3. dbms_random.random 方法
random返回的是BINARY_INTEGER類(lèi)型值,產(chǎn)生一個(gè)任意大小的隨機(jī)數(shù)
與dbms_random.value 的區(qū)別舉例:
Order By dbms_random.value; 這條語(yǔ)句功能是實(shí)現(xiàn)記錄的隨機(jī)排序 另外: dbms_random.value 和 dbms_random.random 兩者之間有什么區(qū)別? 1。Order By dbms_random.value ,為結(jié)果集的每一行計(jì)算一個(gè)隨機(jī)數(shù),dbms_random.value 是結(jié)果集的一個(gè)列(雖然這個(gè)列并不在select list 中),然后根據(jù)該列排序,得到的順序自然就是隨機(jī)的啦。 2。看看desc信息便知道vlue和random這兩個(gè)函數(shù)的區(qū)別了,value返回的是number類(lèi)型,tb并且返回的值介于1和0之間,而random返回的是BINARY_INTEGER類(lèi)型(以二進(jìn)制形式存儲(chǔ)的數(shù)字,據(jù)說(shuō)運(yùn)算的效率高于number但我沒(méi)測(cè)試過(guò),但取值范圍肯定小于number,具體限制得查資料了) 如果你要實(shí)現(xiàn)隨機(jī)排序,還是用value函數(shù)吧
4. dbms_random.normal方法
NORMAL函數(shù)返回服從正態(tài)分布的一組數(shù)。此正態(tài)分布標(biāo)準(zhǔn)偏差為1,期望值為0。這個(gè)函數(shù)返回的數(shù)值中有68%是介于-1與+1之間,95%介于-2與+2之間,99%介于-3與+3之間。
5. dbms_random.send方法
用于生成一個(gè)隨機(jī)數(shù)種子,設(shè)置種子的目的是可以重復(fù)生成隨機(jī)數(shù),用于調(diào)試。否則每次不同,難以調(diào)度。
對(duì)于一般的select操作,如果使用動(dòng)態(tài)的sql語(yǔ)句則需要進(jìn)行以下幾個(gè)步驟:
open cursor---> parse---> define column---> excute---> fetch rows---> close cursor;
而對(duì)于dml操作(insert,update)則需要進(jìn)行以下幾個(gè)步驟:
open cursor---> parse---> bind variable---> execute---> close cursor;
對(duì)于delete操作只需要進(jìn)行以下幾個(gè)步驟:
open cursor---> parse---> execute---> close cursor;
例一:
create table test(n_id number, v_name varchar2(50), d_insert_date date);
alter table test add constraint pk_id primary key(n_id);
declare
v_cursor number;
v_sql varchar2(200);
v_id number;
v_name varchar2(50);
v_date date;
v_stat number;
begin
v_id := 1;
v_name := '測(cè)試 insert';
v_date := sysdate;
v_cursor := dbms_sql.open_cursor; --打開(kāi)游標(biāo)
v_sql := 'insert into test(n_id, v_name, d_insert_date) values(:v_id,:v_name,:v_date)';
dbms_sql.parse(v_cursor, v_sql, dbms_sql.native); --解析SQL
dbms_sql.bind_variable(v_cursor, ':v_id', v_id); --綁定變量
dbms_sql.bind_variable(v_cursor, ':v_name', v_name);
dbms_sql.bind_variable(v_cursor, ':v_date', v_date);
v_stat := dbms_sql.execute(v_cursor); --執(zhí)行
dbms_sql.close_cursor(v_cursor); --關(guān)閉游標(biāo)
commit;
end;
例二:
declare
v_cursor number;
v_sql varchar2(200);
v_id number;
v_name varchar2(50);
v_stat number;
begin
v_name := '測(cè)試 update';
v_id := 1;
v_cursor := dbms_sql.open_cursor;
v_sql := 'update test set v_name = :v_name, d_insert_date = :v_date where n_id = :v_id';
dbms_sql.parse(v_cursor, v_sql, dbms_sql.native);
dbms_sql.bind_variable(v_cursor, ':v_name', v_name);
dbms_sql.bind_variable(v_cursor, ':v_date', sysdate);
dbms_sql.bind_variable(v_cursor, ':v_id', v_id);
v_stat := dbms_sql.execute(v_cursor);
dbms_sql.close_cursor(v_cursor);
commit;
end;
例三:
declare
v_cursor number;
v_sql varchar2(200);
v_id number;
v_stat number;
begin
v_id := 1;
v_sql := 'delete from test where n_id = :v_id';
v_cursor := dbms_sql.open_cursor;
dbms_sql.parse(v_cursor, v_sql, dbms_sql.native);
dbms_sql.bind_variable(v_cursor, ':v_id', v_id);
v_stat := dbms_sql.execute(v_cursor);
dbms_sql.close_cursor(v_cursor);
commit;
end;
例四:
declare
v_cursor number;
v_sql varchar2(200);
v_id number;
v_name varchar2(50);
v_date varchar2(10);
v_stat number;
begin
v_sql := 'select n_id, v_name, to_char(d_insert_date, ''yyyy-mm-dd'') from test';
v_cursor := dbms_sql.open_cursor; --打開(kāi)游標(biāo)
dbms_sql.parse(v_cursor, v_sql, dbms_sql.native); --解析游標(biāo)
dbms_sql.define_column(v_cursor, 1, v_id); --定義列
dbms_sql.define_column(v_cursor, 2, v_name, 50); --注意:當(dāng)變量為varchar2類(lèi)型時(shí),要加長(zhǎng)度
dbms_sql.define_column(v_cursor, 3, v_date, 10);
v_stat := dbms_sql.execute(v_cursor); --執(zhí)行SQL
loop
exit when dbms_sql.fetch_rows(v_cursor) <= 0; --fetch_rows在結(jié)果集中移動(dòng)游標(biāo),如果未抵達(dá)末尾,返回1。
dbms_sql.column_value(v_cursor, 1, v_id); --將當(dāng)前行的查詢(xún)結(jié)果寫(xiě)入上面定義的列中。
dbms_sql.column_value(v_cursor, 2, v_name);
dbms_sql.column_value(v_cursor, 3, v_date);
dbms_output.put_line(v_id || ':' || v_name || ':' || v_date);
end loop;
end;
--------------------------------------------------------------------------------------------------
PL/SQL中使用動(dòng)態(tài)SQL編程
在PL/SQL程序設(shè)計(jì)過(guò)程中,會(huì)遇到很多必須使用動(dòng)態(tài)sql的地方,oracle系統(tǒng)所tb提供的DMBS_SQL包可以幫助你解決問(wèn)題。
(一)介紹
DBMS_SQL系統(tǒng)包提供了很多函數(shù)及過(guò)程,現(xiàn)在簡(jiǎn)要闡述其中使用頻率較高的幾種:
function open_cursor:打開(kāi)一個(gè)動(dòng)態(tài)游標(biāo),并返回一個(gè)整型;
procedure close_cursor(c in out integer) :關(guān)閉一個(gè)動(dòng)態(tài)游標(biāo),參數(shù)為open_cursor所打開(kāi)的游標(biāo);
procedure parse(c in integer, statement in varchar2, language_flag in integer):對(duì)動(dòng)態(tài)游標(biāo)所提供的sql語(yǔ)句進(jìn)行解析,參數(shù)C表示游標(biāo),statement為sql語(yǔ)句,language-flag為解析sql語(yǔ)句所用oracle版本,一般有V6,V7跟native(在不明白所連database版本時(shí),使用native);
procedure define_column(c in integer, position in integer, column any datatype, [column_size in integer]):定義動(dòng)態(tài)游標(biāo)所能得到的對(duì)應(yīng)值,其中c為動(dòng)態(tài)游標(biāo),positon為對(duì)應(yīng)動(dòng)態(tài)sql中的位置(從1開(kāi)始),column為該值所對(duì)應(yīng)的變量,可以為任何類(lèi)型,column_size只有在column為定義長(zhǎng)度的類(lèi)型中使用如VARCHAR2,CHAR等(該過(guò)程有很多種情況,此處只對(duì)一般使用到的類(lèi)型進(jìn)行表述);
function execute(c in integer):執(zhí)行游標(biāo),并返回處理一個(gè)整型,代表處理結(jié)果(對(duì)insert,delete,update才有意義,而對(duì)select語(yǔ)句而言可以忽略);
function fetch_rows(c in integer):對(duì)游標(biāo)進(jìn)行循環(huán)取數(shù)據(jù),并返回一個(gè)整數(shù),為0時(shí)表示已經(jīng)取到游標(biāo)末端;
procedure column_value(c in integer, position in integer, value):將所取得的游標(biāo)數(shù)據(jù)賦值到相應(yīng)的變量,c為游標(biāo),position為位置,value則為對(duì)應(yīng)的變量;
procedure bind_variable(c in integer, name in varchar2, value):定義動(dòng)態(tài)sql語(yǔ)句(DML)中所對(duì)應(yīng)字段的值,c為游標(biāo),name為字段名稱(chēng),value為字段的值;
以上是在程序中經(jīng)常使用到的幾個(gè)函數(shù)及過(guò)程,其他函數(shù)及過(guò)程請(qǐng)參照oracle所提供定義語(yǔ)句dbmssql.sql
(二)一般過(guò)程
對(duì)于一般的select操作,如果使用動(dòng)態(tài)的sql語(yǔ)句則需要進(jìn)行以下幾個(gè)步驟: open cursor--->parse--->define column--->excute--->fetch rows--->close cursor;
而對(duì)于dml操作(insert,update)則需要進(jìn)行以下幾個(gè)步驟: open cursor--->parse--->bind variable--->execute--->close cursor;
對(duì)于delete操作只需要進(jìn)行以下幾個(gè)步驟: open cursor--->parse--->execute--->close cursor;
(三)具體案例
下面就本人所開(kāi)發(fā)系統(tǒng)中某一程序做分析 該過(guò)程為一股票技術(shù)曲線計(jì)算程序,將數(shù)據(jù)從即時(shí)數(shù)據(jù)表中取出,并按照計(jì)算曲線的公式,tb對(duì)這些數(shù)據(jù)進(jìn)行計(jì)算,并將結(jié)果保存到技術(shù)曲線表中.
--********************************** --procedure name:R_Ma_Main --入口參數(shù):PID股票代碼,PEND時(shí)間,pinterval時(shí)間間隔,totab目標(biāo)數(shù)據(jù)表 --調(diào)用函數(shù):R_GetSql1,R_GetSql2 --功能:具體計(jì)算單支股票ma技術(shù)曲線 --時(shí)間:2001-06-20 --********************************** create or replace procedure R_Ma_Main ( pid varchar2, pend varchar2, pinterval varchar2, totab varchar2 ) is --定義數(shù)組 type Date_type is table of varchar2(12) index by binary_integer; type Index_type is table of number index by binary_integer;
TempDate Date_Type;--時(shí)間數(shù)組 TempIndex Index_Type;--股票收盤(pán)價(jià)數(shù)組 TempMa Index_Type;--ma技術(shù)曲線數(shù)據(jù)
cursor1 integer;--游標(biāo) cursor2 integer;--游標(biāo) rows_processed integer;--執(zhí)行游標(biāo)返回
TempInter integer;--參與計(jì)算數(shù)值個(gè)數(shù) TempVal integer;--計(jì)算時(shí)間類(lèi)型 TempSql varchar2(500);--動(dòng)態(tài)sql語(yǔ)句 MyTime varchar2(12);--時(shí)間 MyIndex number;--數(shù)值 MidIndex number;--中間變量 i integer := 999; j integer; begin TempInter := to_number(substr(pinterval,1,4)); TempVal := to_number(substr(pinterval,5,2)); TempSql := R_GetSql1(pid, pend, TempVal);--得到選擇數(shù)據(jù)的sql語(yǔ)句
--得到當(dāng)天的即時(shí)數(shù)據(jù),并依次保存到數(shù)組中 cursor1 := dbms_sql.open_cursor; --創(chuàng)建游標(biāo) dbms_sql.parse(cursor1, TempSql, dbms_sql.native); --解析動(dòng)態(tài)sql語(yǔ)句,取兩個(gè)字段,時(shí)間及價(jià)格,其中時(shí)間以14位的varchar2表示 dbms_sql.define_column(cursor1, 1, MyTime, 12); --分別定義sql語(yǔ)句中各字段所對(duì)應(yīng)變量 dbms_sql.define_column(cursor1, 2, MyIndex); rows_processed := dbms_sql.execute(cursor1); loop if dbms_sql.fetch_rows(cursor1) > 0 then begin dbms_sql.column_value(cursor1, 1, MyTime); dbms_sql.column_value(cursor1, 2, MyIndex); TempDate(i) := MyTime; TempIndex(i) := MyIndex; i := i - 1;--按倒序的方法填入數(shù)組 end; else exit; end if; end loop; dbms_sql.close_cursor(cursor1); --如果取得的數(shù)據(jù)量不夠計(jì)算個(gè)數(shù),則跳出程序 if i > 999-TempInter then goto JumpLess; end if; --初始化中間變量 MidIndex := 0; TempIndex(i) := 0; for j in i..i+TempInter-1 loop MidIndex := MidIndex + TempIndex(j); end loop;
--依次對(duì)當(dāng)天數(shù)據(jù)計(jì)算ma值,并保存到ma數(shù)組中 for j in i+TempInter..999 loop MidIndex := MidIndex - TempIndex(j-TempInter) + TempIndex(j); TempMa(j) := MidIndex/TempInter; end loop;
if TempVal < 6 then--如果計(jì)算的是分鐘跟天的ma技術(shù)曲線 begin cursor2 := dbms_sql.open_cursor; TempSql := 'insert into ' || totab || ' values(:r_no, :i_interval, :i_time, :i_index)'; dbms_sql.parse(cursor2, TempSql, dbms_sql.native); for j in i+TempInter..999 loop dbms_sql.bind_variable(cursor2, 'r_no', pid); dbms_sql.bind_variable(cursor2, 'i_interval', pinterval); dbms_sql.bind_variable(cursor2, 'i_time', TempDate(j)); dbms_sql.bind_variable(cursor2, 'i_index', TempMa(j)); rows_processed := dbms_sql.execute(cursor2);--插入數(shù)據(jù) end loop; end; end if; commit; dbms_sql.close_cursor(cursor2); --數(shù)據(jù)量不足跳出 <<JumpLess>> null; --exception處理,無(wú)關(guān)本話題 end; /
(四)個(gè)人觀點(diǎn)
在使用dbms_sql系統(tǒng)包的過(guò)程中,其方法簡(jiǎn)單而又不失靈活,但還是需要注意一些問(wèn)題:
1、在整個(gè)程序的設(shè)計(jì)過(guò)程中,對(duì)游標(biāo)的操作切不可有省略的部分,一旦省略其中某一步驟,則會(huì)程序編譯過(guò)程既告失敗,如在程序結(jié)尾處未對(duì)改游標(biāo)進(jìn)行關(guān)閉操作,則在再次調(diào)用過(guò)程時(shí)會(huì)出現(xiàn)錯(cuò)誤. 2、dbms_sql除了可以做一般的select,insert,update,delete等靜態(tài)的sql做能在過(guò)程中所做工作外,還能執(zhí)行create等DDL操作,不過(guò)在執(zhí)行該類(lèi)操作時(shí)應(yīng)首先顯式賦予執(zhí)行用戶相應(yīng)的系統(tǒng)權(quán)限,比如create table等.該類(lèi)操作只需open cursor--->prase--->close cursor即能完成.
以上為本人在工作中對(duì)dbms_sql的一點(diǎn)點(diǎn)看法,不到之處,請(qǐng)予指正. 對(duì)于想更深了解dbms_sql的朋友,請(qǐng)閱讀dbmssql.sql文件.
附個(gè)Oracle自帶的流程說(shuō)明(強(qiáng)大啊):
-- The flow of procedure calls will typically look like this: -- -- ----------- -- | open_cursor | -- ----------- -- | -- | -- v -- ----- -- ------------>| parse | -- | ----- -- | | -- | | |