日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

课程设计:基于SQL Server的银行ATM 存取款机系统设计与实现

發(fā)布時間:2025/3/15 windows 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 课程设计:基于SQL Server的银行ATM 存取款机系统设计与实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 前言
  • 一、項目背景
    • 1、項目任務(wù)
    • 2、項目技能目標(biāo)
    • 3、需求概述
    • 4、開發(fā)環(huán)境
    • 5 、問題分析
      • (1) 銀行存取款業(yè)務(wù)介紹
      • (2) 客戶信息
      • (3) 銀行卡賬戶信息
      • (4) 銀行卡交易信息
      • (5) 銀行卡手工賬戶和存取款單據(jù)信息
  • 二、項目實訓(xùn)內(nèi)容
    • 1、實訓(xùn)一:制定《數(shù)據(jù)庫設(shè)計與編程規(guī)范》
    • 2、實訓(xùn)二:數(shù)據(jù)庫分析設(shè)計與建模
      • (1) 分析銀行 ATM 存取款系統(tǒng)實體
      • (2) 規(guī)范數(shù)據(jù)庫結(jié)構(gòu)設(shè)計
      • (3) 繪制 CDM 模型、生成 PDM 模型
    • 3、實訓(xùn)三:創(chuàng)建數(shù)據(jù)庫
      • (1) 創(chuàng)建數(shù)據(jù)庫
      • (2) 創(chuàng)建各個數(shù)據(jù)表及相關(guān)的約束
      • (3) 添加外鍵約束和生成數(shù)據(jù)庫關(guān)系圖
    • 4、實訓(xùn)四:創(chuàng)建觸發(fā)器和插入測試數(shù)據(jù)
      • (1) 創(chuàng)建級聯(lián)觸發(fā)器
      • (2) 插入數(shù)據(jù)表的測試數(shù)據(jù)
    • 5、實訓(xùn)五:模擬常規(guī)業(yè)務(wù)
      • (1) 修改客戶密碼
      • (2) 辦理銀行卡掛失
      • (3) 統(tǒng)計銀行資金流通余額和盈利結(jié)算
      • (4) 查詢本周開戶信息
      • (5) 查詢本月單次交易金額最高的卡號和總交易金額最高的卡號
      • (6) 查詢掛失客戶
      • (7) 催款提醒業(yè)務(wù)
    • 6、實訓(xùn)六:創(chuàng)建、使用視圖
      • (1) 輸出銀行客戶記錄視圖VW_userInfo
      • (2) 輸出銀行卡記錄視圖VW_CardInfo
      • (3) 輸出銀行卡交易記錄視圖VW_TransInfo
      • (4) 根據(jù)客戶登錄名查詢該客戶賬戶信息VW_OneUserInfo
    • 7、實訓(xùn)七:存儲過程實現(xiàn)業(yè)務(wù)處理
      • (1) 完成存款或取款業(yè)務(wù)
      • (2) 產(chǎn)生隨機卡號
      • (3) 完成開戶業(yè)務(wù)
      • (4) 分頁顯示查詢交易數(shù)據(jù)
      • (5) 統(tǒng)計未發(fā)生交易的賬戶
    • 8、實訓(xùn)八:利用事務(wù)實現(xiàn)轉(zhuǎn)賬

加油加油

前言

? ? ? ? 本文章主要是在學(xué)了SQL Server后做的一個課程設(shè)計,全文有三萬多字,接近一千行,光簡簡單單寫這篇博客就花了不少時間,若有出現(xiàn)錯誤之處,請指出,定當(dāng)感激不盡,一起學(xué)習(xí),一起進(jìn)步。


一、項目背景

1、項目任務(wù)

  • 使用PowerDesigner 完成數(shù)據(jù)庫設(shè)計
  • 創(chuàng)建數(shù)據(jù)庫、創(chuàng)建表、創(chuàng)建約束
  • 使用觸發(fā)器和插入測試數(shù)據(jù)
  • 模擬常規(guī)業(yè)務(wù)、創(chuàng)建視圖
  • 使用存儲過程實現(xiàn)業(yè)務(wù)處理
  • 利用事務(wù)實現(xiàn)較復(fù)雜的數(shù)據(jù)更新

2、項目技能目標(biāo)

  • 使用PowerDesigner 完成數(shù)據(jù)庫概念模型和數(shù)據(jù)庫物理模型設(shè)計。
  • 使用 T-SQL 語句創(chuàng)建數(shù)據(jù)庫、表和各種約束。
  • 使用 T-SQL 語句編程實現(xiàn)常見業(yè)務(wù)。
  • 使用觸發(fā)器實現(xiàn)多表之間的級聯(lián)更新。
  • 使用事務(wù)和存儲過程封裝業(yè)務(wù)邏輯。
  • 使用視圖簡化復(fù)雜的數(shù)據(jù)查詢。
  • 使用游標(biāo)技術(shù)實現(xiàn)結(jié)果集的行集操作。

3、需求概述

? ? ? ?某銀行是一家民辦的小型銀行企業(yè),現(xiàn)有十多萬客戶,公司將為該銀行開發(fā)一套 ATM 存取款機系統(tǒng),對銀行日常的存取款業(yè)務(wù)進(jìn)行計算機管理,以便保證數(shù)據(jù)的安 全性,提高工作效率。
? ? ? ?要求根據(jù)銀行存取款業(yè)務(wù)需求設(shè)計出符合第三范式的數(shù)據(jù)庫結(jié)構(gòu),使用 T-SQL 語言創(chuàng)建數(shù)據(jù)庫和表,并添加表約束,進(jìn)行數(shù)據(jù)的增刪改查,運用邏輯結(jié)構(gòu)語句、事 務(wù)、視圖和存儲過程,按照銀行的業(yè)務(wù)需求,實現(xiàn)各項銀行日常存款、取款和轉(zhuǎn)賬業(yè) 務(wù)。

4、開發(fā)環(huán)境

  • 數(shù)據(jù)庫:SQL SERVER 2008 開發(fā)版
  • 數(shù)據(jù)庫建模工具:PowerDesigner15

5 、問題分析

該項目的 ATM 存取款機業(yè)務(wù)如下:

(1) 銀行存取款業(yè)務(wù)介紹

? ? ? ?銀行為客戶提供了各種銀行存取款業(yè)務(wù)。詳見表 1

(2) 客戶信息

? ? ? ?每個客戶憑個人身份證在銀行可以開設(shè)多個銀行卡賬戶,開設(shè)賬戶時,客戶需要 提供的開戶數(shù)據(jù)如表 2 所示:

(3) 銀行卡賬戶信息

? ? ? ?銀行為每個賬戶提供一個銀行卡,每個銀行卡可以存入一種幣種的存款,銀行保 存賬戶如表 3 所示:

客戶持銀行卡在 ATM 機上輸入密碼,經(jīng)系統(tǒng)驗證身份后辦理存款、取款和轉(zhuǎn)賬 等銀行業(yè)務(wù)。銀行規(guī)定,每個賬戶當(dāng)前的存款金額不得小于 1 元。

(4) 銀行卡交易信息

? ? ? ?銀行在為客戶辦理業(yè)務(wù)時,需要記錄每一筆賬目,賬目交易信息如表 4 所示:

(5) 銀行卡手工賬戶和存取款單據(jù)信息

? ? ? ?該銀行要求這套軟件實現(xiàn)銀行客戶的開戶、存款、取款、轉(zhuǎn)賬和余額查詢等業(yè)務(wù),使得銀行儲蓄業(yè)務(wù)方便、快捷,同事保證銀行業(yè)務(wù)數(shù)據(jù)的安全性。
? ? ? ?為使開發(fā)人員盡快了解銀行業(yè)務(wù),該銀行提供了銀行卡手工賬戶和存取款單據(jù)的 樣本數(shù)據(jù),以供項目開發(fā)時參考,參加表 5 和表 6 。

二、項目實訓(xùn)內(nèi)容

