Firebird 數據庫使用經驗總結
轉自:https://www.oschina.net/question/54100_8615
最近在改寫一段ms sql的存儲過程到firebird,總結了一些經驗,firebird可以說是這個世界上最小的支持存儲過程的數據庫,才2.3M 而已。如果做小型的應用,相比ms sql桌面版有70多M(+sp3),mysql也有20-30M,還是更合適一些。
1.自定義函數問題.Access to UDF library "rfunc.dll" is denied by server administrator
花了很長時間,不明白為何,將rfunc.dll拷到udf目錄,bin目錄,windows\system32目錄都不能解決問題,google一下, 網上有同樣的問題,但沒有解決方案,結果我重裝了一下firebird就解決了.
2.存儲過程中變量的定義
ms sql存儲過程中無論在哪都可以定義新的變量,但在firebird中,只能在as 與begin之間進行定義.firebird的變量不能用@符號,我將@全部變成a就好了.
3.存儲過程中變量的使用
- select @i=count(*) from table1 //ms sql
- select count(*) from table1 into :i//firebird引用變量使用冒號
4.嵌入式sql,
firebird支持select * from table exists (select ...) 或 select * from table in (select ...)
我是將這類改寫成視圖解決的
5.case語句
mssql 可使用field= case (),但firebbird僅支持case () as field
6.mssql getdate()變成CURRENT_DATE+CURRENT_TIME
- select * from snartleave where dt_starttime<CURRENT_DATE+CURRENT_TIME
或
- select * from snartleave where dt_starttime<CURRENT_DATE||‘ ‘ ||CURRENT_TIME
7.返回數據集的存儲過程寫法(firebird寫法有點麻煩)
- CREATE PROCEDURE SPVARTST2 (
- VAR_IPTARTNO CHAR(6))
- RETURNS (
- VAR_ARTNAME CHAR(10))
- AS
- begin
- for select v_name1 from snart where v_artNo=:var_iptartno into :var_artname do
- suspend;
- end
8.自動增長字段的使用(autoincrement)
firebird有個發生器(generator)的東東,在發生器裏記錄值的增長,
再用觸發器實現
- begin
- if (new.i_seqno is null) then
- begin
- NEW.i_seqno = GEN_ID(GEN_T_DB_ARTSEQNO_ID,1);
- end
- end
GEN_T_DB_ARTSEQNO_ID就是創建的發生器,看到沒有,也就是說不同的表不同的字段可以共用一個發生器,gen_id相當於 identity,看起來比mssql復雜,其實也很簡單。
9.發生器重置mssql裏自動增加的字段要重置好像很麻煩,較難控制,
firebird可以這樣(存儲過程中)
- agenerator=Gen_ID(GEN_T_DB_ARTSEQNO_ID,Gen_ID(GEN_T_DB_ARTSEQNO_ID,0)*-1+1);
//agenerator是一個整形變量,好像一定要裝gen_id的值符給一個變量才行,不知道有沒有更好的辦法,不用定義一個多余的變量
可參考如下網址:http://www.fingerbird.de/generatorguide_body.htm
10 通過一個表更改另一個表的數據
- mssql:update table1 set cname=b.cname from table1 a inner join table2 as b where a.id=b.id
- firebird:update table1 a set cname=(select cname from table 2 b where b where a.id=b.id)
11.如何選擇前幾條記錄
- mssql: select top 10 * from table1
- firebird:select first 10 * from table1
- IB:select * from table rows 10
12.Firebird存存儲過程中的事務
在存儲過程 ib/fb 不支持開事務或者結束事務。提交是由調用者提交的。也就是,fb/ib存儲過程應該設計在一個事務裏。
在sql server裏,存儲過程或以開這樣的事務:
- begin trancstion
- commit trancstion
但在fb/ib裏沒有這樣的事務 ,需要在調的程序中開事務,如:
- pFIBDtbsMain.StartTransaction;
- pFIBDtbsMain.Commit;
在Firebird裏如何防止空值擴散
出自:http://dev.csdn.net/article/72/72836.shtm
在統計、計算、合並數據時,空值擴散問題,有時不經意冒出來,一不小心,就會導致結果出錯。
我舉個例子。
有一個成績表achieve,有四個字段:yuwen、shuxue、yingyu、total, 分別用來存儲語文、數學、英語及總分。現在要計算學生的總分,現寫出如下SQL語句:
- update achieve set total=yuwen+shuxue+yingyu
這句語句好像是沒錯的,但有時得不出有用的結果,比如,有個學生語文80,數學90,英語缺考,沒填成績,這時yingyu字 段的值很可能不是0而是 NULL,空值,要看設計的人是什 麽想法。如果yingyu的值為NULL, 那麽,大家猜猜,計算出來,總分字段total為多少?
按一般的想法,當然是80+90,這個學生的總分是170,英語字段不參加計算。但是,這是錯誤的!
實際計算出來,這個學生的總分為空(NULL)。
在一個SQL計算表達式裏,如果有一個值為空,那麽結果就一定為空!這就是空值擴散!!!
那麽,如何防止出現空值擴散的情況呢?
在這方面,SQL Server提供了ISNULL()函數,Access提供了NZ()函 數,都可以解決這個問題,這些函數就是提供一個判斷功能:如果為空,則用某個值代替,比如用0或用空字符串等。Firebird有類似函數麽?
有,那就是函數coalesce()。
只要將以上的SQL語句改為如下即可。
- update achieve set total=coalesce(yuwen,0)+coalesce(shuxue,0)+coalesce(yingyu,0)
這樣寫,似乎麻煩了一些,但是,它是一個安全的代碼。
Firebird 數據庫使用經驗總結