|
常用鏈接
留言簿
隨筆檔案
搜索
最新評論

閱讀排行榜
評論排行榜
Powered by: 博客園
模板提供:滬江博客
|
|
|
|
|
發新文章 |
|
|
2012年11月21日
我能抽象出整個世界..  . 但是我卻不能抽象出你... 你肯定是一個單例,因為你是那樣的獨一無二... 所以我的世界并不完整... 我可以重載甚至覆蓋這個世界里的任何一種方法... 但是卻不能覆蓋對你的思念... 也許命中注定了 你與我存在于不同的包里... 在你的世界里,你被烙上了私有的屬性... 我用盡全身力氣,也找不到訪問你的接口... 我不愿就此甘心,找到了藏身在javaeye神殿的巫師,教會了我穿越時空的方法... 終于,我用反射這把利劍,打開了你空間的缺口... 并發現了接近你的秘密... 當我迫不及待地調用了愛你這個方法... 并義無返顧的把自己作為參數傳進這個方法時... 我才發現愛上你是一個沒有終止條件的遞歸... 它不停的返回我對你的思念并壓入我心里的堆棧... 在這無盡的黑夜中 , tb終于體驗到你對我愛的回調... 我的內存里已經再也裝不下別人... 當我以為將與你在這個死循環中天荒地老時... 萬惡的系統拋出了愛的異常... 此刻我才發現,我不過是操縱于虛擬機下的一個線程,你也是... 但我毫不后悔,因為在愛的洗禮之后... 我看見了一個新的生命,那是我們的, 繼承
2012年11月5日
線程是Java語言的一個部分,而且是Java的最強大的功能之一。究竟什么是線程,為什么要開發基于線程的應用程序?在本文中,我們將深入了解一下線程的用法,以及使用線程的一些技術。在我們開始講述線程之前,最好先了解一下有關背景知識和分析一下線程的工作原理。
當程序員一開始開發應用程序時,這些應用程序只能在一個時間內完成一件事情。應用程序從主程序開始執行,直到運行結束,像 Fortran/Cobol/Basic這些語言均是如此。
隨著時間的推移,計算機發展到可以在同一時間段內運行不止一個應用程序的時代了,但是應用程序運行時仍然是串行的,即從開始運行到結束,下一條指令接著上一條指令執行。到最近,程序發展到可以在執行時,以若干個線程的形式運行。Java就具有運行多線程的能力,可以在同一時間段內進行幾個操作,這就意味著給定的操作不必等到另外一個操作結束之后,才能開始。而且對某個操作可以指定更高一級的優先級。
不少程序語言,包括ADA, Modula-2和C/C++,已經可以提供對線程的支持。同這些語言相比,Java的特點是從最底層開始就對線程提供支持。除此以外,標準的Java類是可重入的,允許在一個給定的應用程序中由多個線程調用同一方法,tb而線程彼此之間又互不干擾。Java的這些特點為多線程應用程序的設計奠定了基礎。
什么是線程?
究竟什么是線程呢?正如在圖A中所示,一個線程是給定的指令的序列 (你所編寫的代碼),一個棧(在給定的方法中定義的變量),以及一些共享數據(類一級的變量)。線程也可以從全局類中訪問靜態數據。
#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日
有多種方法的,我只說兩種最簡單的。 一、定義數據源sql時,定義一個變量:xb,然后數據源寫成: select * from [運動員表] where [性別]=:xb 再從窗口的open事件中寫: dw_1.settransobject(sqlca) dw_1.retrieve('男')//把變量傳給數據窗口,只刷出男生。 即可實現。 二、定義數據源sql時,直接寫成: select * from [運動員表] 窗口的open事件中寫: dw_1.settransobejct(sqlca) dw_1.retrieve()//這句是刷新出所有的運動員,包括男女 dw_1.setfilter("[性別]='男'")//為數據窗口設置過濾 dw_1.filter()//使用過濾字符串過濾數據 也可以實現你所要求的。 是不是數據窗口的行高不夠(這個會擋住每行數據的一點點), 還有可能是details的band tb向下拖拖 多放點空間 (這個肯能擋住最下面的數據)
2012年10月17日
找到了問題產生的原因后,下面來討論如何解決該問題。對于Oracle Enterprise Manager中的所有工具,有一個配置文件名為dbappscfg.properties,修改該文件即可解決上述問題。這個文件的位置在$ORACLE_HOME\sysman\config目錄下,用任何的文本編輯器打開該文件,在這個文件里面,找到這樣一項,
# SQLPLUS_NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1
去掉注釋符#,同時將其修改為
SQLPLUS_NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
對于Windows操作系統,還需要修改一項,在文件中找到# SQLPLUS_SYSTEMROOT=c:\\WINNT40,去掉注釋符,將其修改為你所在機器的操作系統主目錄。如操作系統的主目錄在D盤的Winnt下,則將其修改為
SQLPLUS_SYSTEMROOT=d:\\WINNT。
對于后面一項的修改只對Windows操作系統進行,對UNIX操作系統則不需要。如果在Windows操作系統中不修改該項,在Oracle Enterprise Manager中,連接系統時,會提示如下的錯誤:
ORA-12560 TNS:protocol adapter error
或者
ORA-12545 Connect failed because target host or objectb does not exist
修改完成后,保存文件,退出編輯。重新連接SQL PLUS Worksheet,字符集亂碼問題得到解決,顯示正確的簡體中文字符集。
.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腳本內容如下:
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
--把票據類型為5D的繳款書在庫存中更新成一般繳款書
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
--把票據類型為5DTB的繳款書在庫存中更新成一般繳款書 或者 把指定的19個單位的庫存移到分庫里面
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;
【注】:在每一個DROP語句后面不能加/,而在創建PROCEDURE和TRIGGER的之后必須加/符號,否則下面的腳本會
執行失敗的。
執行txt和sql的腳本寫法如下:
SQL> @D:\myoracle.txt;
Procedure dropped
Procedure created
Trigger dropped
Trigger created
Commit complete
SQL>
exec后面執行跟存儲過程名或函數名[exec只能在命令行執行,call可以在任何環境下執行]。
1.dbms_random.value方法
dbms_random是一個可以生成隨機數值或者字符串的程序包。這個包有initialize()、seed()、terminate()、value()、normal()、random()、string()等幾個函數,但value()是最常用的,value()的用法一般有兩個種,第一 function value return number; 這種用法沒有參數,會返回一個具有38位精度的數值,范圍從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 過程已成功完成。 SQL> 第二種value帶有兩個參數,第一個指下限,第二個指上限,將會生成下限到上限之間的數字,但不包含上限,“學無止境”兄說的就是第二種,如下: 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 過程已成功完成。
2. dbms_random.string 方法
某些用戶管理程序可能需要為用戶創建隨機的密碼。使用10G下的dbms_random.string 可以實現這樣的功能。
例如:
SQL> select dbms_random.string('P',8 ) from dual ;
DBMS_RANDOM.STRING('P',8)
--------------------------------------------------------------------------------
3q<M"yf[
第一個參數的含義:
■ '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,即字符串由任意可打印字符構成
而第二個參數表示返回的字符串長度。
3. dbms_random.random 方法
random返回的是BINARY_INTEGER類型值,產生一個任意大小的隨機數
與dbms_random.value 的區別舉例:
Order By dbms_random.value; 這條語句功能是實現記錄的隨機排序 另外: dbms_random.value 和 dbms_random.random 兩者之間有什么區別? 1。Order By dbms_random.value ,為結果集的每一行計算一個隨機數,dbms_random.value 是結果集的一個列(雖然這個列并不在select list 中),然后根據該列排序,得到的順序自然就是隨機的啦。 2??纯磀esc信息便知道vlue和random這兩個函數的區別了,value返回的是number類型,tb并且返回的值介于1和0之間,而random返回的是BINARY_INTEGER類型(以二進制形式存儲的數字,據說運算的效率高于number但我沒測試過,但取值范圍肯定小于number,具體限制得查資料了) 如果你要實現隨機排序,還是用value函數吧
4. dbms_random.normal方法
NORMAL函數返回服從正態分布的一組數。此正態分布標準偏差為1,期望值為0。這個函數返回的數值中有68%是介于-1與+1之間,95%介于-2與+2之間,99%介于-3與+3之間。
5. dbms_random.send方法
用于生成一個隨機數種子,設置種子的目的是可以重復生成隨機數,用于調試。否則每次不同,難以調度。
對于一般的select操作,如果使用動態的sql語句則需要進行以下幾個步驟:
open cursor---> parse---> define column---> excute---> fetch rows---> close cursor;
而對于dml操作(insert,update)則需要進行以下幾個步驟:
open cursor---> parse---> bind variable---> execute---> close cursor;
對于delete操作只需要進行以下幾個步驟:
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 := '測試 insert';
v_date := sysdate;
v_cursor := dbms_sql.open_cursor; --打開游標
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); --執行
dbms_sql.close_cursor(v_cursor); --關閉游標
commit;
end;
例二:
declare
v_cursor number;
v_sql varchar2(200);
v_id number;
v_name varchar2(50);
v_stat number;
begin
v_name := '測試 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; --打開游標
dbms_sql.parse(v_cursor, v_sql, dbms_sql.native); --解析游標
dbms_sql.define_column(v_cursor, 1, v_id); --定義列
dbms_sql.define_column(v_cursor, 2, v_name, 50); --注意:當變量為varchar2類型時,要加長度
dbms_sql.define_column(v_cursor, 3, v_date, 10);
v_stat := dbms_sql.execute(v_cursor); --執行SQL
loop
exit when dbms_sql.fetch_rows(v_cursor) <= 0; --fetch_rows在結果集中移動游標,如果未抵達末尾,返回1。
dbms_sql.column_value(v_cursor, 1, v_id); --將當前行的查詢結果寫入上面定義的列中。
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中使用動態SQL編程
在PL/SQL程序設計過程中,會遇到很多必須使用動態sql的地方,oracle系統所tb提供的DMBS_SQL包可以幫助你解決問題。
(一)介紹
DBMS_SQL系統包提供了很多函數及過程,現在簡要闡述其中使用頻率較高的幾種:
function open_cursor:打開一個動態游標,并返回一個整型;
procedure close_cursor(c in out integer) :關閉一個動態游標,參數為open_cursor所打開的游標;
procedure parse(c in integer, statement in varchar2, language_flag in integer):對動態游標所提供的sql語句進行解析,參數C表示游標,statement為sql語句,language-flag為解析sql語句所用oracle版本,一般有V6,V7跟native(在不明白所連database版本時,使用native);
procedure define_column(c in integer, position in integer, column any datatype, [column_size in integer]):定義動態游標所能得到的對應值,其中c為動態游標,positon為對應動態sql中的位置(從1開始),column為該值所對應的變量,可以為任何類型,column_size只有在column為定義長度的類型中使用如VARCHAR2,CHAR等(該過程有很多種情況,此處只對一般使用到的類型進行表述);
function execute(c in integer):執行游標,并返回處理一個整型,代表處理結果(對insert,delete,update才有意義,而對select語句而言可以忽略);
function fetch_rows(c in integer):對游標進行循環取數據,并返回一個整數,為0時表示已經取到游標末端;
procedure column_value(c in integer, position in integer, value):將所取得的游標數據賦值到相應的變量,c為游標,position為位置,value則為對應的變量;
procedure bind_variable(c in integer, name in varchar2, value):定義動態sql語句(DML)中所對應字段的值,c為游標,name為字段名稱,value為字段的值;
以上是在程序中經常使用到的幾個函數及過程,其他函數及過程請參照oracle所提供定義語句dbmssql.sql
(二)一般過程
對于一般的select操作,如果使用動態的sql語句則需要進行以下幾個步驟: open cursor--->parse--->define column--->excute--->fetch rows--->close cursor;
而對于dml操作(insert,update)則需要進行以下幾個步驟: open cursor--->parse--->bind variable--->execute--->close cursor;
對于delete操作只需要進行以下幾個步驟: open cursor--->parse--->execute--->close cursor;
(三)具體案例
下面就本人所開發系統中某一程序做分析 該過程為一股票技術曲線計算程序,將數據從即時數據表中取出,并按照計算曲線的公式,tb對這些數據進行計算,并將結果保存到技術曲線表中.
--********************************** --procedure name:R_Ma_Main --入口參數:PID股票代碼,PEND時間,pinterval時間間隔,totab目標數據表 --調用函數:R_GetSql1,R_GetSql2 --功能:具體計算單支股票ma技術曲線 --時間:2001-06-20 --********************************** create or replace procedure R_Ma_Main ( pid varchar2, pend varchar2, pinterval varchar2, totab varchar2 ) is --定義數組 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;--時間數組 TempIndex Index_Type;--股票收盤價數組 TempMa Index_Type;--ma技術曲線數據
cursor1 integer;--游標 cursor2 integer;--游標 rows_processed integer;--執行游標返回
TempInter integer;--參與計算數值個數 TempVal integer;--計算時間類型 TempSql varchar2(500);--動態sql語句 MyTime varchar2(12);--時間 MyIndex number;--數值 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);--得到選擇數據的sql語句
--得到當天的即時數據,并依次保存到數組中 cursor1 := dbms_sql.open_cursor; --創建游標 dbms_sql.parse(cursor1, TempSql, dbms_sql.native); --解析動態sql語句,取兩個字段,時間及價格,其中時間以14位的varchar2表示 dbms_sql.define_column(cursor1, 1, MyTime, 12); --分別定義sql語句中各字段所對應變量 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;--按倒序的方法填入數組 end; else exit; end if; end loop; dbms_sql.close_cursor(cursor1); --如果取得的數據量不夠計算個數,則跳出程序 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;
--依次對當天數據計算ma值,并保存到ma數組中 for j in i+TempInter..999 loop MidIndex := MidIndex - TempIndex(j-TempInter) + TempIndex(j); TempMa(j) := MidIndex/TempInter; end loop;
if TempVal < 6 then--如果計算的是分鐘跟天的ma技術曲線 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);--插入數據 end loop; end; end if; commit; dbms_sql.close_cursor(cursor2); --數據量不足跳出 <<JumpLess>> null; --exception處理,無關本話題 end; /
(四)個人觀點
在使用dbms_sql系統包的過程中,其方法簡單而又不失靈活,但還是需要注意一些問題:
1、在整個程序的設計過程中,對游標的操作切不可有省略的部分,一旦省略其中某一步驟,則會程序編譯過程既告失敗,如在程序結尾處未對改游標進行關閉操作,則在再次調用過程時會出現錯誤. 2、dbms_sql除了可以做一般的select,insert,update,delete等靜態的sql做能在過程中所做工作外,還能執行create等DDL操作,不過在執行該類操作時應首先顯式賦予執行用戶相應的系統權限,比如create table等.該類操作只需open cursor--->prase--->close cursor即能完成.
以上為本人在工作中對dbms_sql的一點點看法,不到之處,請予指正. 對于想更深了解dbms_sql的朋友,請閱讀dbmssql.sql文件.
附個Oracle自帶的流程說明(強大啊):
-- The flow of procedure calls will typically look like this: -- -- ----------- -- | open_cursor | -- ----------- -- | -- | -- v -- ----- -- ------------>| parse | -- | ----- -- | | -- | | |