1、實訓(xùn)一:制定《數(shù)據(jù)庫設(shè)計與編程規(guī)范》

  • 長度規(guī)范:
    ? ? ? ?凡是需要命名的對象其標(biāo)識符均控制在 30 個字符以內(nèi),也即:SQL Server 中的 表名、字段名、函數(shù)名、存儲過程、觸發(fā)器、視圖等名字長度要盡量不超過 30 個字 符長度。
  • 構(gòu)成規(guī)范:
    ? ? ? ?數(shù)據(jù)庫各種名稱必須以字母開頭,但嚴(yán)禁以系統(tǒng)關(guān)鍵字開頭,名稱只能含有字母、數(shù) 字以及下劃線“_ ”三類字符, “_ ”用于間隔名稱中的各語義字段;不要使用系統(tǒng)保留字作表名。
  • 大小寫規(guī)范:
    ? ? ? ?構(gòu)成 SQL Server 數(shù)據(jù)庫中的各種名稱(表名、字段名、過程名、視圖名等所有命 名符的首字母需要使用大寫,也即每個命名單詞的首字母大寫,其它字符小寫。但對 于簡寫或縮寫的短單詞,如 ID 、UI 可以全為大寫。
  • 主鍵規(guī)范:
    ? ? ? ?除臨時表、流水表以及日志表外,其它表都要建立主鍵。主鍵最好設(shè)計成單一主 鍵,盡量不要用復(fù)合主鍵,盡量使用沒有業(yè)務(wù)語義的字段作為主鍵,
    如采用按順序自增的數(shù)值型字段為主鍵
  • 注釋規(guī)范:
    ? ? ? ?每個表,每個字段都要有注釋,說明其含義,對于冗余字段還要特別說明其維護方法,外鍵字段要說明參照于那個表,另外對于存儲過程、視圖、觸發(fā)器、函數(shù)等代碼均要增加注釋,以保持代碼的可讀性以及后續(xù)的可維護性。
  • 行大小規(guī)范:
    ? ? ? ?SQL Server 的 1 頁的大小是 8K,因此一行的數(shù)據(jù)要控制到 8K 之內(nèi),如果超過 8K 要想辦法將表進(jìn)行拆分成多個子表。
  • 數(shù)據(jù)保留策略:
    ? ? ? ?大表由于數(shù)據(jù)量較大,往往是系統(tǒng)的性能瓶頸所在,因此對于大表的設(shè)計好考慮到今后的數(shù)據(jù)轉(zhuǎn)移、分片、Partition 等,并且對大表以及其相關(guān)表的數(shù)據(jù)保留時間也要有一個提前規(guī)劃,以免今后出現(xiàn)性能問題束手無策。
  • 必備字段要求:
    ? ? ? ?每個大表都應(yīng)該添加以下幾個有用的字段,分別為創(chuàng)建日期、修改日期、操作人以及版本標(biāo)記,創(chuàng)建這些字段的目的是為今后的數(shù)據(jù)轉(zhuǎn)移以及分片或分區(qū)做準(zhǔn)備,同時也有利于今后的數(shù)據(jù)審計等。
    注意事項:
    ? ? ? ?基于大表的任何操作都要慎重思考,通常情況下要禁止在大表上創(chuàng)建觸發(fā)器,禁止在大表上做頻繁的批量更新或刪除動作,禁止在生產(chǎn)時間對大表做 DDL 操作,禁止在大表上做全表掃描(Full Scan)等。
  • 臨時表功能:
    ? ? ? ?SQL Server 分為全局臨時表和局部臨時表,臨時表在很多場合下能帶來意想不到 的效果,尤其是需要中轉(zhuǎn)的數(shù)據(jù)記錄集采用臨時表能提升系統(tǒng)性能。臨時表支持索引、 約束、排序等實體表具有的功能。
  • 存儲特點:
    ? ? ? ?臨時表的數(shù)據(jù)存儲在 tempdb 數(shù)據(jù)庫中,因此過于頻繁的創(chuàng)建臨時表會增加 tempdb 庫的負(fù)荷,尤其是數(shù)據(jù)量超過 10W 條記錄的臨時表更是會影響 tempdb 庫的 性能,由此在某些情況下可用CTE 替代臨時表的使用。
    注意事項:
    ? ? ? ?臨時表執(zhí)行完畢后,要及時的手工 Drop 掉,及時釋放資源,減輕系統(tǒng)的 Loading , 另外特別注意的是要盡量禁止使用全局臨時表,全局適合多個 session 間的數(shù)據(jù)交互, 但往往會引起數(shù)據(jù)的串值。
  • 命名規(guī)范:
    ? ? ? ?盡量采用有意義的字段名,使描述盡可能清楚,如采用縮寫,盡量使用通用的縮 寫語言,如 addr 代表 address,避免出現(xiàn)只有自己理解的縮寫。
  • 日期字段:
    ? ? ? ?時效性數(shù)據(jù)應(yīng)包括“創(chuàng)建時間/修改時間”字段,時間標(biāo)記對查找數(shù)據(jù)、清理數(shù)據(jù)、 排序合并特別有用,另外要根據(jù)具體業(yè)務(wù)考量時間字段的類型,如在 Smalldatetime和 Datetime 類型進(jìn)行選擇。
  • 注意保留詞:
    ? ? ? ?對于字段的命名,要確保字段名沒有和保留詞、數(shù)據(jù)庫系統(tǒng)或者常用方法沖突, 比如 master 、CROSS 、address 、substring 、len 、sysobjects 等詞就不適合用來做字段 的獨立命名。
  • 數(shù)值規(guī)范:
    ? ? ? ?數(shù)值型的主要有 INT 、BIGINT 、TINYINT 、SMALLINT 、FLOAT 、NUMERIC 、 MONEY 等類型,要根據(jù)實際應(yīng)用選擇合適的類型,如字段的數(shù)據(jù)為小于 255 的整形 數(shù)字,那么就要選擇 TINYINT;如字段數(shù)據(jù)小于 32767 的整形數(shù)字,那么就要選擇SMALLINT,以此類推。
  • 文本規(guī)范:
    ? ? ? ?文本類型主要有 CHAR 、VARCHAR 、TEXT 等類型,要根據(jù)實際應(yīng)用選擇合適 的類型,如字段文本長度固定為 8 位,那么就要用CHAR(8);如文本長度最大為 100 , 并且大小是非定長的,那么就要設(shè)為 VARCHAR(100)。并且以上文本若為漢字,那 么就要設(shè)為 NVARCHAR 和 NCHAR 。
  • 字段命名技巧:
    ? ? ? ?字段命名要統(tǒng)一規(guī)范,同一個字段在不同的表中命名要一致,另外字段名一般都 要帶上業(yè)務(wù)模塊的前綴,如訂單(Order)價格字段命名為 Or_Price,部門(Department)編 號為 Dep_No。命名規(guī)范沒有那個是最合理的,只有定義好最適合自己的統(tǒng)一規(guī)范即 可。
    ? ? ? ?外鍵建立索引:
    外鍵不建立索引,將有可能導(dǎo)致兩個嚴(yán)重的問題。1.更新相關(guān)的表產(chǎn)生死鎖。2. 兩表關(guān)聯(lián)查詢時性能低下。因此通常情況下都必須要求外鍵建立索引。
  • 聯(lián)合索引規(guī)范:
    ? ? ? ?當(dāng)數(shù)據(jù)對某表經(jīng)常要多條件查詢時,可能就需要建立聯(lián)合索引,聯(lián)合索引的第一 個引導(dǎo)列字段非常重要,引導(dǎo)列字段通常要能過濾掉大部分?jǐn)?shù)據(jù),這樣方能減少 IO 的讀寫,提高性能。非引導(dǎo)列字段在引導(dǎo)列的查詢數(shù)據(jù)基礎(chǔ)上繼續(xù)過濾數(shù)據(jù),以提高 查詢速度。聯(lián)合索引對更新會產(chǎn)生一定的性能影響。
    禁用多余索引:
    ? ? ? ?數(shù)據(jù)庫索引能提高查詢速度,但會增加寫操作的開銷,因此對一些幾月或者從沒 有使用過的索引要刪除掉,以免增大數(shù)據(jù)庫的負(fù)荷。
    重復(fù)索引問題:
    ? ? ? ?一般情況下,盡量避免重復(fù)索引的出現(xiàn),重復(fù)索引很容易引起死鎖,減低數(shù)據(jù)庫
    的并發(fā)訪問。重復(fù)索引也會造成索引的維護困難。
    索引數(shù)量限制:
    ? ? ? ?數(shù)據(jù)庫索引主要用來解決讀的性能瓶頸,但是會增加寫操作的負(fù)荷,因此過多的 索引會造成更新速度變慢,甚至?xí)鸩灰乃梨i。一般情況下表中的索引不要超過5 個。
    注意事項:
    ? ? ? ?建立索引前,要充分了解表的使用及數(shù)據(jù)特性,要了解表的查詢條件和查詢頻率, 甚至隨著業(yè)務(wù)的變化而引起表數(shù)據(jù)使用狀況的變化,帶之而來的是索引也需要相應(yīng)調(diào)
    整。
  • 命名規(guī)范:
    ? ? ? ?存儲過程命名遵守統(tǒng)一的規(guī)范,對于業(yè)務(wù)存儲過程要以 p 或 proc開頭,接著加上” _ ”,然后再加上模塊名稱簡寫和具體的業(yè)務(wù)詞,最后加上執(zhí)行類型。
    數(shù)據(jù)庫的存儲過程名嚴(yán)禁以 sp 開頭,sp 通常表示系統(tǒng)數(shù)據(jù)庫存儲過程名的前綴。觸 發(fā)器以 Tr 開頭,接著加上”_ ”,然后加上表名。
  • 書寫規(guī)范:
    ? ? ? ?關(guān)鍵字建議用大寫,同樣的代碼書寫格式保持一致,SQL 腳本采用縮進(jìn)風(fēng)格,風(fēng) 格一致,縮進(jìn)格式一致,使用空格。
    INSERT 規(guī)范:
    ? ? ? ?通常情況下,INSERT 語句要給出具體的字段列表,避免采用“INSERT INTO TB_1 VALUES( ‘值 1’, ’值 2’, ’值 3’)”用法,此種用法往往會由于表結(jié)構(gòu)變遷 而導(dǎo)致語句不可執(zhí)行
    避免隱式轉(zhuǎn)換:
    ? ? ? ?書寫時,必須明確表結(jié)構(gòu)及表中各個字段的數(shù)據(jù)類型,特別是查詢條件中的字段,要避免由于類型的不同導(dǎo)致數(shù)據(jù)類型轉(zhuǎn)換的發(fā)生,從而減少因為
    數(shù)據(jù)類型轉(zhuǎn)換產(chǎn)生的系統(tǒng)開銷。
  • NULL 陷阱:
    ? ? ? ?NULL 不要直接用來進(jìn)行運算符的比較,也不要和其它值進(jìn)行連接操作,判斷一 個值是否為 NULL 值時,要采用IS NULL 來進(jìn)行比較。
  • LIKE 規(guī)范:
    ? ? ? ?LIKE 子句應(yīng)盡量前段匹配,要避免通配符在前段,以免導(dǎo)致全索引掃描的發(fā)生。
  • 參數(shù)化代碼:
    ? ? ? ?SQL 中常量的直接使用,會導(dǎo)致 SQL 語句頻繁的硬解析,進(jìn)而嚴(yán)重影響數(shù)據(jù)庫 的性能,基于這些原因,代碼中要盡量采用參數(shù)綁定,以減少語句硬解析的次數(shù),從 而提高語句執(zhí)行性能。
  • 動態(tài) SQL:
    ? ? ? ?動態(tài) SQL 是在運行時才進(jìn)行解析的,相當(dāng)于是硬解析,因此會損失一些系統(tǒng)性 能,但是動態(tài) SQL 寫法靈活,因此在某些情況下需要以性能換靈活,但對于用靜態(tài) 語句就能簡單實現(xiàn)的 SQL,就不要用動態(tài)SQL 語句。
  • 嵌套層級限制:
    ? ? ? ?嵌套查詢盡量少使用,尤其是對于超過 3 層的嵌套查詢更要慎用,對于復(fù)雜的嵌 套語句要根據(jù)業(yè)務(wù)進(jìn)行拆分為多條 SQL 來實現(xiàn),或者通過臨時表來取代一部分嵌套 層級。
  • 排序規(guī)范:
    ? ? ? ?SQL 語句中要盡量減少排序,對查詢結(jié)果進(jìn)行的排序會大大降低系統(tǒng)的性能,并 且會增加 tempdb 數(shù)據(jù)庫的負(fù)荷,因此在開發(fā)時間寬松情況下,要盡量將排序動作放 到應(yīng)用程序?qū)尤ネ瓿伞?/li>
  • 代碼注釋要求:
    ? ? ? ?注釋是指程序中會被編譯器忽略掉的部分,目的是描述代碼的用途及更新時間, 合理的添加注釋可以使得程序結(jié)構(gòu)清晰,可以使代碼更好理解,便于系統(tǒng)后續(xù)的維護。 一般情況下,注釋要不少于代碼的十分之一。
  • 靜態(tài) SQL:
    ? ? ? ?SQL 語句要盡可能采用靜態(tài) SQL,靜態(tài) SQL 第一次執(zhí)行時會將編譯器解析的結(jié) 果存儲在緩存中,下次執(zhí)行該靜態(tài) SQL 時會直接從緩存中獲取其執(zhí)行計劃,相當(dāng)于 是軟解析,因此采用靜態(tài) SQL 可以減少語句的解析時間,提升了數(shù)據(jù)庫的性能。
  • 最小事務(wù)原則:
    ? ? ? ?數(shù)據(jù)庫事務(wù)用來保持?jǐn)?shù)據(jù)的一致性,但是對于一個執(zhí)行時間較長的大事務(wù),會造 成數(shù)據(jù)庫鎖的增加,當(dāng)鎖越積越多的時候就會從行鎖升級到頁鎖,從業(yè)鎖升級到表鎖, 從而嚴(yán)重影響數(shù)據(jù)庫的性能。因此,在能滿足數(shù)據(jù)一致性的前提下,要盡量將非一致
    性要求的語句代碼從事務(wù)中移除,以便提升數(shù)據(jù)庫的并發(fā)訪問。
  • 順序提交:
    ? ? ? ?順序提交是一個好的代碼編寫習(xí)慣,順序提交可以減少死鎖的發(fā)生,并且還能增 加代碼的可讀性及可維護性。

