http://www.cnblogs.com/snooper/archive/2009/09/07/1561715.html
mantis的安裝配置(for windows)
http://blog.csdn.net/lyd518/article/details/1857073
下面是郵件服務器:
在c:\php-5.0.3\php.ini文件中查找smtp,將localhost改為你的發件服務器,如SMTP =
smtp.163.com
在php.ini文件中查找sendmail_from,將前面的分號去掉,并在后面填上郵件地址
在c:\mantis-0.19.2\config_inc.php文件中添加
$g_smtp_host='smtp.163.com';////IP地址也可以
$g_smtp_username='yourusername';
$g_smtp_password='yourpassword';
$g_phpMailer_method =2;
查找$g_return_path_email,將后面的郵件地址改為有效的地址,這一點非常重要,不然將無法正常
發送激活注冊的郵件。
config_inc.php其它郵件地址最好也改為有效的地址。
$g_smtp_username,$g_smtp_password在服務器需要驗證時用,不需驗證時不用加,或設為
$g_smtp_username='
$g_smtp_password='
現在你可以注冊新用戶,并使用發送郵件功能了。
(4)關于界面語言(漢化)
在這個版本中已經自帶了中文簡體,以管理員身份登陸后,選擇個人帳號(My Account),然后選擇更改個人設置(Preferences),找到界面語言(Language),選擇下拉列表中 chinese_simplified,點擊更新設置(Updata Prefs)之后重新登陸就ok了
郵件服務器的配置:
1.fast mail
server安裝可以網絡上搜到,一路安裝下來,設置SMTP gateways為你的IP取一個名字如:huan.com,
2.加用戶:admin@huan.com
3,可用OUTLOOK設置驗證你的郵件器是否可以發郵件
因為向往 所以選擇了遠方 因為無可依靠 所以必須堅強
BugFree是借鑒
微軟的研發流程和
Bug管理理念,使用PHP+MySQL獨立寫出的一個Bug管理 系統。簡單實用、免費并且開放源代碼(遵循GNU GPL)。 命名BugFree 有兩層意思:一是希望軟件中的缺陷越來越少直到沒有,Free嘛;二是表 示它是免費且開放源代碼的,大家可以自由使用傳播。
如何有效地管理軟件產品中的 Bug,是每一家軟件企業必須面臨的問題。遺憾的是很多軟件企業還是停留在作坊式的研發模式中,其研發流程、研發工具、人員管理不盡人意,無法有效的保證質量、控制進度,并使產品可持續發展。
具體安裝操作步驟:
步驟一:下載XAMpp安裝包
此安裝包中有Apache 、
MySQL、PHP 等所需的工具
下載地址:http://www.apachefriends.org/zh_cn/xampp-linux.html
步驟二:安裝
2、將下載的壓包文件拷貝到 /opt 目錄下
3、解壓安裝:
cd /opt
tar xvfz xampp-linux-1.7.7.tar.gz
注意:執行此命令時,會自動覆蓋xampp舊版本
4.修改lampp的默認端口號80
vim /opt/lampp/etc/httpd.conf
修改80端口為自定義端口號
5.運行
/opt/lampp/lampp start
Starting XAMPP 1.7.7...
LAMPP: Starting Apache...
LAMPP: Starting MySQL...
LAMPP started.
【注意】如果啟動失敗,請先停掉相關服務httpd,mysql,ftp
pkill httpd
pkill mysql
pkill ftp
檢查啟動狀態/opt/lampp/lampp status
6. 配置mysql(可參考http://www.cnblogs.com/dengzhangkun/articles/3664488.html)
登陸mysql (首次登陸密碼為空)
Mysql -uroot -p
回車登陸
設置root密碼:password=set password(‘123456’);
授遠程登陸權限(navigate可以訪問)
GRANT ALL PRIVILEGES ON *.* TO root@'211.151.97.%' IDENTIFIED BY '!@#$%^123456' WITH GRANT OPTION;
GRANT select,CREATE,INSERT,UPDATE ON *.* TO user_lampp@'211.151.97.%' IDENTIFIED BY '!@#123456';
執行flush privileges 刷新權限設置
7. 重啟lampp
/opt/lampp/lampp restart
步驟三:下載BugFree并安裝
1、下載地址:http://www.bugfree.org.cn/blog/?page_id=9 (bugfree官方網站)
2、下載完成后,先在本地機器,解壓
3、將解壓后的文件復制到Linux系統下 opt/lampp/htdocs 目錄下
本地瀏覽器里登陸:
http://serverName:端口/bugfree/
然后一步一步設置
檢查環境
① 安裝頁面提示,設置文件庫讀寫權限
② cd /opt/lampp/htdocs
③ mkdir BugFile
④ 創建BugFile文件夾
⑤ 配置讀寫權限
⑥ chmod 777 /opt/lampp/htdocs/BugFile
⑦ chmod 777 /opt/lampp/htdocs /bugfree/assets
⑧ chmod 777 //opt/lampp/htdocs /bugfree/protected/runtime
⑨ chmod 777 -R /opt/lampp/htdocs /bugfree/protected/config
⑩ chmod 777–R /opt/lampp/htdocs /bugfree/install
設置數據庫地址、用戶名、密碼、數據庫名
安裝
TestLink所需環境為PHP+MYSQL (支持MS
SQL等),系統推薦使用PHP5.2,安裝成功以后,如果運行時出錯,主要兩種錯:
[1].HP Warning: strtotime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'UTC' for '8.0/no DST' instead in XXX
解決該錯誤的方法是找到錯誤的PHP文件,打開
1、在php文件頭加上:date_default_timezone_set("PRC");
2、更改php.ini種date.timezone的屬性值為PRC,同時去掉前面的注釋就可以了。
[2].Deprecated: Function ereg_replace() is deprecated in D:\Program Files\Apache Software Foundation\Apache2.2\htdocs\testlink\lib\functions\lang_api.php on line 173
解決該錯誤的方法是打開PHP.INI文件,將
;extension=php_mbstring.dll
改為
extension=php_mbstring.dll
以及將
;mbstring.func_overload = 0
修改為:
mbstring.func_overload = 7
修改之后,系統成功運行
進去之后,還會發現一個WARNING:
There are security warnings for your consideration. To disable any reference to these checkings, set $tlCfg->config_check_warning_mode = 'SILENT';
這需要打開TestLink下config.inc.php文件,將
$tlCfg->config_check_warning_mode = 'FILE';
改為
$tlCfg->config_check_warning_mode = 'SILENT';
再運行,WARNING消失!
1. Testlink 中新增custom field。
2. 用例中custom field中加入該用例對應測試類名和方法名,格式:com.example.demo.TestUrl#prodApi。
3. Jenkins中安裝Testlink Plugin,安裝后在“管理Jenkins”->“組態設定”->“TestLink Installation”中填入你的Testlink資料。
URL:http://localhost/testlink-1.9.9/lib/api/xmlrpc/v1/xmlrpc.php
Developer Key:在Testlink的“My Settings”->“API interface”中,“Generate a new key”。
4. Jenkins的專案設定中,“新增建置后步驟”選擇“Invoke Testlink”,然后在“TestLink Configuration”中填入Testlink中對應的資料。然后“Result Seeking Strategy”->“add strategy”選擇“
JUnit method name”并填入對應資料(“Include Pattern”填入“**/TEST-*.xml”)。
5. 構建項目,完成后應該見到Testlink有相應的執行結果。
CERT安全編程團隊,隸屬于卡內基梅隆大學軟件工程學院,最近發布了
Android平臺上Java應用的安全編程指南。
CERT在該領域已經有所積累,并且在2013年發布CERT Java安全編程規范,后來出版Java編程指南:可靠安全編程的75條建議一書,該Android指南是對以上
工作成果的拓展和延伸。所以,在新版Android編程規范和指南中,一部分是參照已有的Java規范指南,當然也少不了與Android相關,致力于解決
移動相關問題的新規則。
Lori Flynn是發起CERT Android編程規范和指南的研究人員之一,據她所說,“其他地方也存在這樣的Android安全編程建議,但是我們發現這些建議都不完整并且分散在網絡的各個角落。”CERT研究人員采用以下三種方式制定了新版Android編程規范與指南:
挖掘CERT已有的安全編程規范;
研究已有漏洞
數據庫,包括國土安全部的國家漏洞數據庫等;
研究目前與安全相關的文獻,比如,研究論文、在線
文章以及安全會議演講等。
所有規范和指南都可以在CERT Wiki上獲取。每條記錄以簡要概述開頭,然后描述此條規范所要解決的安全問題,并且包括違規代碼案例。Wiki中還提供了基于嚴重程度的評分、漏洞被惡意使用的可能性,以及如果在代碼中發現漏洞,修復漏洞的成本等。
小編聯系了Lori Flynn,并針對CERT Android安全編程規范和指南采訪了她。Lori目前在CERT的工作不僅包括完善新版安全編程規范,還包括對移動應用進行組合性靜態分析,檢查是否符合Android平臺的數據流規則。她工作經歷豐富,包括網絡安全研究,基于標準的安全分析,以及合作開發了一種檢測多態程序的新型靜態分析方法,并且取得了專利。Flynn在圣克魯斯獲得了加利福尼亞大學的計算機科學博士學位,她的研究方向是移動自組網絡的安全多播路由協議。
Lori,您能簡要介紹一下Android安全編程規范和指南的目標受眾有哪些嗎?
我們制定的Android安全編程規范和指南目前主要面向使用Java語言的Android應用開發人員。但是,我們也在著手制定適用于基于底層(非Java)語言如C和C++所開發應用的安全規范。我們的目標是幫助開發人員構建可靠安全的系統,但是這些規范和指南對實現其他質量特性如可靠性也大有裨益。
所有希望保護客戶系統免受危害的組織或個人,在其開發人員遵循規則和指南并產出安全代碼后,都會從中受益。金融、衛生和防御系統都必須小心保護其應用所處理的信息。有些應用處理的數據非常敏感——比如,用戶的信用卡信息、位置、短信、聯系方式和照片。除了對用戶造成潛在傷害外,非安全代碼可能會使處于金融風險中的開發人員走上法庭,也可能使整個公司失去公眾信任(和導致銷售損失),或導致困難局面,使給公眾造成不安全印象的單應用銷售乏力。
總而言之,知曉Android安全編程規范和指南,不論對于大型組織還是獨立應用開發者都會有所幫助。
軟件開發管理者、軟件需求方,或者其他軟件開發和需求專家可以將安全編程規范作為禁止性需求的參考。教育工作者也可以通過該指南教會學生安全開發Android應用的方法。
據您所知,移動相關人員在碰到應用安全問題時面臨的主要挑戰是什么?在移動領域,您是否知道某些特定安全相關問題?
除了已知的公認安全編程問題以及規范和指南給出的修復方法外,無法有效把控應用的數據去向也是我們面臨的挑戰之一。信息泄露如此泛濫,Android應用之間的相互影響是主要原因。我們目前正在研發靜態分析工具,用于檢測和消除這些漏洞。有了這些工具,用戶——包括個人和組織——將更有信心解決部分應用的數據泄露問題。然而,盡管我們目前的工作有效促進了安全分析的發展,但是還是無法解決底層代碼或反射面臨的安全問題。數據流安全問題同樣非常嚴重,所以有許多工業界和學術界的研究人員在這方面傾注心血。
另一個問題是可用性。實際上在我們深入分析數據流時,應用需要給用戶展現對應選項,還得讓用戶(開發人員用戶排除在外)容易明白這些選項的意義。Adrienne Porter Felt(
Google)已經發表了若干非常優秀的研究論文,分析了用戶界面安全問題并給出了修復建議。她的工作涉及面向開發人員的可用性問題,比如與權限相關的不恰當API,可能導致正常開發人員的權限過大,進而被惡意應用利用。
Android安全還面臨另一個問題,在Google修復Android暴露的安全問題后,因為各種原因,移動運營商可能在很長時間后才將安全更新推送給用戶。這就導致在這段時間內,與應用相關的數據將面臨巨大的風險。
遵循Android安全編程規范和指南,對應用有哪些好處?您有沒有這方面的案例,遵循指南后,應用能夠避免以前遇到的安全問題?
如果我們能夠嚴格遵守Android安全編程規范和指南,數據和系統會更安全。舉個例子吧,DRD00-J禁止將敏感數據保存到SD卡中,因為其他應用可以讀取SD卡,DRD01-J限制內容提供者中敏感數據的權限等。Skype的Android應用曾經出現過一個漏洞,該應用將聯系信息和個人用戶信息保存在未加密數據庫中,并且沒有實施權限控制。如果應用遵守DRD01-J就可以避免該問題。
為了改善語言的安全現狀,SCI(Secure Coding Initiative)發起了開發編程語言國際規范的工作。該規范致力于防范代碼漏洞,并充分利用在研發CERT安全編碼規范和
一致性測試中所收集的信息。
您對應用CERT安全編程規范和指南有哪些建議方法,工具、流程或其他方法都可以?感興趣的開發人員或組織要如何開始呢?
我建議開發人員首先通讀我們的技術報告,移動源碼安全分析實驗室:Java和Android安全編程規則和分析,然后瀏覽Android安全編程首頁。我們打算創建單獨的CERT編程規范,就像其他CERT安全編程規范一樣可以通過CERT編程規范Wiki主頁訪問。該首頁概述了我們目前在研發Android安全編程規范方面的工作:分析(適用性)和擴展已有Java規范;分析(適用性)和擴展Java指南,雖然該指南還在制定過程中;制定面向Android的安全編程規范,但該規范并不一定只針對Java語言。查看出現在首頁中的三個主題鏈接,這是Android安全編程規范制定中的主要課題。
接下來,我建議開發人員瀏覽一遍DRD規范和指南,并考慮如何將它們應用到應用編程中。然后,我建議大家閱讀Java CERT
Oracle安全編程規范(Addison-Wesley Professional, 2011)中適用于Android的Java規范,包括Wiki,關注該書相關的主題。這些規則是安全應用必須遵守的,這也是將其放在指南前面的原因。讀完規則后,以同樣方式閱讀Java編程指南:可靠安全編程的75條建議(Addison-Wesley Professional,2013)。雖然我們不一定能夠立即將書中列出的規范和指南應用到工作中,但是這些知識精華會印入我們的腦海,當開發應用需要用到這些規范和指南時,我們可以再仔細查看。另外我們值得做的是訂閱安全編程簡報,LinkedIn上的安全編程討論,還有安全編程wiki中的提醒,當增加新規范和指南時會立即提醒。這些渠道有助于開發人員及時知曉安全方面的修復程序。
您在Android安全編程規范方面的工作完成了嗎?或是您有沒有設想將來涉及其他領域?
我們在Android安全編程指南方面的工作還在繼續。另一個我們特別想研究的領域是分析CERT安全編程指南在基于C和C++的Android應用中的適用性。我們已經有了初步的分析,但是要檢驗Android底層編程接口如何影響已有編程規則的適用性,還要付出更多努力。同時,我們也會完善應用于反射的初步規則和指南。
你們的團隊還有其他類似的項目嗎?
我們的CERT安全編程倡議(SCI)已經為C、C++、Java和Perl制定了安全編程規范,其中一些規范已經被像Cisco和Oracle這樣的企業在公司范圍內采用。我們鼓勵開發人員以及其他使用這些語言工作的組織使用我們的安全編程規范,這將會帶來諸多好處,就像使用Android安全編程規范和指南一樣。
SCI的目標是將漏洞的數目降低到某個級別,有效緩解運營環境中的風險應用。該目標通過在實現和測試階段預防編程錯誤或檢測并清除安全缺陷來達成。同時,SCI也在持續壯大源碼分析實驗室(SCALe),支持根據我們的編程規范對系統進行一致性測試,包括針對移動平臺(Mobile SCALe)的一致性測試。移動SCALe目前專注于Android平臺,因為這是我們在制定安全編碼規范和指南時所面向的首個移動平臺。我們還計劃支持針對Apple iOS和Microsoft
Windows 8的安全編程規范和一致性測試。
前面說到在實施冒煙
測試自動化時候,當時使用的selenium1.0所支持的瀏覽器版本太低,無法滿足我們的需求,面對這個問題,唯有升級我們的框架,可是面前有1千多條自動化用例等著,的確需要花費很大的人力和時間來完成。當時后臺組也已有人研究過Webdriver,在其中一個產品中用起來了,但是并沒有對原來的東西全部升級,不過至少證明了它的實用價值。當時我跟我老大說我研究下Webdriver,OK的話要不我們索性全部升級吧。當時他還持懷疑的態度,畢竟這并不是一個小的
工作量。
就這樣開始了升級之旅。剛開始時就是我自己查了很多的資料,通過新建一個項目,把原來下面所有內容復制過來,把Maven的POM文件中dependency全部改成了全新的Webdriver,然后對框架中driver實例化的地方進行了修改,當然這些還遠遠不夠。因為兩個版本設計理念不一樣,原來的方法也無法通用,為了便于日后分享給大家順利開展工作,是很有必要把兩個版本如何操作頁面元素的做個對比。接下來就是把我們日常用到的方法羅列出來,包括打開頁面,點擊元素,輸入,下拉選擇,單選,復選,獲取文本內容,彈出框,frame的操作等等,接著把在1.0里的方法寫出來,把2.0對應的方法也寫出來,然后再對其中一條用例進行實驗,把底層這些方法改成新的。
到這里,鉆研之路就進行的差不多了,見證奇跡的時刻到了。如果我說一運行case就通過了,也許這并不值得懷疑,但是事實上并沒有這么順利,中間遇到的諸多事宜我也記不清了,但是好在最后的確是通過了。我甚是欣喜,告訴了我老大,同時我組織我們組其他幾個做自動化的同學開始了全面的升級行動。我把中間做過的事情整理成了文檔,把1.0 VS 2.0的方法整理成表格,方便大家對照修改。當時我們做這個的順序是:第一步,把所有底層的方法對照著表格全部改完,認真思考的你可能也看出來了,這的確是個苦差事,已經沒有什么技術含量了;第二步,分工把所有的冒煙級別用例重新調試運行直到測試通過。
經過大家一個Q的努力,升級工作圓滿結束,不過在這之后,原來那1千多條case其實也被我們放棄了,主要原因并不是調試的工作量,而是那些是之前專門的自動化組寫的用例,很多都不是按照業務重點來寫的,對我們的價值并不大,之后我們所完成的400多條都是基于重新梳理手工用例后實施的,當然這些也都是基于新升級的框架上寫的。當時在升級過程中關于如何進行的修改還寫了一篇博文,請查看歷史
文章。
版權聲明:本文出自 zzzmmmkkk 的51Testing軟件測試博客:http://www.51testing.com/?258885
原創作品,轉載時請務必以超鏈接形式標明本文原始出處、作者信息和本聲明,否則將追究法律責任。
相關文章:
2014年4月21日,我很榮幸進入網易
工作,新的環境、新的同事及新任務項目對我來說都是全新的挑戰,非常感謝領導、負責人及其他同事的關心照顧和指導。到網易已經一個多月了,針對這段時間的工作情況,做以下總結:
一、關于工作
1、熟悉
每個公司的項目產品流程都不一樣的,換了工個環境,所熟悉的業務和環境都改變了,要從頭開始了解。剛到網易,首先肯定是熟悉,熟悉同事、熟悉環境。一開始同事們就很照顧我,有問必答,讓我一點點慢慢熟悉起來。雖然我是外包人員,但在這里完全感受不到以前聽別人說的外包人員怎么怎么的情況。最開始,自己也有點顧忌,后來就想通了,感謝翟姐的一句話讓我更有自信。第二步,熟悉項目、熟悉產品、熟悉業務,第一周,主要了解已有的產品和項目,照著已有的用例進一步了解。第二周,開始了解新項目需求。
項目、業務稍微熟悉了之后(好吧,其實很多東西都還不是很熟),慢慢開始參與新項目的測試分析和
用例設計,同事們很照顧,先分配了一些比較簡單、比較基礎的模塊給我,讓我慢慢上手。雖然大學畢業到現在2年多時間一直從事
軟件測試,不過以前接觸較多的還是
手機軟件測試,在
web測試上是比較淺層的經驗,也算個菜鳥吧,很多web測試需要注重的點會考慮不周全、隱藏點會遺漏,劃分測試分析分類時思路比較亂,感謝丹姐幫我看測試分析,幫我分析比較清晰的思路和分類。設計測試分析和用例時注意一下幾點:
1)熟悉需求和業務,不了解需求或需求不明確的情況不能盲目設計;
2)設計過程有疑點,需求有問題時及時與他人溝通,找策劃確認,不要按照自己常理和想象做決定
3)考慮
測試用例的復用性,功能相似的模塊可以考慮整合到一起,不需設計重復用例
4)對用例進行分類,劃分思路清晰的分類,評審時能夠讓他人比較清晰的了解
5)根據測試用例的設計方法(等價類、邊界值、錯誤推測、因果圖等等)進行用例設計,當然也要根據產品模塊情況,針對比適用的模塊,可以減少一定工作量,不適用的模塊反而會加大工作量。
3、測試維護任務
目前接觸了兩個維護任務,任務比較簡單,但也不能因為簡單而稍有馬虎,要對維護任務的需求了解清楚,有針對性的測試。開發提測后,不僅要對修改的模塊進行測試,還要了解修改的地方影響的范圍,對有影響的地方也要測試回歸一下。
做測試以來,一直對
自動化測試、
性能測試比較憧憬,自己也有買參考書、根據網上資料進行學習,不過平時不常用,時間一久就拋之腦后了(自己知道這個問題,一直努力改正來著)。
Dagger是網易杭研QA自己開發的一個WebUI自動化測試框架,基于
Selenium和TestNG組合和封裝的。在熟悉環境和看測試分析的時候,看到劉主席在跟比我晚2天來的實習MM講解這個框架,心里癢癢,一旁觀摩了一下,然后問同事要了資料,空閑之余根據wiki上的資料例子學習,因為對Selenium和TestNG也不熟悉,使用過程中問題比較多,下載的包不對、缺少必要的jar包、執行wiki上的用例代碼報錯或找不到頁面元素、缺少瀏覽器驅動等,然后網絡上搜索各種問題解決方案。一些小問題基本解決了,想著拿現有網站練練手(這就是典型的還沒學會走就想著飛啊),照葫蘆畫瓢的寫了一堆,執行各種錯誤,度娘都解決不了了。所有還是要一步一個腳印慢慢走——先把Dagger放一邊,找到一些比較基礎的Selenium資料,目前正在循序漸進的學習,然后等Selenium扎實了繼續學習TestNG,等這些都熟練了再去征戰Dagger。
在今后的工作中,我會不斷完善自己,提高業務&技術水平,相互學習,共同進步!做好自己的本職工作,為公司創造更高的價值,力爭取得更大的成績。
今天 在項目中看一個存儲過程的時候,發現同事寫的之前的有些邏輯錯誤,可能這個錯誤比較典型吧 拿出來分享一下,不使用公司的
數據庫,所以在自己的機子上模擬了一下這個場景。OK
首先,就是2個表,
表temp1,包括id1,val1,2個字段,
表temp2,包括id2,val2 2個字段。
首先,情景大致是這樣的,2個表的ID是有關聯的,就是把temp2中包含的temp1的id的數據,在temp1中把val1都設置為1,不包含的設置為0.
首先,發一下之前錯誤的存儲過程。
create or replace procedure mysdtest as cursor te_v1 is select id1,val1 from Temp1; cursor te_v2 is select id2,val2 from Temp2; v1_t te_v1%rowtype; v2_t te_v2%rowtype; begin open te_v1; loop fetch te_v1 into v1_t; exit when te_v1%notfound; open te_v2; loop fetch te_v2 into v2_t; exit when te_v2%notfound; if v1_t.id1=v2_t.id2 then update temp1 set val1='1' where id1=v1_t.id1; else update temp1 set val1='0' where id1=v1_t.id1; end if; end loop; close te_v2; end loop; close te_v1; end; |
這樣寫邏輯是存在問題的,2層循環,結果就會發現都是0,仔細讀一下程序就會發現問題
比如說有一個值 t1 在表temp1中有值,應該更新val1為1,但是遍歷到下一個t2時,此時t1不符合,然后就執行else 那么t1的val1就又變回了0,所以,程序執行完,都執行了else里面的,當然就錯了。
正確的寫法很多種,這里我就以設置帶參數的游標為例,將2個游標建立關系,再進行遍歷就不會出現問題。
如下:
create or replace procedure myt as cursor te_v1 is select id1,val1 from Temp1; cursor te_v2(idv2 varchar2) is select count(*) from temp2 where id2=idv2; v1_t te_v1%rowtype; numv varchar2(2); begin open te_v1; loop fetch te_v1 into v1_t; exit when te_v1%notfound; open te_v2(v1_t.id1); fetch te_v2 into numv; if numv=0 then update TEMP1 set val1='0' where id1=v1_t.id1; else update TEMP1 set val1='1' where id1=v1_t.id1; end if; close te_v2; end loop; close te_v1; end; |
ok,這種問題我們應該注意到
數據庫是以某種數據模型所確定的數據結構方式來組織和存儲某個組織(或部門)相互關聯的數據集。數據庫管理系統是一種幫助用戶建立、使用、管理和維護數據庫的計算機系統軟件?;蛘哒f,數據庫管理系統是開發一個實際應用數據庫的工具并支撐其運行的平臺。數據庫管理系統必須與其管理的數據庫的數據模型相一致。
1.數據模型
數據模型是對現實世界數據特征進行抽象的工具,用來描述和處理現實世界中的數據和信息。數據模型要能較真實地模擬現實世界,既要便于人們理解,又要便于在計算機上實現。數據模型主要由數據結構、數據操作、數據完整性規則三個部分組成。數據結構描述了組成數據庫的基本成分;數據操作描述了對數據結構允許執行的操作集合;完整性規則描述了對數據結構所具有的約束和存儲規則。
2.關系數據模型
關系數據模型的數據結構是人們日常事務處理中常見的二維表結構(如工資發放表)。關系數據模型將數據看成是二維表中唯一的行號和列號確定的一個表中元素,即關系數據模型是用二維表的方式來組織、存儲和處理數據和信息的。從應用的角度來看,任何一個組織(或部門)的關系數據庫的基本組成成分是二維表,或者說某個組織(或部門)的數據庫是由若干張相互關聯的二維表組成。由于二維表結構清晰、簡單、易于理解,也易于計算機實現(存儲、操作、控制),加上關系數據模型有數學理論基礎(集合論、關系代數),因此現在的數據庫管理系統軟件都是基于關系數據模型研發的,如
SQL SERVER、ORACLE、DB2、SYBASE、ACCESS、FOXPRO等等。也就是說,用這些關系數據庫管理系統軟件為某個組織開發的會計數據庫系統必須按關系數據模型來組織數據。那么,關系數據模型中的二維表與數據庫中的數據文件之間有何聯系?
下面我們通過會計科目代碼表來介紹關系數據模型的基本概念及其與數據庫中的數據文件之間的對應關系:
?。?)關系、二維表、數據文件:關系數據模型中用關系來表述現實世界中能夠相互區別的要管理的數據對象集。每一個關系都有一個關系名和一組表述其特征的屬性集,人們就是通過這些屬性集區別不同的關系。如記賬憑證、會計科目、總賬都可以稱之為關系,它們都是要管理的數據對象集,都有各自的屬性集。一個關系用一張二維表表示,表名對應關系名。二維表由有限個不重復的行組成,表中的每一列不可再分。一張二維表在關系數據庫中用一個數據文件存儲。如“會計科目代碼表”在會計數據庫中用一個數據文件存儲,文件名可以用表名“會計科目代碼”,使計算機中存儲的文件內容與現實世界管理的數據對象相聯系。
?。?)記錄:二維表中的每一行稱為一個記錄,描述了關系中一個具體的個體,在數據文件中是一個記錄值。如表1中第一行為現金賬戶的記錄,描述了現金賬戶在會計科目代碼文件中所有屬性的取值(特征)。
(3)屬性、列、字段:二維表中的每一列是一個屬性,描述了關系的一個特征。一個二維表的所有列構成了一個關系的屬性集,通過它可以區別不同的二維表(關系)。二維表中的每一列的數據屬于同一類型。每一列的列名對應關系的屬性名,同時對應數據文件中的字段名。如表1用6個列表示會計科目代碼的屬性,其中第三列表示屬性“科目性質”,當某條記錄取值為1時,表示是資產類科目。
?。?)主碼、主關鍵字:指二維表中的某個列(屬性)或某幾個列(或屬性組),它們的值能夠唯一確定表中或數據文件中的一個記錄。如表1中的“科目代碼”屬性可以作為主碼(或主關鍵字),用來唯一識別表中的每一個會計科目。
?。?)域:描述二維表中每一列屬性或數據文件的某一字段的取值類型和范圍。如表1中每一列的列名下面的括號中的內容表示該列的取值類型和范圍,其中第四列“底層明細標志”表示某個科目是不是最底層明細科目(不再有下層科目),只有兩種取值T(真)和F(假)。
?。?)關系模式:一個關系模式由一個關系名及它所有的屬性構成,它對應一個二維表的表名和表頭欄目行(列的集合),構成了一個二維表的框架,同時也是設計該二維表的數據文件結構的依據。
至此,我們直觀地介紹了關系數據庫中的關系、二維表、數據文件之間各個概念的對應關系。由于二維表中的行與數據文件的記錄、二維表的列(屬性)與數據文件的字段之間相互對應,因此,審計人員只要掌握了會計賬務數據庫的二維表結構及表之間的關聯也就能夠分析電子賬的結構。
例如,將會計科目代碼表轉換成關系數據庫中的數據文件結構
3.關系數據模型的數據操作
從數學的角度看,關系數據模型的數據操作是基于集合的操作,操作對象和操作結果都是集合。從數據處理的角度看,數據操作的對象和結果都是二維表。對二維表的操作主要有:
?。?)對表中的行(記錄)進行操作:指對一張表中指定范圍的記錄進行有條件的操作,操作的結果組成一張新表。例如,從“會計科目代碼表”中篩選出資產類科目組成新的“資產類科目代碼表”,操作的范圍是整個“會計科目代碼表”,條件是“科目性質等于1”。對表中的行進行操作后的結果表的結構與原表相同,記錄數小于或等于原表。
?。?)對表中的列(屬性)進行操作:指對一張表中指定的列進行有條件的操作,操作的結果組成一張新表。例如,從“會計科目代碼表”中選出“科目代碼”、“科目名稱”兩列,組成新的科目代碼對應表,新表只有“科目代碼”和“科目名稱”兩列。顯然,列操作后的結果表的結構與原表不同,結果表小于或等于原表。
?。?)連接:對兩張表或多張表進行有條件的連接操作,生成一張新表。連接操作后的結果表大于等于操作前的表。
從應用的角度看,對二維表中的數據操作功能主要包括更新(增加、修改、刪除)數據和檢索(查詢)數據,即對二維表填入和修改數據,并從表中檢索出數據進行加工應用。
4.關系數據模型的數據完整性規則
數據完整性是指數據庫中存儲的數據是有意義的或正確的。關系數據模型中的數據完整性規則是指對二維表的定義和操作過程中要遵循的某些約束條件。主要包括:
?。?)實體完整性:指每張表都必須有主碼,而且表中不允許存在無主碼值的記錄和主碼值相同的記錄。如表1中的每一個記錄都必須有科目代碼,并且不能有相同科目代碼的記錄和無科目代碼的記錄。
?。?)參照完整性:指一張表的某列的取值受另一張表的某列的取值范圍約束,描述了多張表之間的關聯關系。例如,記賬憑證表中的“科目代碼”列的取值受到會計科目代碼表的“科目代碼”取值范圍的限定。
?。?)用戶定義完整性。指針對某一具體應用定義的數據庫約束條件,反映某一具體應用所涉及的數據必須滿足應用語義的要求。即限制屬性的取值類型及范圍,防止屬性的值與應用語義矛盾。如表1中,“科目性質”的取值只能是1(資產)、2(負債)、3(權益)、4(成本)、5(損益)。
5.從關系數據模型得到的啟示
(1)基于關系數據模型的會計賬務數據庫是以二維表為基本部件構建的,數據庫中的每一個數據文件對應一張二維表,數據文件之間的關聯也可以用二維表之間的關聯來表示,對二維表的定義和數據操作必須滿足數據完整性約束條件。構建一個會計賬務數據庫首先要將會計賬務管理的對象,如會計科目、記賬憑證、日記賬、明細賬、總賬及它們之間的關系抽象成二維表的形式,弄清了它們的二維表結構也就弄清了它們的數據文件結構,即電子賬結構。因此,會計賬務數據庫結構設計可以轉變成會計賬務數據的二維表及二維表之間的關聯設計,而一張二維表的表頭欄目(屬性集)反映了表的結構特征,是設計數據文件結構的依據。
?。?)依據關系數據模型研發的關系數據庫管理系統是開發和管理會計數據庫系統的工具軟件,也是支持所開發的會計數據庫系統運行的平臺,任何一個會計賬務數據庫都必須在某一個關系數據庫管理系統的在線管理下運行。由于不同的數據庫軟件公司提供的關系數據庫管理系統軟件的各個版本的功能強弱、所適應的計算機系統的運行環境(單機、網絡等)、所提供的對表的操作命令等都有所不同,因此,審計人員要審查電子賬,首先要了解被審單位的電子賬的數據庫管理系統軟件的名稱(例如是SQL SERVER或ORACLE)、版本(單機、網絡,第幾版)、打開數據庫(表)以及對表操作的命令格式和命令等。盡管各種關系數據庫管理系統軟件版本有差異,但通過以上對關系數據模型的操作可以了解到:表的主要操作類型和功能基本一致。審計人員僅需要掌握最基本的打開、檢索、匯總數據庫(表)等操作命令就能進行審查會計賬務數據庫的基本工作,并非深不可測。
/** * 本例解決的問題: * 核心問題:通過SQLiteOpenHelper類創建 數據庫對象 * 通過數據庫對象對數據庫的數據的操作 * 1.sql語句方式操作SQLite數據庫 * 2.谷歌提供的api對SQLite數據庫的操作 * 3.SQLite對事務的操作 */ import com.ghsy.createsqlitedb.db.MyOpenHelper; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.test.AndroidTestCase; public class Test extends AndroidTestCase { MyOpenHelper oh; SQLiteDatabase db; public void test() { // 創建一個MyOpenHelper對象 // 改動此處的版本,會運行upgrade方法--upgrade方法中加入?了一列 MyOpenHelper oh = new MyOpenHelper(getContext(), "people.db", null, 3); // 假設數據庫不存在,先創建數據庫,再打開數據庫,假設已經存在,直接打開 SQLiteDatabase db = oh.getWritableDatabase(); db.close(); } // 測試框架初始化完畢 /** * This method is called before a test is executed */ @Override protected void setUp() throws Exception { // TODO Auto-generated method stub super.setUp(); oh = new MyOpenHelper(getContext(), "people.db", null, 3); db = oh.getWritableDatabase(); } |
// ===========sql語句方式操作SQLite數據庫================================
public void insert() { db.execSQL("insert into person(name, phone, money) values(?, ?, ?)", new Object[] { "大明", "18666", 6000 }); db.execSQL("insert into person(name, phone, money) values(?, ?, ?)", new Object[] { "小紅", "18666", 6000 }); db.execSQL("insert into person(name, phone, money) values(?, ?, ?)", new Object[] { "大紅", "18666", 6000 }); } public void delete() { db.execSQL("delete from person where name = ?", new Object[] { "大明" }); } public void update() { db.execSQL("update person set money = 10000 where name = ?", new Object[] { "小明" }); } public void query() { // 游標,存放查詢返回的數據,獲取方法跟resultSet高度雷同 Cursor c = db.rawQuery("select * from person", new String[] {}); while (c.moveToNext()) { String name = c.getString(c.getColumnIndex("name")); String phone = c.getString(c.getColumnIndex("phone")); System.out.println(name + ";" + phone); } } |
// ==============谷歌提供的api對SQLite數據庫的操作======================
/** * api-insert data to table */ public void insertApi() { ContentValues cv = new ContentValues(); cv.put("name", "微明"); cv.put("phone", 15666); cv.put("money", 630); long id = db.insert("person", null, cv); System.out.println(id); } /** * api-delete data from table * * @return the number of rows affected */ public int deleteApi() { int affectedNum = db.delete("person", "name=?", new String[] { "小紅" }); return affectedNum; } /** * api-update */ public void updateApi() { ContentValues contentValues = new ContentValues(); contentValues.put("name", "小紅"); contentValues.put("money", "10"); // return the number of rows affected db.update("person", contentValues, "name=?", new String[] { "大紅" }); } public void queryApi() { Cursor cursor = db.query("person", new String[] { "phone", "money" }, null, null, null, null, null); while (cursor.moveToNext()) { String phone = cursor.getString(cursor.getColumnIndex("phone")); String money = cursor.getString(cursor.getColumnIndex("money")); System.out.println(phone + "##" + money); } } |
// ===============SQLite對事務的操作=====================
/** * 銀行轉賬操作 */ public void transation(){ db.beginTransaction(); try { //name為微明的用戶向小紅轉賬 ContentValues contentValues=new ContentValues(); contentValues.put("money", 1000); db.update("person", contentValues, "name=?", new String[]{"微明"}); ContentValues contentValues2=new ContentValues(); contentValues2.put("money", 1100); db.update("person", contentValues2, "name=?", new String[]{"小紅"}); //全部語句運行完畢,若沒有異常,則會運行這句設置事務成功的標記 db.setTransactionSuccessful(); } finally { //會檢查事務的標識,若沒有調用setTransactionSuccessful()方法設置標志,則回滾事務。否則提交事務。 db.endTransaction(); } } } MyOpenHelper.java **SQLiteOpenHelper: * A helper class to manage database creation and version management. * 所以,SQLiteOpenHelper是對庫本身的操作。若要對庫中數據操作,須要使用庫對象的方法。 */ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class MyOpenHelper extends SQLiteOpenHelper { //name:數據庫文件的名字 //factory:游標工廠 //version:版本號,必須大于等于1 public MyOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } //數據庫創建時調用 @Override public void onCreate(SQLiteDatabase db) { //創建一個person表 db.execSQL("create table person(_id integer primary key autoincrement, name char(10), phone char(20))"); System.out.println("oncreate調用了"); } //數據庫升級時調用 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub System.out.println("onupgrade調用了"); db.execSQL("alter table person add money char(20)"); } } |