字符串轉(zhuǎn)為數(shù)字用to_number函數(shù),例如
創(chuàng)新互聯(lián)建站長(zhǎng)期為1000多家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為君山企業(yè)提供專業(yè)的成都網(wǎng)站制作、網(wǎng)站建設(shè),君山網(wǎng)站改版等技術(shù)服務(wù)。擁有十多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。
to_number('1210.73')就得到1210.73
數(shù)字轉(zhuǎn)為字符串用to_char函數(shù),例如
to_char(1210.73)就得到'1210.73'
兩個(gè)函數(shù)都可以設(shè)定轉(zhuǎn)換的格式,例如
to_char(1210.73, '$9,999.00')就得到'$1,210.73'
第二個(gè)問(wèn)題:select count(*) from ...
在ORACLE中,將空字符串視為NULL,任何值與NULL比較結(jié)果都為NULL。如此一來(lái),在比較兩個(gè)字符串的時(shí)候就會(huì)出現(xiàn)意外。請(qǐng)看以下的例子:DECLAREi VARCHAR2(10) := NULL;
v VARCHAR2(10) := 'ABC';BEGINIF(i = v) THEN
v VARCHAR2(10) := 'ABC';BEGINIF(i v) THEN
DBMS_OUTPUT.PUT_LINE('不等');ELSEDBMS_OUTPUT.PUT_LINE('相等');END IF;END;看上去和第一個(gè)程序沒(méi)有太大的差別,很容易就得出結(jié)果:'不等'。呵呵。你確定結(jié)果就是這個(gè)嗎?那么請(qǐng)你在SQLPLUS測(cè)試一下,來(lái)驗(yàn)證你是正確的。很可惜,正確的結(jié)果應(yīng)該是:'相等'。是不是很詫異?正如開(kāi)始所說(shuō)的:任何值與NULL比較結(jié)果都為NULL。即在第一個(gè)程序中的i=v比較的結(jié)果應(yīng)該是NULL,而第二個(gè)程序中的iv比較的結(jié)果也是NULL。當(dāng)IF結(jié)構(gòu)中的條件為NULL時(shí),將跳過(guò)當(dāng)前的分支進(jìn)入到ELSE或者是結(jié)束。不行嗎?那你運(yùn)行一下以下的程序?qū)⒖梢缘鹊津?yàn)證:BEGINIF(NULL) THEN
DBMS_OUTPUT.PUT_LINE('NOT NULL');ELSEDBMS_OUTPUT.PUT_LINE('NULL');END IF;END;結(jié)果輸出的是:'NULL'。
1、當(dāng)i和v都為NULL的時(shí)候,認(rèn)為i和v相等。i IS NULL AND v IS NULL(不要寫(xiě)成這樣:i = v。從上邊的分析我們可以知道這樣寫(xiě)的結(jié)果為NULL)。
2、當(dāng)i和v中只有一個(gè)為NULL,肯定不相等。
3、當(dāng)i和v都不為NULL的時(shí)候,我們就可以用‘=’號(hào)來(lái)判斷它們是否相等。i IS NOT NULL AND v IS NOT NULL AND i = v。
根據(jù)以上三點(diǎn),我們可以得出判斷i和v相等的條件表達(dá)式:i IS NULL AND v IS NULL OR i IS NOT NULL AND v IS NOT NULL AND i = v。
那么兩個(gè)字符串不相等的條件表達(dá)式只需要判斷相等的表達(dá)式為FALSE就可以了。
把判斷兩個(gè)字符串是否相等的功能寫(xiě)成函數(shù):
CREATE OR REPLACE FUNCTION ISEQUAL(VAR1 IN VARCHAR2,
VAR2 IN VARCHAR2)RETURN NUMBER -- 0:不等 1:相等 -1:錯(cuò)誤ISIF(VAR1 IS NULL AND VAR2 IS NULL OR VAR1 IS NOT NULL AND VAR2 IS NOT NULL AND VAR1 = VAR2) THENRETURN 1;ELSERETURN 0;ENF IF;BEGINEXCEPTIONWHEN OTHERS THENRETURN -1;END;以下上測(cè)試程序:DECLAREVAR1 VARCHAR2(10) := NULL;
以前自己寫(xiě)的:
/* exam01.pc 開(kāi)發(fā)Oracle接口程序舉例 */
/* 說(shuō)明:本程序介紹用PROC開(kāi)發(fā)Oracle庫(kù)接口的編程特點(diǎn)。通過(guò)向AUTHS
* 表輸入作家代碼,查詢作家姓名及工資。運(yùn)行前應(yīng)建表、插入數(shù)據(jù)并提交。*/
#include stdio.h
#include string.h
#include stdlib.h
/* 包含SQL通訊區(qū),它用于處理錯(cuò)誤。*/
#include sqlca.h
void connect(); /* 連接到Oracle Server */
void disconnect(); /* 斷開(kāi)到Oracle Server的連接 */
void sql_error(char *); /* 處理錯(cuò)誤句柄 */
void select(); /* 查詢子程序 */
extern sqlglm(char *,int *,int *);
/* 主程序 */
void main()
{
/* 安裝錯(cuò)誤處理句柄 */
EXEC SQL WHENEVER SQLERROR DO sql_error("Oracle錯(cuò)誤--\n");
/* 連接到數(shù)據(jù)庫(kù) */
connect();
/* 執(zhí)行查詢 */
select();
/* 斷開(kāi)數(shù)據(jù)庫(kù)連接 */
disconnect();
}
/* 子程序 */
/* 連接子程序 connect() */
void connect()
{
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR username[10], password[10], server[10];
EXEC SQL END DECLARE SECTION;
/* 輸入用戶名、口令以及服務(wù)器名 */
printf("\n輸入用戶名:");
gets(username.arr);
username.len=(unsigned short)strlen((char *)username.arr);
printf("\n輸入口令:");
gets(password.arr);
password.len=(unsigned short)strlen((char *)password.arr);
printf("\n輸入服務(wù)器名:");
gets(server.arr);
server.len=(unsigned short)strlen((char *)server.arr);
/* 連接到Oracle服務(wù)器上 */
EXEC SQL CONNECT :username IDENTIFIED BY :password USING :server;
printf("\n以用戶%s成功地連接到了服務(wù)器%s上!\n", username.arr, server.arr);
}
/* 斷開(kāi)連接子程序 disconnect() */
void disconnect()
{
char temp;
printf("\n是否在斷開(kāi)連接前提交所有事務(wù)? (Y/N)");
scanf("%c", temp);
fflush(stdin);
if(temp !='Y' temp != 'y')
{
/* 回退事務(wù),斷開(kāi)連接。 */
EXEC SQL ROLLBACK WORK RELEASE;
printf("\n回退事務(wù),斷開(kāi)連接,退出程序!\n\n");
}
else
{
/* 提交事務(wù),斷開(kāi)連接。 */
EXEC SQL COMMIT WORK RELEASE;
printf("\n提交事務(wù),斷開(kāi)連接,退出程序!\n\n");
exit(1);
}
}
/* 查詢子程序 select()
* 首先輸入作家代碼,然后查詢作家姓名和工資。*/
void select()
{
EXEC SQL BEGIN DECLARE SECTION;
char author_code[8], name[10];
float salary;
short salary_ind;
EXEC SQL END DECLARE SECTION;
printf("\n輸入作家代碼: ");
gets(author_code);
/* 查詢作家姓名和工資 */
EXEC SQL SELECT name, salary INTO :name, :salary:salary_ind
FROM auths
WHERE author_code = :author_code;
/* 根據(jù)指示變量的值來(lái)確定該作家的工資是否為空。*/
if (salary_ind ==0)
{
printf("\n作家代碼\t作家姓名\t作家工資\n");
printf("--------\t--------\t--------\n");
printf("%8s\t%8s\t%8.2f\n", author_code, name, salary);
}
else
{
printf("作家%s的工資未錄入,為空值!\n", name);
}
}
/* 錯(cuò)誤處理子程序 sql_error() */
void sql_error(char *msg)
{
char err_msg[128];
size_t buf_len, msg_len;
/* 出現(xiàn)SQL錯(cuò)誤,繼續(xù)往下執(zhí)行。 */
EXEC SQL WHENEVER SQLERROR CONTINUE;
printf("\n%s\n", msg);
buf_len=sizeof(err_msg);
/* 調(diào)用函數(shù)sqlglm()獲得錯(cuò)誤消息。 */
sqlglm(err_msg, buf_len, msg_len);
printf("%.*s\n", msg_len, err_msg);
/* 回退事務(wù),斷開(kāi)連接,退出程序。 */
EXEC SQL ROLLBACK RELEASE;
exit(EXIT_FAILURE);
}
Java能夠調(diào)用Oracle的存儲(chǔ)過(guò)程,反之Oracle也能用Java來(lái)開(kāi)發(fā)外部存儲(chǔ)過(guò)程,這樣Java和oracle的相互界限就已經(jīng)不明確了。Oracle實(shí)現(xiàn)BLOB字段的字符串讀取也就非常容易了。
當(dāng)然關(guān)系型數(shù)據(jù)庫(kù)最好做自己應(yīng)該做的事情而不是大包大攬做所有的非數(shù)據(jù)庫(kù)應(yīng)該做的事情。
--開(kāi)發(fā)Java類
--然后在Oracle中把這個(gè)類導(dǎo)入成為一個(gè)函數(shù),執(zhí)行命令
--執(zhí)行相應(yīng)的操作
以上代碼均在PL/SQL developer中開(kāi)發(fā)并調(diào)試通過(guò),Java和Oracle實(shí)現(xiàn)BLOB字段的字符串讀取很有意思。
要么用存儲(chǔ)過(guò)程,開(kāi)了游標(biāo)讀出表名來(lái)一個(gè)個(gè)拼,比較麻煩,
要么用觸發(fā)器,每個(gè)你關(guān)心的表上都戳那么一個(gè)上去,完成寫(xiě)操作后把最大值記錄在某張?zhí)囟ū砝镱^(性能可能影響大點(diǎn),但是讀的時(shí)候輕松),
要么用job來(lái)干上面那個(gè)活計(jì)(如果數(shù)據(jù)滯后點(diǎn)關(guān)系不大的話比觸發(fā)器好些);
或者我又想,如果這些表的結(jié)構(gòu)比較類似的話,至少id都是同一類型的話,做個(gè)帶表名的視圖,表大的話id上要有索引。
create or replace view v_All as
select 'Table_A' as t_name, A.id from Table_A A
union all
select 'Table_B' as t_name, B.id from Table_B B
...;
select t_name, MAX(id) from v_all
group by t_name;