2、實訓(xùn)二:數(shù)據(jù)庫分析設(shè)計與建模

(1) 分析銀行 ATM 存取款系統(tǒng)實體

(2) 規(guī)范數(shù)據(jù)庫結(jié)構(gòu)設(shè)計

  • 第一范式(1NF)是指數(shù)據(jù)庫表的每一列都是不可分割的基本數(shù)據(jù)項,同一列中 不能有多個值,即實體中的某個屬性不能有多個值或者不能有重復(fù)的屬性。
    ? ? ? ?如在銀行客戶表 BankCustomer 中,不能將客戶信息都放在一列中顯示,也不能 將其中的兩列或多列在一列中顯示;客戶信息表的每一行只表示一個員工的信息,一個客戶的信息在表中只出現(xiàn)一次。簡而言之,第一范式就是無重復(fù)的列。
  • 第二范式(2NF)要求實體的屬性完全依賴于主關(guān)鍵字。
    ? ? ? ?如銀行交易信息表 BankDealInfo 中,不能把卡號設(shè)為主鍵因為一個卡號可以發(fā)生 多條交易記錄。要確定唯一的一條信息,必須重新定義一個和其它屬性無關(guān)的交易編 號。這樣要查詢一條交易信息。就可以用交易編號。簡而言之,第二范式就是屬性完全依賴于主鍵。
  • 第三范式(3NF)要求一個數(shù)據(jù)庫表中不包含已在其它表中已包含的非主關(guān)鍵字 信息。
    ? ? ? ? 如銀行卡表 BankCard 中,有了用戶Id 后。不能還添加用戶姓名等相關(guān)的用戶信 息。否則就會有大量的數(shù)據(jù)冗余。簡而言之,第三范式就是屬性不依賴于其它非主屬性。

(3) 繪制 CDM 模型、生成 PDM 模型


3、實訓(xùn)三:創(chuàng)建數(shù)據(jù)庫

(1) 創(chuàng)建數(shù)據(jù)庫

? ? ? ?使用 Create DataBase 語句創(chuàng)建“ATM 存取款機系統(tǒng)”數(shù)據(jù)庫BankDB,數(shù)據(jù)文件和日志文件保存在指定目錄下文件增長率為 15% 。

