diff --git "a/\345\257\274\345\207\272\346\212\245\350\241\250\357\274\214\345\214\205\346\213\254\344\277\241\346\201\257\347\232\204\347\273\237\350\256\241\346\237\245\350\257\242\357\274\210\345\246\202\351\223\266\350\241\214\345\215\241\344\272\244\346\230\223\351\242\235\345\222\214\346\234\210\346\234\253\346\261\207\346\200\273\347\255\211" "b/\345\257\274\345\207\272\346\212\245\350\241\250\357\274\214\345\214\205\346\213\254\344\277\241\346\201\257\347\232\204\347\273\237\350\256\241\346\237\245\350\257\242\357\274\210\345\246\202\351\223\266\350\241\214\345\215\241\344\272\244\346\230\223\351\242\235\345\222\214\346\234\210\346\234\253\346\261\207\346\200\273\347\255\211" new file mode 100644 index 0000000000000000000000000000000000000000..b9883903e0353f28e70bc5c702998c859272553e --- /dev/null +++ "b/\345\257\274\345\207\272\346\212\245\350\241\250\357\274\214\345\214\205\346\213\254\344\277\241\346\201\257\347\232\204\347\273\237\350\256\241\346\237\245\350\257\242\357\274\210\345\246\202\351\223\266\350\241\214\345\215\241\344\272\244\346\230\223\351\242\235\345\222\214\346\234\210\346\234\253\346\261\207\346\200\273\347\255\211" @@ -0,0 +1,342 @@ +-- 银行储蓄系统完整SQL脚本(最终修复版) + +-- ----------------------------------------------------- +-- 表结构定义 +-- ----------------------------------------------------- + +CREATE TABLE IF NOT EXISTS userInfo ( + customerID INT AUTO_INCREMENT PRIMARY KEY, + customerName VARCHAR(50) NOT NULL, + PID CHAR(18) UNIQUE, + telephone VARCHAR(20), + address VARCHAR(100) +); + +CREATE TABLE IF NOT EXISTS deposit ( + savingID SERIAL PRIMARY KEY, + savingName VARCHAR(20) NOT NULL, + descrip VARCHAR(50) +); + +CREATE TABLE IF NOT EXISTS cardInfo ( + cardID CHAR(19) PRIMARY KEY, + curID CHAR(3) DEFAULT 'RMB', + savingID INT NOT NULL, + openDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + openMoney DECIMAL(18,2) NOT NULL, + balance DECIMAL(18,2) NOT NULL, + pass CHAR(6) NOT NULL, + isReportLoss ENUM('是', '否') DEFAULT '否', + customerID INT NOT NULL, + FOREIGN KEY (savingID) REFERENCES deposit(savingID), + FOREIGN KEY (customerID) REFERENCES userInfo(customerID) +); + +CREATE TABLE IF NOT EXISTS tradeInfo ( + tradeDate TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + tradeType CHAR(6) NOT NULL, + cardID CHAR(19) NOT NULL, + tradeMoney DECIMAL(18,2) NOT NULL, + remark TEXT, + FOREIGN KEY (cardID) REFERENCES cardInfo(cardID) +); + +-- ----------------------------------------------------- +-- 触发器定义 +-- ----------------------------------------------------- + +DELIMITER // + +DROP TRIGGER IF EXISTS trg_after_deposit; +CREATE TRIGGER trg_after_deposit +AFTER UPDATE ON cardInfo +FOR EACH ROW +BEGIN + IF NEW.balance > OLD.balance THEN + INSERT INTO tradeInfo(tradeDate, tradeType, cardID, tradeMoney, remark) + VALUES (NOW(), '存款', NEW.cardID, NEW.balance - OLD.balance, + CONCAT('存款操作,余额:', OLD.balance, '→', NEW.balance)); + END IF; +END // + +DROP TRIGGER IF EXISTS trg_after_withdraw; +CREATE TRIGGER trg_after_withdraw +AFTER UPDATE ON cardInfo +FOR EACH ROW +BEGIN + IF NEW.balance < OLD.balance AND @transfer_from IS NULL THEN + INSERT INTO tradeInfo(tradeDate, tradeType, cardID, tradeMoney, remark) + VALUES (NOW(), '取款', NEW.cardID, OLD.balance - NEW.balance, + CONCAT('取款操作,余额:', OLD.balance, '→', NEW.balance)); + END IF; +END // + +DROP TRIGGER IF EXISTS trg_transfer_out; +CREATE TRIGGER trg_transfer_out +AFTER UPDATE ON cardInfo +FOR EACH ROW +BEGIN + IF @transfer_from IS NOT NULL AND NEW.cardID = @transfer_from AND NEW.balance < OLD.balance THEN + INSERT INTO tradeInfo(tradeDate, tradeType, cardID, tradeMoney, remark) + VALUES (NOW(), '转账', NEW.cardID, OLD.balance - NEW.balance, + CONCAT('转出到', @transfer_to, ',金额:', OLD.balance - NEW.balance, + ',余额变化:', OLD.balance, '→', NEW.balance)); + END IF; +END // + +DROP TRIGGER IF EXISTS trg_transfer_in; +CREATE TRIGGER trg_transfer_in +AFTER UPDATE ON cardInfo +FOR EACH ROW +BEGIN + IF @transfer_to IS NOT NULL AND NEW.cardID = @transfer_to AND NEW.balance > OLD.balance THEN + INSERT INTO tradeInfo(tradeDate, tradeType, cardID, tradeMoney, remark) + VALUES (NOW(), '转账', NEW.cardID, NEW.balance - OLD.balance, + CONCAT('从', @transfer_from, '转入,金额:', NEW.balance - OLD.balance, + ',余额变化:', OLD.balance, '→', NEW.balance)); + END IF; +END // + +DELIMITER ; + +-- ----------------------------------------------------- +-- 存储过程定义(修复命名问题) +-- ----------------------------------------------------- + +DELIMITER // + +DROP PROCEDURE IF EXISTS sp_transfer; +CREATE PROCEDURE sp_transfer( + IN from_card CHAR(19), + IN to_card CHAR(19), + IN amount DECIMAL(18,2), + OUT result BOOLEAN, + OUT message VARCHAR(255) +) +proc_main: BEGIN + DECLARE from_bal DECIMAL(18,2); + DECLARE from_cur CHAR(3); + DECLARE to_cur CHAR(3); + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK; + SET result = FALSE; + SET message = '转账失败:系统异常'; + END; + + SET result = FALSE; + SET message = ''; + + IF amount <= 0 THEN + SET message = '转账金额必须大于0'; + LEAVE proc_main; + END IF; + + SELECT balance, curID INTO from_bal, from_cur + FROM cardInfo + WHERE cardID = from_card AND isReportLoss = '否'; + + IF from_bal IS NULL THEN + SET message = '转出账户不存在或已挂失'; + LEAVE proc_main; + END IF; + + SELECT curID INTO to_cur + FROM cardInfo + WHERE cardID = to_card AND isReportLoss = '否'; + + IF to_cur IS NULL THEN + SET message = '转入账户不存在或已挂失'; + LEAVE proc_main; + END IF; + + IF from_bal < amount THEN + SET message = CONCAT('余额不足,当前余额:', from_bal); + LEAVE proc_main; + END IF; + + IF from_cur <> to_cur THEN + SET message = '转入/转出账户货币类型不匹配'; + LEAVE proc_main; + END IF; + + START TRANSACTION; + BEGIN + SET @transfer_from = from_card; + SET @transfer_to = to_card; + SET @transfer_amount = amount; + + UPDATE cardInfo SET balance = balance - amount WHERE cardID = from_card; + UPDATE cardInfo SET balance = balance + amount WHERE cardID = to_card; + + SET @transfer_from = NULL; + SET @transfer_to = NULL; + SET @transfer_amount = NULL; + END; + COMMIT; + + SET result = TRUE; + SET message = '转账操作成功完成'; +END // + +DROP PROCEDURE IF EXISTS sp_get_card_trade_total; +CREATE PROCEDURE sp_get_card_trade_total( + IN p_card_id CHAR(19), + OUT total_amount DECIMAL(18,2) +) +BEGIN + SELECT SUM(tradeMoney) INTO total_amount + FROM tradeInfo + WHERE cardID = p_card_id; + + IF total_amount IS NULL THEN + SET total_amount = 0.00; + END IF; +END // + +DROP PROCEDURE IF EXISTS sp_export_trade_csv; +CREATE PROCEDURE sp_export_trade_csv( + IN p_year INT, + IN p_month INT, + IN p_file_path VARCHAR(255) +) +BEGIN + SET @query = CONCAT( + 'SELECT ', + 'DATE_FORMAT(tradeDate, ''%Y-%m-%d %H:%i:%s''),', + 'tradeType,', + 'cardID,', + 'tradeMoney,', + 'remark ', + 'FROM tradeInfo ', + 'WHERE YEAR(tradeDate) = ', p_year, ' AND MONTH(tradeDate) = ', p_month, ' ', + 'INTO OUTFILE ''', p_file_path, ''' ', + 'FIELDS TERMINATED BY '','' ENCLOSED BY ''"'' ', + 'LINES TERMINATED BY ''\n''' + ); + + PREPARE stmt FROM @query; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; +END // + +DELIMITER ; + +-- ----------------------------------------------------- +-- 视图定义 +-- ----------------------------------------------------- + +CREATE OR REPLACE VIEW vw_customer_summary AS +SELECT + u.customerID, + u.customerName, + u.PID, + u.telephone, + u.address, + c.cardID, + c.curID, + d.savingName, + c.balance, + c.isReportLoss, + t.tradeDate, + t.tradeType, + t.tradeMoney, + t.remark +FROM userInfo u +JOIN cardInfo c ON u.customerID = c.customerID +JOIN deposit d ON c.savingID = d.savingID +LEFT JOIN tradeInfo t ON c.cardID = t.cardID; + +CREATE OR REPLACE VIEW vw_monthly_trade AS +SELECT + YEAR(tradeDate) AS trade_year, + MONTH(tradeDate) AS trade_month, + cardID, + SUM(tradeMoney) AS monthly_trade, + COUNT(*) AS trade_count +FROM tradeInfo +GROUP BY trade_year, trade_month, cardID; + +-- ----------------------------------------------------- +-- 测试数据插入 +-- ----------------------------------------------------- + +-- 首次执行时取消注释,清空旧数据 +TRUNCATE TABLE tradeInfo; +TRUNCATE TABLE cardInfo; +TRUNCATE TABLE userInfo; +TRUNCATE TABLE deposit; + +-- 插入存款类型 +INSERT INTO deposit (savingName, descrip) VALUES +('活期', '按存款日结算利息'), +('定期一年', '存款期是1年'), +('定期二年', '存款期是2年'), +('定期三年', '存款期是3年'), +('定活两便', NULL), +('零存整取一年', '存款期是1年'), +('零存整取二年', '存款期是2年'), +('零存整取三年', '存款期是3年'); + +-- 插入用户数据 +INSERT INTO userInfo (customerName, PID, telephone, address) VALUES +('John', '110000000000000001', '13900000001', '江苏省南京市'), +('Jane', '110000000000000002', '13900000002', NULL), +('Michael', '110000000000000003', '13900000003', NULL), +('Emily', '110000000000000004', '13900000004', NULL), +('David', '110000000000000005', '13900000005', NULL), +('Sarah', '110000000000000006', '13900000006', NULL), +('Robert', '110000000000000007', '13900000007', NULL), +('Jessica', '110000000000000008', '13900000008', NULL), +('William', '110000000000000009', '13900000009', NULL), +('Olivia', '110000000000000010', '13900000010', NULL); + +-- 插入银行卡数据 +INSERT IGNORE INTO cardInfo (cardID, curID, savingID, openMoney, balance, pass, isReportLoss, customerID) VALUES +('1010357600000001', 'RMB', 1, 1000.00, 1000.00, '888888', '否', 1), +('1010357600000002', 'RMB', 2, 1.00, 1.00, '888888', '否', 2), +('1010357600000003', 'RMB', 2, 1.00, 1.00, '888888', '否', 3), +('1010357600000004', 'RMB', 2, 1.00, 1.00, '888888', '否', 4), +('1010357600000005', 'RMB', 3, 500.00, 500.00, '888888', '否', 5), +('1010357600000006', 'RMB', 3, 300.00, 300.00, '888888', '否', 6), +('1010357600000007', 'RMB', 3, 200.00, 200.00, '888888', '否', 7), +('1010357600000008', 'RMB', 3, 150.00, 150.00, '888888', '否', 8), +('1010357600000009', 'RMB', 3, 100.00, 100.00, '888888', '否', 9), +('1010357600000010', 'RMB', 3, 80.00, 80.00, '888888', '否', 10); + +-- 插入交易记录 +INSERT IGNORE INTO tradeInfo (tradeDate, tradeType, cardID, tradeMoney, remark) VALUES +(NOW() - INTERVAL 10 DAY, '存款', '1010357600000001', 500.00, '工资入账'), +(NOW() - INTERVAL 9 DAY, '取款', '1010357600000001', 200.00, 'ATM取款'), +(NOW() - INTERVAL 8 DAY, '存款', '1010357600000005', 300.00, '定期存款'), +(NOW() - INTERVAL 7 DAY, '转账', '1010357600000001', 100.00, '转出到1010357600000005'), +(NOW() - INTERVAL 7 DAY, '转账', '1010357600000005', 100.00, '从1010357600000001转入'), +(NOW() - INTERVAL 6 DAY, '取款', '1010357600000006', 50.00, '商场消费'), +(NOW() - INTERVAL 5 DAY, '存款', '1010357600000007', 200.00, '奖金入账'), +(NOW() - INTERVAL 4 DAY, '取款', '1010357600000002', 10.00, '超市购物'), +(NOW() - INTERVAL 3 DAY, '存款', '1010357600000003', 50.00, '零花钱'), +(NOW() - INTERVAL 2 DAY, '转账', '1010357600000007', 80.00, '转出到1010357600000009'), +(NOW() - INTERVAL 2 DAY, '转账', '1010357600000009', 80.00, '从1010357600000007转入'), +(NOW() - INTERVAL 1 DAY, '取款', '1010357600000008', 30.00, '餐饮消费'); + +-- ----------------------------------------------------- +-- 功能测试(取消注释执行) +-- ----------------------------------------------------- + +/* +-- 测试:查询银行卡交易总额 +SET @total = 0; +CALL sp_get_card_trade_total('1010357600000001', @total); +SELECT CONCAT('银行卡 1010357600000001 交易总额: ', @total) AS result; + +-- 测试:执行转账操作 +SET @result = FALSE; +SET @message = ''; +CALL sp_transfer('1010357600000001', '1010357600000002', 50.00, @result, @message); +SELECT @result AS success, @message AS message; + +-- 测试:导出当月交易记录到CSV +SET @year = YEAR(NOW()); +SET @month = MONTH(NOW()); +CALL sp_export_trade_csv(@year, @month, '/var/lib/mysql-files/trade_current_month.csv'); +*/ \ No newline at end of file