--創(chuàng)建BankDB數(shù)據(jù)庫,數(shù)據(jù)庫文件和日志文件均保存在文件夾D:\data下 --文件增長率均為%,數(shù)據(jù)文件起始大小為MB,日志文件起始大小為MB create database BankDB on primary ( name=N'BankDB', filename=N'C:\data\BankDB.mdf', size=5mb, filegrowth=15% ) log on ( name=N'BankDB_log', filename=N'C:\data\BankDB_log.ldf', size=2mb, filegrowth=15% )

(2) 創(chuàng)建各個數(shù)據(jù)表及相關(guān)的約束

? ? ? ?根據(jù)銀行業(yè)務(wù),分析表中每個列相應(yīng)的約束要求,為每個表添加各種約束。要求創(chuàng)建表時要求檢測是否存在表結(jié)構(gòu),如果存在,則先刪除再創(chuàng)建。

use BankDB go--判斷銀行客戶信息表是否存在,若存在則刪除 --sysobjects 系統(tǒng)對象表。保存當(dāng)前數(shù)據(jù)庫的對象。 --OBJECT_ID()根據(jù)對象名稱返回該對象的id IF EXISTS(SELECT * FROM sysobjects WHERE id=OBJECT_ID(N'BankCustomerInfo')) DROP TABLE BankCustomerInfo--創(chuàng)建BankCustomerInfo表 create table BankCustomerInfo( CustNum int identity(1,1) primary key not null, --客戶編號 CustName char(20) not null, --客戶姓名 CustID char(18) not null, --身份證號 CustTelephone char(20) not null, --客戶電話 CustAddress varchar(100) not null --客戶住址 )--判斷銀行卡表是否存在,若存在則刪除 IF EXISTS(SELECT * FROM sysobjects WHERE id=OBJECT_ID(N'BankCardInfo')) DROP TABLE BankCardInfo--創(chuàng)建BankCardInfo表 create table BankCardInfo( CardID char(19) primary key not null, --銀行卡號 Password char(6) not null, --密碼 MoneyType char(5) not null, --貨幣類型 DepositType int not null, --存款類型 OpenDate date not null, --開戶日期 OpenMoney money not null, --開戶金額 CardLoss char(10) not null, --是否掛失 CustNum int not null, --客戶編號 CardMoney numeric(8,2) not null --卡內(nèi)余額 )--判斷銀行交易信息表是否存在,若存在則刪除 IF EXISTS(SELECT * FROM sysobjects WHERE id=OBJECT_ID(N'BankDealInfo')) DROP TABLE BankDealInfo--創(chuàng)建BankDealInfo表 create table BankDealInfo( DealNum int identity(1,1) primary key not null, --交易編號 CardID char(19) not null, --銀行卡號 DealDate date not null, --交易日期 DealMoney decimal(8,2) not null, --交易金額 DealType char(256) not null, --交易類型 DealNote varchar(1024) null --交易備注 )--判斷業(yè)務(wù)類型表是否存在,若存在則刪除 IF EXISTS(SELECT * FROM sysobjects WHERE id=OBJECT_ID(N'BankBusinessType')) DROP TABLE BankBusinessType--創(chuàng)建BankBusinessType表 create table BankBusinessType( BusNum int identity(1,1) primary key not null, --業(yè)務(wù)編號 BusName char(20) not null, --業(yè)務(wù)名稱 BusDescribe varchar(100) null --業(yè)務(wù)描述 )--為BankCustomerInfo表添加約束 --添加check約束,身份證號前位必須是數(shù)字,后位可以是數(shù)字或者X alter table BankCustomerInfo add constraint ck_CustID check(left(CustID ,17) like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' and (right(CustID ,1) like'[0-9]' or right(CustID,1) like 'X')) --客戶電話必須是固定電話號碼或者手機號 alter table BankCustomerInfo add constraint ck_CustTelephone check( CustTelephone like'[0-9][0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9]' or CustTelephone like '[0-9][0-9][0-9]_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' or CustTelephone like '1[358][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]') --銀行卡號前位必須為,后位為-9任意數(shù)字--為BankCardInfo表添加約束 alter table BankCardInfo add constraint ck_CardID check(CardID LIKE '1010 3576 [0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9]') --密碼默認(rèn)為 alter table BankCardInfo add constraint df_Password default('888888') for Password --貨幣類型默認(rèn)為RMB alter table BankCardInfo add constraint df_MoneyType default('RMB') for MoneyType --開戶日期默認(rèn)為當(dāng)前時間 alter table BankCardInfo add constraint df_OpenDate default(getdate()) for OpenDate --開戶金額至少為元 alter table BankCardInfo add constraint ck_OpenMoney check(OpenMoney>=1) --是否掛失默認(rèn)為’否‘ alter table BankCardInfo add constraint df_CardLoss default('否') for CardLoss

(3) 添加外鍵約束和生成數(shù)據(jù)庫關(guān)系圖

添加子表外鍵約束

--添加外鍵約束 alter table BankCardInfo add constraint fk_DepositType foreign key(DepositType) references BankBusinessType(BusNum) alter table BankCardInfo add constraint fk_CustNum foreign key(CustNum) references BankCustomerInfo(CustNum) alter table BankDealInfo add constraint fk_CardID foreign key(CardID) references BankCardInfo(CardID)

在 SQL SERVER 里自動生成數(shù)據(jù)庫關(guān)系圖,如下圖所示:

4、實訓(xùn)四:創(chuàng)建觸發(fā)器和插入測試數(shù)據(jù)

(1) 創(chuàng)建級聯(lián)觸發(fā)器

創(chuàng)建 Insert 觸發(fā)器:
? ? ? ? 在交易信息表創(chuàng)建一個 insert 觸發(fā)器,當(dāng)增加一條交易信息時,修改相應(yīng)銀行卡
的存款余額。

--在交易信息表插入觸發(fā)器.使用游標(biāo)當(dāng)新增一個交易信息.修改銀行卡的存款余額 --檢查觸發(fā)器是否存在.存在則刪除 if(object_id('tr_insertDealInfo','tr') is not null) drop trigger tr_insertDealInfo go --創(chuàng)建insert 觸發(fā)器 create trigger tr_insertDealInfo on BankDealInfo for insert as declare @type char(10),@sum money,@BDCardID char(19) --定義游標(biāo),指向inserted 表 declare cursor_BankDealInfo cursor for select DealType,DealMoney,CardID from inserted --打開游標(biāo)、 open cursor_BankDealInfo --讀取游標(biāo).賦值給相應(yīng)字段 fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID --@@fetch_status=0 fetch 語句成功 while @@fetch_status=0 begin --根據(jù)交易類型.更新銀行卡余額.rtrim 和lraim 是去除首尾空格 if(rtrim(ltrim(@type))='存入') update BankCardInfo set CardMoney=CardMoney+@sum where CardID=@BDCardID if(rtrim(ltrim(@type))='支取') update BankCardInfo set CardMoney=CardMoney-@sum where CardID=@BDCardID fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID end --關(guān)閉游標(biāo) close cursor_BankDealInfo --釋放游標(biāo) deallocate cursor_BankDealInfo go

創(chuàng)建Delete觸發(fā)器:
? ? ? ? 在交易信息表創(chuàng)建一個 Delete 觸發(fā)器,當(dāng)刪除一條交易信息時,修改相應(yīng)銀行卡
的存款余額。

--觸發(fā)器存在則刪除 if(object_id('tr_delDealInfo','tr') is not null) drop trigger tr_delDealInfo go --創(chuàng)建delete 觸發(fā)器 create trigger tr_delDealInfo on BankDealInfo for delete as declare @type char(10),@sum money,@BDCardID char(19) --定義游標(biāo),指向deleted 表 declare cursor_BankDealInfo cursor for select DealType,DealMoney,CardID from deleted --打開游標(biāo) open cursor_BankDealInfo --讀取游標(biāo),賦值 fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID while @@fetch_status=0 begin if(rtrim(ltrim(@type))='存入') update BankCardInfo set CardMoney=CardMoney-@sum where CardID=@BDCardID if(rtrim(ltrim(@type))='支取') update BankCardInfo set CardMoney=CardMoney+@sum where CardID=@BDCardID fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID end close cursor_BankDealInfo deallocate cursor_BankDealInfo go

創(chuàng)建 Update 觸發(fā)器
? ? ? ? 在交易信息表創(chuàng)建一個 Update 觸發(fā)器,當(dāng)更新一條交易信息時,修改相應(yīng)銀行 卡的存款余額。

--觸發(fā)器存在則刪除 if(object_id('tr_updateDealInfo','tr') is not null) drop trigger tr_updateDealInfo go create trigger tr_updateDealInfo on BankDealInfo for update as declare @type char(10),@sum money,@BDCardID char(19) --定義游標(biāo),指向deleted 表 declare cursor_BankDealInfo cursor for select DealType,DealMoney,CardID from deleted --打開游標(biāo) open cursor_BankDealInfo --讀取游標(biāo),賦值 fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID while @@fetch_status=0 begin if(rtrim(ltrim(@type))='存入') update BankCardInfo set CardMoney=CardMoney-@sum where CardID=@BDCardID if(rtrim(ltrim(@type))='支取') update BankCardInfo set CardMoney=CardMoney+@sum where CardID=@BDCardID fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID end close cursor_BankDealInfo deallocate cursor_BankDealInfo --定義游標(biāo),指向inserted 表 declare cursor_BankDealInfo cursor for select DealType,DealMoney,CardID from inserted --打開游標(biāo) open cursor_BankDealInfo --讀取游標(biāo).賦值給相應(yīng)字段 fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID --@@fetch_status=0 fetch 語句成功 while @@fetch_status=0 begin --根據(jù)交易類型.更新銀行卡余額.rtrim 和lraim 是去除首尾空格 if(rtrim(ltrim(@type))='存入') update BankCardInfo set CardMoney=CardMoney+@sum where CardID=@BDCardID if(rtrim(ltrim(@type))='支取') update BankCardInfo set CardMoney=CardMoney-@sum where CardID=@BDCardID fetch next from cursor_BankDealInfo into @type,@sum,@BDCardID end --關(guān)閉游標(biāo) close cursor_BankDealInfo --釋放游標(biāo) deallocate cursor_BankDealInfo

(2) 插入數(shù)據(jù)表的測試數(shù)據(jù)

? ? ? ? 使用 T-SQL 語句向每個表插入如下所示測試數(shù)據(jù),要保證業(yè)務(wù)數(shù)據(jù)的一致性和 完整性。
BankBusinessType 表的測試數(shù)據(jù):

insert into BankBusinessType (BusName,BusDescribe) values ('活期','無固定存期,可隨時存取,存取金額不限的一種比較靈活的存款'), ('定活兩便','事先不約定存定期,一次性存入,一次性支取的存款'), ('通知','不約定存期,支取是需提前通知銀行,約定支取日期和金額方能支取的存款'), ('整存整取年','整筆存入,到期提取本息'), ('整存整取年','整筆存入,到期提取本息'), ('整存整取年','整筆存入,到期提取本息'), ('零存整取年','事先原定金額,逐月按約定金額存入,到期支付本息'), ('零存整取年','事先原定金額,逐月按約定金額存入,到期支付本息'), ('零存整取年','事先原定金額,逐月按約定金額存入,到期支付本息'), ('自助轉(zhuǎn)賬','銀行atm 存取款機上辦理銀行卡之間互相劃轉(zhuǎn)') go select * from BankBusinessType


BankCustomerInfo 表的測試數(shù)據(jù):

insert into BankCustomerInfo(CustName,CustID,CustTelephone,CustAddress) values ('葉春萌','152825198512548541','13585941287','麗都新城'), ('周明','152821198401248574','0147-7418527','松石名第') go select * from BankCustomerInfo

BankCardInfo表的測試數(shù)據(jù):

insert into BankCardInfo (CardID,Password,MoneyType,DepositType,OpenDate,OpenMoney,CardLoss,CustNum,CardMoney) values ('1010 3576 1234 5678','197611','RMB',1,cast(dateadd(day,-(rand()*30),getdate()) as date),1000,'否',1,1000), ('1010 3576 1234 5688','197611','RMB',2,cast(dateadd(day,-(rand()*30),getdate()) as date),1000,'否',2,1500) go select * from BankCardInfo


BankDealInfo 表的測試數(shù)據(jù):

insert into BankDealInfo (CardID,DealDate,DealMoney,DealType,DealNote) values ('1010 3576 1234 5678',cast(dateadd(day,-(rand()*15),getdate()) as date),500,'存入','單位月工資'), ('1010 3576 1234 5678',cast(dateadd(day,-(rand()*15),getdate()) as date),1500,'存入','單位月工資'), ('1010 3576 1234 5678',cast(dateadd(day,-(rand()*15),getdate()) as date),300,'存入','支付寶付款'), ('1010 3576 1234 5678',cast(dateadd(day,-(rand()*15),getdate()) as date),400,'支取','刷卡消費'), ('1010 3576 1234 5688',cast(dateadd(day,-(rand()*15),getdate()) as date),3500,'存入','單位月工資'), ('1010 3576 1234 5688',cast(dateadd(day,-(rand()*15),getdate()) as date),4500,'存入','單位月工資'), ('1010 3576 1234 5688',cast(dateadd(day,-(rand()*15),getdate()) as date),800,'存入','支付寶付款'), ('1010 3576 1234 5688',cast(dateadd(day,-(rand()*15),getdate()) as date),900,'支取','刷卡消費') go select * from BankDealInfo

5、實訓(xùn)五:模擬常規(guī)業(yè)務(wù)

(1) 修改客戶密碼

? ? ? ?根據(jù)卡號修改指定 2 個客戶的銀行密碼,其中第一個客戶 1010 3576 1234 5678 密碼修改為 123456,第二個客戶 1010 3576 1234 5688 修改為 123123。

update BankCardInfo set Password='123465' where CardID='1010 3576 1234 5678' update BankCardInfo set Password='123123' where CardID='1010 3576 1234 5688' select CardID '銀行卡卡號',Password '密碼',MoneyType '貨幣類型',DepositType '儲蓄種類',OpenDate ' 開戶日期',OpenMoney '開戶金額', CardLoss '是否掛失',CustNum'客戶編號',CardMoney '存款金額' from BankCardInfo

(2) 辦理銀行卡掛失

? ? ? ?卡號為 1010 3576 1234 5678 的銀行卡丟失,申請掛失。

update BankCardInfo set CardLoss='是' where CardID='1010 3576 1234 5678' select CardID '銀行卡卡號',Password'密碼',MoneyType '貨幣類型',BusName '儲蓄類型',OpenDate ' 開戶日期',OpenMoney '開戶金額', CardLoss '是否掛失',CustName'客戶姓名',CardMoney '存款 金額' from BankCardInfo inner join BankCustomerInfo on BankCardInfo.CustNum=BankCustomerInfo.CustNum inner join BankBusinessType on BankCardInfo.DepositType=BankBusinessType.BusNum

(3) 統(tǒng)計銀行資金流通余額和盈利結(jié)算

存入代表資金流入,支取代表資金流出。
計算公式:資金流通余額=總存入金額-總支取金額
假定存款利率為千分之三,貸款利率為千分之八。
計算公式:盈利結(jié)算=總支取金額0.008-總存入金額0.003 。
要求創(chuàng)建一個存儲過程 proc_staticsBanlanceAndProfit 。

if exists(select * from sys.sysobjects where name='proc_staticsBanlanceAndProfit') drop procedure proc_staticsBanlanceAndProfit go create procedure proc_staticsBanlanceAndProfit as declare @inmoney money declare @outmoney money select @inmoney=sum(DealMoney) from BankDealInfo where DealType='存入' select @outmoney=sum(DealMoney) from BankDealInfo where DealType='支取' print '存入總金額:'+ltrim(str(@inmoney))+'rmb,支取總金 額:'+ltrim(str(@outmoney))+'rmb,銀行流通余額:'+ltrim(str(@inmoney-@outmoney))+'rmb, 盈利余額:'+ ltrim(str(@outmoney*0.008-@inmoney*0.003))+'rmb' go exec proc_staticsBanlanceAndProfit

(4) 查詢本周開戶信息

查詢本周開戶的卡號,顯示該卡的相關(guān)信息。

--默認(rèn)星期日作為一周的第一天.修改星期一為第一天 set datefirst 1 select CardID '銀行卡卡號',CustName '姓名', MoneyType '貨幣類型',OpenDate '開戶時間 ',BusName '儲蓄類型',OpenMoney '開戶金額',CardMoney '存款金額', case CardLoss when '是' then '掛失賬戶' when '否' then '正常賬戶' end '是否掛失' from BankCardInfo inner join BankBusinessType on BankBusinessType.BusNum = BankCardInfo.DepositType inner join BankCustomerInfo on BankCustomerInfo.CustNum = BankCardInfo.CustNum where datediff(day,OpenDate,getdate())<datepart(weekday,getdate())

(5) 查詢本月單次交易金額最高的卡號和總交易金額最高的卡號

查詢本月存、取款中單次交易金額最高的卡號信息。

select distinct BankDealInfo.CardID '銀行卡卡號',OpenDate '開戶日期',OpenMoney '開戶金額 ',DealMoney '單次最高金額' from BankCardInfo inner join BankDealInfo on BankDealInfo.CardID=BankCardInfo.CardID where DealMoney =(select max(DealMoney ) from BankDealInfo where datediff(month,DealDate,getdate())=0) select top 1 BankCardInfo.CardID '銀行卡卡號',OpenDate '開戶日期',OpenMoney '開戶金額 ',sum(DealMoney ) '總交易最高金額' from BankCardInfo inner join BankDealInfo on BankDealInfo.CardID=BankCardInfo.CardID where datediff(month,DealDate,getdate())=0 group by BankCardInfo.CardID,OpenDate,OpenMoney order by sum(DealMoney ) desc

(6) 查詢掛失客戶

--子查詢 select CustName '客戶姓名',CustTelephone '聯(lián)系電話' from BankCustomerInfo where CustNum in (select CustNum from BankCardInfo where CardLoss='是') --內(nèi)連接 select CustName '客戶姓名',CustTelephone '聯(lián)系電話' from BankCustomerInfo inner join BankCardInfo on BankCardInfo.CustNum = BankCustomerInfo.CustNum where CardLoss='是'

(7) 催款提醒業(yè)務(wù)

? ? ? ?根據(jù)某種業(yè)務(wù)(如代繳電話費、代繳手機費或房貸等)的需要,每個月末,查詢出客戶賬戶上余額少于 10000 元,由銀行統(tǒng)一致電催款。

select CustName '客戶姓名',CustTelephone '聯(lián)系電話',CardMoney '存款金額' from BankCardInfo inner join BankCustomerInfo on BankCustomerInfo.CustNum = BankCardInfo.CustNum where CardMoney<=10000

6、實訓(xùn)六:創(chuàng)建、使用視圖

(1) 輸出銀行客戶記錄視圖VW_userInfo

? ? ? ?顯示的列名全為中文,要求先判斷該視圖是否存在,若存在,則先刪除。

if object_id('vw_userinfo','v') is not null drop view vw_userinfo go create view vw_userinfo as select CustNum '客戶編號',CustName '開戶名',CustID '身份證號',CustTelephone '電話號碼',CustAddress '居住地址' from BankCustomerInfo go select * from vw_userinfo

(2) 輸出銀行卡記錄視圖VW_CardInfo

if object_id('VW_CardInfo','v') is not null drop view VW_CardInfo go create view VW_CardInfo as select CardID '銀行卡卡號',CustName '姓名', MoneyType '貨幣類型',BusName '儲蓄類型 ',OpenDate '開戶日期',CardMoney '存款金額',Password'密碼', CardLoss '是否掛失' from BankCardInfo inner join BankCustomerInfo on BankCustomerInfo.CustNum = BankCardInfo.CustNum inner join BankBusinessType on BankBusinessType.BusNum = BankCardInfo.DepositType go select * from VW_CardInfo

(3) 輸出銀行卡交易記錄視圖VW_TransInfo

if object_id('VW_TransInfo','v') is not null drop view VW_TransInfo go create view VW_TransInfo as select DealDate '交易日期',DealType '交易類型',CardID '銀行卡卡號',DealMoney'交易 金額',DealNote '備注' from BankDealInfo go select * from VW_TransInfo order by 交易日期

(4) 根據(jù)客戶登錄名查詢該客戶賬戶信息VW_OneUserInfo

? ? ? ?根據(jù)客戶登錄名(采用實名制訪問銀行系統(tǒng))查詢該客戶賬戶信息的視圖,利用SQL SERVER 系統(tǒng)函數(shù) system_user 獲得數(shù)據(jù)庫用戶名。

if object_id('VW_OneUserInfo','v') is not null drop view VW_OneUserInfo go create view VW_OneUserInfo as select CustNum '客戶編號',CustName '開戶名',CustID '身份證號',CustTelephone '電話號碼',CustAddress '居住地址' from BankCustomerInfo where CustName=system_user go select * from VW_OneUserInfo

7、實訓(xùn)七:存儲過程實現(xiàn)業(yè)務(wù)處理

(1) 完成存款或取款業(yè)務(wù)

描述:
? ? ? ? 根據(jù)銀行卡號和交易金額實現(xiàn)銀行卡的存款和取款業(yè)務(wù)。
? ? ? ? 每一筆存款,取款業(yè)務(wù)都要計入銀行交易賬,并同時更新客戶的存款余額。
? ? ? ? 如果是取款業(yè)務(wù),在記賬之前,要完成下面兩項數(shù)據(jù)的檢查驗證工作,如果檢查 不合格,那么中斷取款業(yè)務(wù),給出提示信息后退出。
? ? ? ? 檢查客戶輸入的密碼是否正確。
? ? ? ? 賬戶取款金額是否大于當(dāng)前存款額加 1 。

--判斷存儲過程是否存在.存在則刪除 if object_id('proc_TakeMoney','p') is not null drop procedure proc_TakeMoney go --創(chuàng)建存取款業(yè)務(wù)的存儲過程 create procedure proc_TakeMoney @CardID char(19),@money money,@pwd char(6)=null as --不返回受影響的行數(shù) set nocount on declare @existbanlance money --啟動事務(wù) begin transaction select @existbanlance=CardMoney from BankCardInfo where CardID=@CardID print '交易前,卡號'+@CardID print '交易正進(jìn)行,請稍后...' --如果輸入?yún)?shù)@pwd 為空,則為取款業(yè)務(wù).否則為存款業(yè)務(wù) if (select CardLoss from BankCardInfo where CardID=@CardID)='是' begin print '本卡已掛失,不能交易!' rollback transaction return end if(@pwd is not null) begin --取款 if exists(select * from BankCardInfo where CardID=@CardID and Password=@pwd) begin if(@money<=@existbanlance-1) insert into BankDealInfo (CardID,DealDate,DealMoney,DealType,DealNote) values (@CardID,getdate(),@money,'支取','通過存儲過程操作') else print '取款交易失敗.余額不足,請減少取款' end else begin print '取款交易失敗,卡號或密碼有錯誤' rollback transaction return end end else begin --辦理存款業(yè)務(wù) if exists(select * from BankCardInfo where CardID=@CardID) insert into BankDealInfo (CardID,DealDate,DealMoney,DealType,DealNote) values (@CardID,getdate(),@money,'存入','通過存儲過程操作') else begin print '存款失敗,卡號不存在' rollback transaction return end end --判斷事務(wù)處理是否有異常.沒有提交.有則回滾 if(@@error<>0) begin print '交易失敗,發(fā)生未知錯誤' rollback transaction end else begin commit transaction print '交易成功,交易金額為:'+ltrim(str(@money)) select @existbanlance=CardMoney from BankCardInfo where CardID=@CardID print '卡號:'+@CardID+',余額為:'+ltrim(str(@existbanlance)) end --顯示銀行卡用戶詳情和交易詳情 select * from VW_CardInfo select * from VW_TransInfo order by 交易日期 go --執(zhí)行存款存儲過程 exec proc_TakeMoney @CardID='1010 3576 1234 5688',@money=2000 --執(zhí)行取款存儲過程 exec proc_TakeMoney @CardID='1010 3576 1234 5688',@money=1200,@pwd='123465'

(2) 產(chǎn)生隨機卡號

? ? ? ? 創(chuàng)建存儲過程產(chǎn)生 8 位隨機數(shù)字,與前 8 位固定數(shù)字“1010 3576”連接,生成一個由 16 位數(shù)字組成的銀行卡號,并輸出。

if object_id('proc_RandCardID','p') is not null drop procedure proc_RandCardID go --創(chuàng)建隨機卡號的存儲過程 create procedure proc_RandCardID @randcardid char(19) output as declare @r numeric(8,8),@tmpstr char(10) --產(chǎn)生隨機種子=當(dāng)前的月份數(shù)*100000+當(dāng)前的秒數(shù)*1000+當(dāng)前的毫秒數(shù) set @r=rand(datepart(month,getdate())*100000+datepart(second,getdate())*1000+datepart(millisecond,getdate())) set @tmpstr=convert(char(10),@r) set @randcardid='1010 3576 '+substring(@tmpstr,3,4)+' '+substring(@tmpstr,7,4) go declare @mycardid1 char(19) exec proc_RandCardID @mycardid1 output print '產(chǎn)生隨機卡號為'+@mycardid1

(3) 完成開戶業(yè)務(wù)

描述:
? ? ? ? 利用存儲過程為客戶開設(shè) 2 個銀行卡賬戶,開戶時需要提供客戶的信息有:開戶 名、身份證號、電話號碼、開戶金額、存款類型和地址。客戶的信息見表所示:
? ? ? ? 為成功開戶的客戶提供銀行卡,且銀行卡號唯一。

if object_id('proc_OpenAccount','p') is not null drop procedure proc_OpenAccount go --創(chuàng)建存取款業(yè)務(wù)的存儲過程 create procedure proc_OpenAccount @CustName char(20),@CustID char(18),@CustTelephone varchar(20),@OpenMoney money,@BusName varchar(20),@CustAddress varchar(100) as --不返回受影響的行數(shù) set nocount on declare @DepositType int,@CardID char(19),@CustNum int --判斷存款類型是否正確 if exists(select * from BankBusinessType where BusName=@BusName) begin begin tran select @DepositType=BusNum from BankBusinessType where BusName=@BusName exec proc_randcardid @CardID output --選出不重復(fù)的卡號 while(exists(select * from BankCardInfo where CardID=@CardID)) exec proc_RandCardID @CardID output --插入一條客戶信息記錄,身份證一樣不重復(fù)插入 if not exists(select * from BankCustomerInfo where CustID=@CustID ) begin insert BankCustomerInfo (CustName,CustID,CustTelephone,CustAddress) values (@CustName,@CustID,@CustTelephone,@CustAddress) set @CustNum=@@identity end else select @CustNum=CustNum from BankCustomerInfo where CustID=@CustID insert BankCardInfo (CardID,Password,MoneyType,DepositType,OpenDate,OpenMoney,CardLoss,CustNum,CardMoney) values (@CardID,'888888','rmb',@DepositType,getdate(),@OpenMoney,'否 ',@CustNum,@OpenMoney) if(@@error<>0) begin print '尊敬的客戶,開戶不成功,所有操作均撤銷' rollback tran end else begin commit tran print '尊敬的客戶,開戶成功,系統(tǒng)為你產(chǎn)生的隨機卡號是:'+@CardID+',開戶日 期:'+convert(char(10),getdate(),111)+',開戶金額:'+ltrim(str(@OpenMoney)) end --顯示開戶的客戶表信息和銀行卡信息 select * from vw_userinfo select * from VW_CardInfo end else print '尊敬的客戶,未能成功開戶,存款類型不正確,請重新輸入!' go exec proc_OpenAccount @CustName = '陳曦',@CustID = '152825198909120124',@CustTelephone = '13574129856',@OpenMoney = 1200,@BusName = '定活兩便',@CustAddress = '海天家園' exec proc_OpenAccount @CustName = '林念初',@CustID = '152825197905149652',@CustTelephone = '15852147869',@OpenMoney = 1000,@BusName = '活期',@CustAddress = '峻峰華庭'

(4) 分頁顯示查詢交易數(shù)據(jù)

? ? ? ? 根據(jù)指定的頁數(shù)和每頁的記錄數(shù)分頁顯示交易數(shù)據(jù)。

if object_id('proc_PagingDisplay','p') is not null drop procedure proc_PagingDisplay go create procedure proc_PagingDisplay @page int,@count int as select rownumber '交易編號',DealDate '交易日期',DealType '交易類型',CardID '銀行卡卡號 ',DealMoney'交易金額' from (select row_number() over(order by DealNum) rownumber,DealDate,DealType,CardID,DealMoney from BankDealInfo) c where c.rownumber between (@page-1)*@count+1 and @page*@count go exec proc_PagingDisplay @page = 2,@count = 5

(5) 統(tǒng)計未發(fā)生交易的賬戶

? ? ? ? 查詢統(tǒng)計指定時間段內(nèi)沒有發(fā)生交易的賬戶信息

if object_id('proc_getwithouttrade','p') is not null drop procedure proc_getwithouttrade go create procedure proc_getwithouttrade @startdate datetime=null,@enddate datetime=null as declare @name char(16),@icno char(18),@tel char(15),@addr char(50),@moneysum money=0,@customersum int=0,@money int if (@startdate is null) set @startdate=convert(datetime,convert(char(8),getdate(),120)+'1') if (@enddate is null) set @enddate=getdate() --有的客戶未交易.所以用右連接或者全連接 declare cur_outtrade cursor for select distinct CustName,CustID,CustTelephone,CustAddress,CardMoney from BankDealInfo right join BankCardInfo on BankCardInfo.CardID=BankDealInfo.CardID right join BankCustomerInfo on BankCustomerInfo.CustNum = BankCardInfo.CustNum where BankDealInfo.CardID not in(select BankDealInfo.CardID from BankDealInfo where DealDate>=@startdate and DealDate<=@enddate) print convert(char(16),'客戶姓名')+convert(char(20),'身份證號')+convert(char(16),'電 話')+convert(char(20),'地址') open cur_outtrade fetch next from cur_outtrade into @name,@icno,@tel,@addr,@money while @@fetch_status=0 begin print convert(char(16),@name)+convert(char(20),@icno)+convert(char(16),@tel)+convert(char(20),@addr) set @moneysum=@moneysum+@money set @customersum=@customersum+1 fetch next from cur_outtrade into @name,@icno,@tel,@addr,@money end print '統(tǒng)計未發(fā)生交易的客戶' print '客戶人數(shù):'+ltrim(str(@customersum))+',客戶總余額:'+ltrim(str(@moneysum)) close cur_outtrade deallocate cur_outtrade go exec proc_getwithouttrade @startdate='2015-8-19',@enddate='2015-9-19' exec proc_getwithouttrade

8、實訓(xùn)八:利用事務(wù)實現(xiàn)轉(zhuǎn)賬

? ? ? ? 使用存儲過程和事務(wù)實現(xiàn)轉(zhuǎn)賬業(yè)務(wù),操作步驟如下所示:
? ? ? ? (1)從某一個賬戶支取一定金額的存款。
? ? ? ? (2)將支取金額存入到另一個指定的賬戶中。
? ? ? ? (3)分別打印此筆業(yè)務(wù)的轉(zhuǎn)出賬單和轉(zhuǎn)入賬單

--判斷該存儲過程是否存在,若存在,則刪除 if object_id('usp_transfer','p') is not null drop procedure usp_transfer go --創(chuàng)建轉(zhuǎn)賬存儲過程,需要傳遞兩個賬戶號碼及轉(zhuǎn)賬金額 create procedure usp_transfer @outCardID char(19),@inCardID char(19),@dealacount money as --不返回受影響的行數(shù) set nocount on --聲明個變量分別存放轉(zhuǎn)出賬戶和轉(zhuǎn)入賬戶的轉(zhuǎn)賬之后的余額 declare @outexistbalance money,@inexistbalance money --聲明變量存放轉(zhuǎn)出賬戶的姓名、貨幣類型、存款類型和開戶日期 declare @outCustName char(20),@outMoneyType char(5),@outBusName char(20),@outOpenDate date --聲明變量存放轉(zhuǎn)入賬戶的姓名、貨幣類型、存款類型和開戶日期 declare @inCustName char(20),@inMoneyType char(5),@inBusName char(20),@inOpenDate date --聲明交易日.類型.交易金額.備注 declare @DealDate date,@DealType char(20),@DealMoney money,@DealNote char(100) print '開始轉(zhuǎn)賬,請稍后...' --判斷轉(zhuǎn)出賬戶及余額是否大于轉(zhuǎn)出金額+1 if exists(select * from BankCardInfo where CardID=@outCardID and CardMoney>=@dealacount+1) begin --判斷轉(zhuǎn)入賬戶是否存在 if not exists(select * from BankCardInfo where CardID=@inCardID) begin print '轉(zhuǎn)入賬戶不存在,轉(zhuǎn)賬交易失敗' return end --判斷轉(zhuǎn)出賬戶是否存在 if not exists(select * from BankCardInfo where CardID=@outCardID) begin print '轉(zhuǎn)出賬戶不存在,轉(zhuǎn)賬交易失敗' return end --啟動事務(wù)機制 begin tran print '交易正進(jìn)行,請稍后...' --首先增加一條轉(zhuǎn)出賬戶的支出交易記錄 insert into BankDealInfo (CardID,DealDate,DealMoney,DealType,DealNote) values (@outCardID,getdate(),@dealacount,'支取','轉(zhuǎn)出') -- 給交易日.類型.交易金額.備注賦值 select @DealDate=DealDate,@DealType=DealType,@DealMoney=DealMoney,@DealNote=DealNote from BankDealInfo where DealNum=@@identity --增加一條轉(zhuǎn)入賬戶的存取交易記錄 insert into BankDealInfo (CardID,DealDate,DealMoney,DealType,DealNote) values (@inCardID,getdate(),@dealacount,'存入','轉(zhuǎn)入') --取得轉(zhuǎn)賬后兩個賬戶的余額 select @outexistbalance=(select CardMoney from BankCardInfo where CardID=@outCardID) select @inexistbalance=(select CardMoney from BankCardInfo where CardID=@inCardID) --判斷事務(wù)處理里是否有異常,若沒有異常,則提交,若有異常,則回滾 if @@error<>0 begin print '轉(zhuǎn)賬交易失敗' rollback tran end else begin commit tran print '交易成功,交易金額:'+convert(varchar(10),@dealacount) print '卡號'+@outCardID+' 余額:'+ltrim(str(@outexistbalance)) print '卡號'+@inCardID+' 余額:'+ltrim(str(@inexistbalance)) print '轉(zhuǎn)賬成功!' end end --分別打印轉(zhuǎn)出賬戶對賬單和轉(zhuǎn)入賬戶對賬單 else begin print '轉(zhuǎn)出賬戶余額不足,此次轉(zhuǎn)賬交易失敗' return end print '打印轉(zhuǎn)出賬戶對賬單' --獲取轉(zhuǎn)出賬戶的相關(guān)信息 select @outCustName=CustName,@outMoneyType=MoneyType,@outBusName=BusName,@outOpenDate=OpenDate from BankCardInfo inner join BankCustomerInfo on BankCustomerInfo.CustNum = BankCardInfo.CustNum inner join BankBusinessType on BankBusinessType.BusNum = BankCardInfo.DepositType where CardID=@outCardID print '---------------------------------------------------' print '卡號:'+@outCardID print '姓名:'+@outCustName print '存款類型:'+@outMoneyType print '開戶日期:'+convert(char(14),@outOpenDate) print convert(char(15),'交易日')+convert(char(15),'類型')+convert(char(15),'交易金額 ')+convert(char(15),'備注') print '---------------------------------------------------' print convert(char(15),@DealDate)+convert(char(15),@DealType)+convert(char(15),ltrim(@DealMoney))+convert(char(15),@DealNote) print '打印轉(zhuǎn)入賬戶對賬單' --獲取轉(zhuǎn)入賬戶的相關(guān)信息 select @inCustName=CustName,@inMoneyType=MoneyType,@inBusName=BusName,@inOpenDate=OpenDate from BankCardInfo inner join BankCustomerInfo on BankCustomerInfo.CustNum = BankCardInfo.CustNum inner join BankBusinessType on BankBusinessType.BusNum = BankCardInfo.DepositType where CardID=@inCardID print '---------------------------------------------------' print '卡號:'+@inCardID print '姓名:'+@inCustName print '存款類型:'+@inMoneyType print '開戶日期:'+convert(char(14),@inOpenDate) -- 給交易日.類型.交易金額.備注賦值 select @DealDate=DealDate,@DealType=DealType,@DealMoney=DealMoney,@DealNote=DealNote from BankDealInfo where DealNum=@@identity print convert(char(15),'交易日')+convert(char(15),'類型')+convert(char(15),'交易金額 ')+convert(char(15),'備注') print '---------------------------------------------------' print convert(char(15),@DealDate)+convert(char(15),@DealType)+convert(char(15),ltrim(@DealMoney))+convert(char(15),@DealNote) Go exec usp_transfer @outCardID='1010 3576 1234 5678',@inCardID='1010 3576 1234 5688',@dealacount=50

總結(jié)

以上是生活随笔為你收集整理的课程设计:基于SQL Server的银行ATM 存取款机系统设计与实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧洲性猛交| 99久久精品一区 | 国产视频二区三区 | www五月天com | 第四色在线视频 | 久久av无码精品人妻出轨 | 午夜黄色av | 色无极亚洲影院 | 999免费 | 国产精品 欧美激情 | 大伊人久久 | 美国福利片 | 久成人| 91免费在线观看网站 | 国产一区二区视频在线播放 | 天天插天天操天天干 | 久久爱综合 | 中文字幕日韩久久 | 成人高清视频免费观看 | www.-级毛片线天内射视视 | 国产主播精品在线 | 欧美午夜精品久久久久久人妖 | 日韩精品在线一区二区 | 国产综合图片 | 精品视频一区二区在线观看 | 无套中出丰满人妻无码 | 欧美日韩三级在线观看 | 99在线播放视频 | 国产男男gay体育生白袜 | 欧美精选一区二区 | 亚洲国产97| 久久亚洲精品石原莉奈 | 久夜精品 | 毛茸茸日本熟妇高潮 | 永久免费不卡在线观看黄网站 | a级片中文字幕 | 超碰日日干| 日韩一区二区视频在线播放 | 欧美成人国产精品高潮 | 在线观看免费高清视频 | 亚洲色图50p | 久久久久久午夜 | 阿v天堂2017 欧美小视频在线观看 | 国产精品秘入口18禁麻豆免会员 | 成年人在线免费看 | 日本三级黄在线观看 | 成人乱码一区二区三区av | 北京富婆泄欲对白 | 精品人妻少妇嫩草av无码专区 | 少妇高潮一区二区三区99欧美 | 黄色无遮挡网站 | 亚洲第一色 | 欧美成人免费看 | 天天操天天舔天天干 | 成人av免费播放 | xxx视频在线观看 | 曰批免费视频播放免费 | 亚洲欧美日韩国产成人精品影院 | 成全影视在线观看第8季 | av在线伊人| 欧美日韩成人免费 | 视频一二区 | 亚洲视频自拍偷拍 | 一区二区在线免费观看 | 欧洲做受高潮免费看 | 亚洲乱码中文字幕 | a级片在线免费看 | av黄色天堂| 国产精品国产自产拍高清av | 国产免费成人 | 色老板精品凹凸在线视频观看 | 在线观看中文字幕码 | 一本大道伊人av久久综合 | 免费男女视频 | 久久久久久亚洲av无码专区 | 国产精品原创 | 国产制服丝袜在线 | 欧美精品二区三区四区免费看视频 | 国产99爱| 久一国产 | 丰满少妇影院 | 老头糟蹋新婚少妇系列小说 | 亚洲午夜久久 | 欧美亚洲中文精品字幕 | 国产精品一品二区三区的使用体验 | 免费亚洲一区二区 | 欧美一级黄色网 | 小视频在线观看 | 美女扒开下面让男人捅 | 欧美成人三级在线视频 | 性欧美13一14内谢 | 亚洲av少妇一区二区在线观看 | 伊人久久久久久久久久久久 | 尤物最新网址 | 久久密av | 国产成人精品视频在线观看 | 亚洲成人一二三 | 无码人妻丰满熟妇区毛片蜜桃精品 | 国产情侣呻吟对白高潮 |