当前位置: 首页 > news >正文

板凳-------Mysql cookbook学习 (十一--------12)

第16章:使用存储例程、触发器和事件
16.0 引言

mysql> -- 首先设置分隔符(避免分号被解释为语句结束)
mysql> DELIMITER //
mysql>
mysql> -- 创建第一个存储过程
mysql> CREATE PROCEDURE get_time()-> BEGIN->     SET @current_time = CURTIME();-> END//
ERROR 1304 (42000): PROCEDURE get_time already exists
mysql>
mysql> -- 创建第二个存储过程(调用第一个)
mysql> CREATE PROCEDURE part_of_day()-> BEGIN->     CALL get_time();->->     -- 这里可以添加更多逻辑,例如:->     IF HOUR(@current_time) < 12 THEN->         SELECT 'Morning' AS part_of_day;->     ELSEIF HOUR(@current_time) < 18 THEN->         SELECT 'Afternoon' AS part_of_day;->     ELSE->         SELECT 'Evening' AS part_of_day;->     END IF;-> END//
Query OK, 0 rows affected (0.01 sec)mysql>
mysql> -- 恢复默认分隔符
mysql> DELIMITER ;
mysql>
mysql> -- 测试调用
mysql> CALL part_of_day();
+-------------+
| part_of_day |
+-------------+
| Evening     |
+-------------+
1 row in set (0.01 sec)Query OK, 0 rows affected (0.02 sec)
关键点说明:
1.	DELIMITER 命令:临时将语句分隔符从 ; 改为 //,这样存储过程中的分号不会提前终止创建过程
2.	BEGIN/END 块:每个存储过程体必须用 BEGINEND 包围
3.	调用顺序:确保被调用的存储过程(get_time())已经存在
4.	完整语法:存储过程可以包含复杂的逻辑(如我的示例中添加了时间段判断)

16.1 创建复合语句对象

mysql> -- 首先设置分隔符
mysql> DELIMITER //
mysql>
mysql> -- 创建第一个无参数函数(已成功)
mysql> CREATE FUNCTION avg_mail_size()-> RETURNS FLOAT READS SQL DATA-> RETURN (SELECT AVG(size) FROM mail)//
ERROR 1304 (42000): FUNCTION avg_mail_size already exists
mysql>
mysql> -- 创建带参数的函数
mysql> CREATE FUNCTION avg_mail_size(user VARCHAR(8))-> RETURNS FLOAT READS SQL DATA-> BEGIN->     IF user IS NULL THEN->         RETURN (SELECT AVG(size) FROM mail);->     ELSE->         RETURN (SELECT AVG(size) FROM mail WHERE srcuser = user);->     END IF;-> END//
ERROR 1304 (42000): FUNCTION avg_mail_size already exists
mysql>
mysql> -- 恢复默认分隔符
mysql> DELIMITER ;
mysql>mysql> DROP FUNCTION IF EXISTS avg_mail_size;
Query OK, 0 rows affected (0.02 sec)mysql> DELIMITER $$
mysql> CREATE FUNCTION avg_mail_size(user VARCHAR(8))-> RETURNS FLOAT READS SQL DATA-> BEGIN->     IF user IS NULL THEN->         RETURN (SELECT AVG(size) FROM mail);->     ELSE->         RETURN (SELECT AVG(size) FROM mail WHERE srcuser = user);->     END IF;-> END$$
Query OK, 0 rows affected (0.02 sec)mysql> DELIMITER ;
mysql> select avg_mail_size(null), avg_mail_size('barb');
+---------------------+-----------------------+
| avg_mail_size(null) | avg_mail_size('barb') |
+---------------------+-----------------------+
|              237387 |                 52232 |
+---------------------+-----------------------+
1 row in set (0.01 sec)

16.2 使用存储函数封装计算

mysql> DELIMITER $$
mysql>
mysql> CREATE FUNCTION sales_tax(state_param CHAR(2), amount_param DECIMAL(10, 2))-> RETURNS DECIMAL(10, 2) READS SQL DATA-> BEGIN->     DECLARE rate_var DECIMAL(3, 2);  -- 修正声明语法->     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET rate_var = 0;->->     SELECT tax_rate INTO rate_var->     FROM sales_tax_rate->     WHERE state = state_param;->->     RETURN amount_param * rate_var;-> END$$
Query OK, 0 rows affected (0.01 sec)mysql>
mysql> DELIMITER ;mysql> select sales_tax('ZZ', 100.00);
+-------------------------+
| sales_tax('ZZ', 100.00) |
+-------------------------+
|                    0.00 |
+-------------------------+
1 row in set (0.01 sec)完整测试流程示例mysql> -- 1. 确保表结构正确
mysql> CREATE TABLE IF NOT EXISTS sales_tax_rate (->     state CHAR(2) PRIMARY KEY,->     tax_rate DECIMAL(3,2)-> );
Query OK, 0 rows affected, 1 warning (0.01 sec)mysql>
mysql> -- 2. 清空并重置测试数据
mysql> TRUNCATE TABLE sales_tax_rate;
Query OK, 0 rows affected (0.07 sec)mysql> INSERT INTO sales_tax_rate VALUES->     ('CA', 0.08),->     ('NY', 0.09),->     ('TX', 0.0625);
Query OK, 3 rows affected, 1 warning (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 1mysql>
mysql> -- 3. 重新创建函数(确保使用最新版本)
mysql> DELIMITER $$
mysql> DROP FUNCTION IF EXISTS sales_tax$$
Query OK, 0 rows affected (0.01 sec)mysql> CREATE FUNCTION sales_tax(state_param CHAR(2), amount_param DECIMAL(10,2))-> RETURNS DECIMAL(10,2) READS SQL DATA-> BEGIN->     DECLARE rate_var DECIMAL(3,2) DEFAULT 0;->     DECLARE CONTINUE HANDLER FOR NOT FOUND SET rate_var = 0;->->     SELECT tax_rate INTO rate_var->     FROM sales_tax_rate->     WHERE state = state_param;->->     RETURN amount_param * rate_var;-> END$$
Query OK, 0 rows affected (0.02 sec)mysql> DELIMITER ;
mysql>
mysql> -- 4. 全面测试
mysql> SELECT->     sales_tax('CA', 100) AS California,->     sales_tax('NY', 100) AS NewYork,->     sales_tax('TX', 100) AS Texas,->     sales_tax('XX', 100) AS UnknownState;
+------------+---------+-------+--------------+
| California | NewYork | Texas | UnknownState |
+------------+---------+-------+--------------+
|       8.00 |    9.00 |  6.00 |         0.00 |
+------------+---------+-------+--------------+
1 row in set (0.00 sec)

16.3 使用存储过程来“返回”多个值

mysql> DELIMITER $$
mysql>
mysql> CREATE PROCEDURE mail_sends_stats(->     IN user VARCHAR(8),->     OUT messages INT,->     OUT total_size FLOAT,->     OUT avg_size FLOAT-> )-> BEGIN->     SELECT COUNT(*), IFNULL(SUM(size), 0), IFNULL(AVG(size), 0)->     INTO messages, total_size, avg_size->     FROM mail WHERE srcuser = user;-> END$$
Query OK, 0 rows affected (0.01 sec)mysql>
mysql> DELIMITER ;mysql> call mail_sends_stats('barb', @messages, @total_size, @avg_size);
Query OK, 1 row affected (0.00 sec)mysql> select @messages, @total_size, @avg_size;
+-----------+-------------+-----------+
| @messages | @total_size | @avg_size |
+-----------+-------------+-----------+
|         3 |      156696 |     52232 |
+-----------+-------------+-----------+
1 row in set (0.00 sec)
16.4 用触发器来定义动态的默认列值
mysql> create table doc_table(-> author varchar(100) not null,-> title  varchar(100) not null,-> documer mediumblob not null,-> doc_hash char(32) not null,-> primary key (doc_hash)-> );
Query OK, 0 rows affected (0.05 sec)mysql> create trigger bi_doc_table before insert on doc_table-> for each row set new.doc_hash = MD5(new.documer);
Query OK, 0 rows affected (0.01 sec)mysql> insert into doc_table (author, title, documer)-> values('Mr. Famous Writer', 'My life as a writer', 'This is the document');
Query OK, 1 row affected (0.01 sec)mysql> SELECT * FROM doc_table\G
*************************** 1. row ***************************author: Mr. Famous Writertitle: My life as a writerdocumer: 0x546869732069732074686520646F63756D656E74
doc_hash: 5282317909724f9f1e65318be129539c
1 row in set (0.00 sec)mysql> CREATE TRIGGER bu_doc_table-> BEFORE UPDATE ON doc_table
1.	    -> FOR EACH ROW  #确保 FOR EACH ROW 作为完整的语法单元-> SET NEW.doc_hash = MD5(NEW.documer);
Query OK, 0 rows affected (0.02 sec)mysql> -- 删除已存在的同名触发器(如果存在)
mysql> DROP TRIGGER IF EXISTS bu_doc_table;
Query OK, 0 rows affected (0.01 sec)mysql>
mysql> -- 创建更新触发器
mysql> CREATE TRIGGER bu_doc_table-> BEFORE UPDATE ON doc_table-> FOR EACH ROW-> SET NEW.doc_hash = MD5(NEW.documer);
Query OK, 0 rows affected (0.01 sec)mysql>
mysql> -- 测试触发器
mysql> UPDATE doc_table-> SET documer = 'Updated document content'-> WHERE author = 'Mr. Famous Writer';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select MD5('a new document');
+----------------------------------+
| MD5('a new document')            |
+----------------------------------+
| a5136f98d2313cc850527957b4293f60 |
+----------------------------------+
1 row in set (0.00 sec)

16.5 为其他日期和时间类型模拟timestamp属性

mysql> create table ts_emulate(-> data char(10),-> d    date,-> t    time,-> dt    datetime-> );
Query OK, 0 rows affected (0.04 sec)mysql> create trigger bi_ts_emulate before insert on ts_emulate-> for each row set new.d = curdate(), new.t = curtime(), new.dt = now();
Query OK, 0 rows affected (0.01 sec)mysql> insert into ts_emulate (data) values ('cat');
Query OK, 1 row affected (0.01 sec)mysql> insert into ts_emulate (data) values ('dog');
Query OK, 1 row affected (0.01 sec)mysql> select * from ts_emulate;
+------+------------+----------+---------------------+
| data | d          | t        | dt                  |
+------+------------+----------+---------------------+
| cat  | 2025-07-15 | 21:40:48 | 2025-07-15 21:40:48 |
| dog  | 2025-07-15 | 21:40:59 | 2025-07-15 21:40:59 |
+------+------------+----------+---------------------+
2 rows in set (0.00 sec)mysql> update ts_emulate set data = 'axolot1' where data = 'cat';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> select * from ts_emulate;
+---------+------------+----------+---------------------+
| data    | d          | t        | dt                  |
+---------+------------+----------+---------------------+
| axolot1 | 2025-07-15 | 21:40:48 | 2025-07-15 21:40:48 |
| dog     | 2025-07-15 | 21:40:59 | 2025-07-15 21:40:59 |
+---------+------------+----------+---------------------+
2 rows in set (0.00 sec)mysql> update ts_emulate set data = data;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 2  Changed: 0  Warnings: 0mysql> select * from ts_emulate;
+---------+------------+----------+---------------------+
| data    | d          | t        | dt                  |
+---------+------------+----------+---------------------+
| axolot1 | 2025-07-15 | 21:40:48 | 2025-07-15 21:40:48 |
| dog     | 2025-07-15 | 21:40:59 | 2025-07-15 21:40:59 |
+---------+------------+----------+---------------------+
2 rows in set (0.00 sec)

16.6 使用触发器记录表的变化

拍卖流程图 java 拍卖系统开发_mob6454cc780924的技术博客_51CTO博客drop database if exists auction;create database auction;use auction;#用户表
create table auction_user(user_id int(11) auto_increment,username varchar(50) not null,userpass varchar(50) not null,email varchar(100) not null,primary key(user_id),unique(username)
);INSERT INTO auction_user (username,userpass,email) VALUES ('tomcat','tomcat','spring_test@');
INSERT INTO auction_user (username,userpass,email) VALUES ('mysql','mysql','spring_test@');#物品种类表
create table kind(kind_id int(11) auto_increment,kind_name varchar(50) not null, kind_desc varchar(255) not null,primary key(kind_id)
);INSERT INTO kind (kind_name,kind_desc) VALUES ('电脑硬件','这里并不是很主流的产品,但价格绝对令你心动');
INSERT INTO kind (kind_name,kind_desc) VALUES ('房产','提供非常稀缺的房源');#物品状态表
create table state(state_id int(11) auto_increment,state_name varchar(10),primary key(state_id)
);INSERT INTO state (state_name) VALUES ('拍卖中');
INSERT INTO state (state_name) VALUES ('拍卖成功');
INSERT INTO state (state_name) VALUES ('流拍');#物品表
create table item(item_id int(11) auto_increment,item_name varchar(255) not null,item_remark varchar(255),item_desc varchar(255),kind_id int(11) not null, addtime date not null,endtime date not null,init_price double not null, max_price double not null, owner_id int(11) not null, winer_id int(11), state_id int(11) not null, primary key(item_id),FOREIGN KEY(kind_id) REFERENCES kind(kind_id), FOREIGN KEY(owner_id) REFERENCES auction_user(user_id),FOREIGN KEY(winer_id) REFERENCES auction_user(user_id),FOREIGN KEY(state_id) REFERENCES state(state_id)
); # 拍卖中的物品
INSERT INTO item ( item_name , item_remark , item_desc, kind_id, addtime , endtime, init_price,  max_price,  owner_id,  winer_id,  state_id)VALUES ( '主板', '老式主板', '老主板,还可以用', 1, ADDDATE(CURDATE(), -5), ADDDATE(CURDATE(), 30) , 230, 250, 1,  null,  1);
# 流派的物品
INSERT INTO item ( item_name , item_remark , item_desc, kind_id, addtime , endtime, init_price,  max_price,  owner_id,  winer_id,  state_id)VALUES ( '显卡', '老式显卡', '老显卡,还可以用', 1, ADDDATE(CURDATE(), -9), ADDDATE(CURDATE(), -2), 210, 210, 2,  null,  3);
# 被竞得的物品
INSERT INTO item ( item_name , item_remark , item_desc, kind_id, addtime , endtime, init_price,  max_price,  owner_id,  winer_id,  state_id)VALUES ( '老房子', '老式房子', '40年的老房子', 2, ADDDATE(CURDATE(), -9), ADDDATE(CURDATE(), -5), 21000, 25000, 2,  1,  2);#竞标历史表
create table bid(bid_id int(11) auto_increment,user_id int(11) not null,item_id int(11) not null,bid_price double not null,bid_date date not null, primary key(bid_id),unique(item_id , bid_price),FOREIGN KEY(user_id) REFERENCES auction_user(user_id), FOREIGN KEY(item_id) REFERENCES item(item_id)   
);INSERT INTO bid ( user_id , item_id , bid_price, bid_date)VALUES ( 2, 1, 250, ADDDATE(CURDATE(), -2));
INSERT INTO bid ( user_id , item_id , bid_price, bid_date)VALUES ( 1, 3, 25000, ADDDATE(CURDATE(), -6));Python Web服务器搭建 - 拍卖系统
下面是将Java PO/VO对象和MySQL数据库转换为Python的实现:1. 数据库模型 (PO对象)
python
from datetime import datetime
from typing import List, Set, Optional
from sqlalchemy import Column, Integer, String, Float, Date, ForeignKey, Table
from sqlalchemy.orm import relationship, declarative_baseBase = declarative_base()# 关联表
bid_item_user = Table('bid', Base.metadata,Column('bid_id', Integer, primary_key=True, autoincrement=True),Column('user_id', Integer, ForeignKey('auction_user.user_id'), nullable=False),Column('item_id', Integer, ForeignKey('item.item_id'), nullable=False),Column('bid_price', Float, nullable=False),Column('bid_date', Date, nullable=False)
)class User(Base):__tablename__ = 'auction_user'user_id = Column(Integer, primary_key=True, autoincrement=True)username = Column(String(50), unique=True, nullable=False)userpass = Column(String(50), nullable=False)email = Column(String(100), nullable=False)# 关系owned_items = relationship("Item", back_populates="owner", foreign_keys="Item.owner_id")won_items = relationship("Item", back_populates="winer", foreign_keys="Item.winer_id")bids = relationship("Bid", back_populates="user")class Kind(Base):__tablename__ = 'kind'kind_id = Column(Integer, primary_key=True, autoincrement=True)kind_name = Column(String(50), nullable=False)kind_desc = Column(String(255), nullable=False)items = relationship("Item", back_populates="kind")class State(Base):__tablename__ = 'state'state_id = Column(Integer, primary_key=True, autoincrement=True)state_name = Column(String(10))items = relationship("Item", back_populates="item_state")class Item(Base):__tablename__ = 'item'item_id = Column(Integer, primary_key=True, autoincrement=True)item_name = Column(String(255), nullable=False)item_remark = Column(String(255))item_desc = Column(String(255))# 外键kind_id = Column(Integer, ForeignKey('kind.kind_id'), nullable=False)owner_id = Column(Integer, ForeignKey('auction_user.user_id'), nullable=False)winer_id = Column(Integer, ForeignKey('auction_user.user_id'))state_id = Column(Integer, ForeignKey('state.state_id'), nullable=False)addtime = Column(Date, nullable=False)endtime = Column(Date, nullable=False)init_price = Column(Float, nullable=False)max_price = Column(Float, nullable=False)# 关系kind = relationship("Kind", back_populates="items")owner = relationship("User", back_populates="owned_items", foreign_keys=[owner_id])winer = relationship("User", back_populates="won_items", foreign_keys=[winer_id])item_state = relationship("State", back_populates="items")bids = relationship("Bid", back_populates="item")class Bid(Base):__tablename__ = 'bid'bid_id = Column(Integer, primary_key=True, autoincrement=True)bid_price = Column(Float, nullable=False)bid_date = Column(Date, nullable=False)# 外键user_id = Column(Integer, ForeignKey('auction_user.user_id'), nullable=False)item_id = Column(Integer, ForeignKey('item.item_id'), nullable=False)# 关系user = relationship("User", back_populates="bids")item = relationship("Item", back_populates="bids")
2. 业务对象 (VO对象)
python
from dataclasses import dataclass
from datetime import datetime@dataclass
class ItemBean:id: intname: strdesc: strremark: strkind: strowner: strwiner: strstate: strinit_price: floatmax_price: floatadd_time: datetimeend_time: datetime@dataclass
class BidBean:id: intuser: stritem: strprice: floatbid_date: datetime@dataclass
class KindBean:id: intkind_name: strkind_desc: str
3. 数据库初始化
python
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker# 创建数据库连接
DATABASE_URL = "mysql+pymysql://username:password@localhost/auction"
engine = create_engine(DATABASE_URL)# 创建表
Base.metadata.create_all(engine)# 创建会话工厂
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)def get_db():db = SessionLocal()try:yield dbfinally:db.close()
4. FastAPI 路由示例
python
from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from datetime import datetime, timedeltaapp = FastAPI()# 获取所有拍卖物品
@app.get("/items/", response_model=List[ItemBean])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):db_items = db.query(Item).offset(skip).limit(limit).all()items = []for item in db_items:items.append(ItemBean(id=item.item_id,name=item.item_name,desc=item.item_desc,remark=item.item_remark,kind=item.kind.kind_name,owner=item.owner.username,winer=item.winer.username if item.winer else None,state=item.item_state.state_name,init_price=item.init_price,max_price=item.max_price,add_time=item.addtime,end_time=item.endtime))return items# 创建新物品
@app.post("/items/", response_model=ItemBean)
def create_item(item: ItemBean, db: Session = Depends(get_db)):db_item = Item(item_name=item.name,item_desc=item.desc,item_remark=item.remark,kind_id=item.kind_id,addtime=datetime.now(),endtime=datetime.now() + timedelta(days=30),init_price=item.init_price,max_price=item.init_price,owner_id=item.owner_id,state_id=1  # 默认拍卖中)db.add(db_item)db.commit()db.refresh(db_item)return item# 获取单个物品详情
@app.get("/items/{item_id}", response_model=ItemBean)
def read_item(item_id: int, db: Session = Depends(get_db)):db_item = db.query(Item).filter(Item.item_id == item_id).first()if db_item is None:raise HTTPException(status_code=404, detail="Item not found")return ItemBean(id=db_item.item_id,name=db_item.item_name,desc=db_item.item_desc,remark=db_item.item_remark,kind=db_item.kind.kind_name,owner=db_item.owner.username,winer=db_item.winer.username if db_item.winer else None,state=db_item.item_state.state_name,init_price=db_item.init_price,max_price=db_item.max_price,add_time=db_item.addtime,end_time=db_item.endtime)
5. 数据库初始化数据
python
def init_db():db = SessionLocal()try:# 创建测试用户user1 = User(username="tomcat", userpass="tomcat", email="spring_test@")user2 = User(username="mysql", userpass="mysql", email="spring_test@")db.add_all([user1, user2])db.commit()# 创建物品种类kind1 = Kind(kind_name="电脑硬件", kind_desc="这里并不是很主流的产品,但价格绝对令你心动")kind2 = Kind(kind_name="房产", kind_desc="提供非常稀缺的房源")db.add_all([kind1, kind2])db.commit()# 创建物品状态state1 = State(state_name="拍卖中")state2 = State(state_name="拍卖成功")state3 = State(state_name="流拍")db.add_all([state1, state2, state3])db.commit()# 创建物品item1 = Item(item_name="主板",item_remark="老式主板",item_desc="老主板,还可以用",kind_id=kind1.kind_id,addtime=datetime.now() - timedelta(days=5),endtime=datetime.now() + timedelta(days=30),init_price=230,max_price=250,owner_id=user1.user_id,state_id=state1.state_id)item2 = Item(item_name="显卡",item_remark="老式显卡",item_desc="老显卡,还可以用",kind_id=kind1.kind_id,addtime=datetime.now() - timedelta(days=9),endtime=datetime.now() - timedelta(days=2),init_price=210,max_price=210,owner_id=user2.user_id,state_id=state3.state_id)item3 = Item(item_name="老房子",item_remark="老式房子",item_desc="40年的老房子",kind_id=kind2.kind_id,addtime=datetime.now() - timedelta(days=9),endtime=datetime.now() - timedelta(days=5),init_price=21000,max_price=25000,owner_id=user2.user_id,winer_id=user1.user_id,state_id=state2.state_id)db.add_all([item1, item2, item3])db.commit()# 创建竞标记录bid1 = Bid(user_id=user2.user_id,item_id=item1.item_id,bid_price=250,bid_date=datetime.now() - timedelta(days=2))bid2 = Bid(user_id=user1.user_id,item_id=item3.item_id,bid_price=25000,bid_date=datetime.now() - timedelta(days=6))db.add_all([bid1, bid2])db.commit()except Exception as e:db.rollback()raise efinally:db.close()# 调用初始化函数
init_db()
6. 运行FastAPI应用
创建一个main.py文件:python
from fastapi import FastAPI
from models import Base
from database import engine, init_db
import uvicorn# 创建表
Base.metadata.create_all(bind=engine)# 初始化数据
init_db()app = FastAPI()# 导入路由
from routes import itemsapp.include_router(items.router)if __name__ == "__main__":uvicorn.run(app, host="0.0.0.0", port=8000)
7. 依赖安装
创建一个requirements.txt文件:text
fastapi
uvicorn
sqlalchemy
pymysql
python-dotenv
python-dateutil
然后运行:bash
pip install -r requirements.txt
8. 运行应用
bash
python main.py
现在你的拍卖系统Web服务器应该运行在 http://localhost:8000 上,你可以访问 /items/ 端点来获取所有拍卖物品的列表。这个实现使用了:SQLAlchemy 作为ORMFastAPI 作为Web框架Pydantic (通过FastAPI的response_model) 进行数据验证和序列化MySQL 作为数据库你可以根据需要进一步扩展功能,比如添加用户认证、竞价功能、物品搜索等。===================================================
mysql> create table auction(-> id int unsigned not null auto_increment,-> ts  timestamp,-> item varchar(30) not null,-> bid decimal(10, 2) not null,-> primary key(id)-> );
Query OK, 0 rows affected (0.04 sec)mysql> create table auction_log(-> action enum('create', 'update','delete'),-> id int unsigned not null,-> ts timestamp,-> item varchar(30) not null,-> bid decimal(10, 2) not null,-> index  (id)-> );
Query OK, 0 rows affected (0.09 sec)mysql>  DELIMITER ;
mysql> DELIMITER $$
mysql>
mysql> CREATE TRIGGER ai_auction AFTER INSERT ON auction-> FOR EACH ROW-> BEGIN->    INSERT INTO auction_log (action, id, ts, item, bid)->    VALUES('create', NEW.id, NOW(), NEW.item, NEW.bid);-> END$$
Query OK, 0 rows affected (0.02 sec)mysql>
mysql> CREATE TRIGGER au_auction AFTER UPDATE ON auction-> FOR EACH ROW-> BEGIN->    INSERT INTO auction_log (action, id, ts, item, bid)->    VALUES('update', NEW.id, NOW(), NEW.item, NEW.bid);-> END$$
Query OK, 0 rows affected (0.01 sec)mysql>
mysql> CREATE TRIGGER ad_auction AFTER DELETE ON auction-> FOR EACH ROW-> BEGIN->    INSERT INTO auction_log (action, id, ts, item, bid)->    VALUES('delete', OLD.id, OLD.ts, OLD.item, OLD.bid);-> END$$
Query OK, 0 rows affected (0.02 sec)mysql>
mysql> DELIMITER ;
mysql> insert into auction (item, bid) values('chintz pillows', 5.00);
Query OK, 1 row affected (0.01 sec)mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                1 |
+------------------+
1 row in set (0.00 sec)mysql> -- 1. 首先插入一条记录
mysql> INSERT INTO auction (item, bid) VALUES('chintz pillows', 5.00);
Query OK, 1 row affected (0.01 sec)mysql>
mysql> -- 2. 获取刚插入的ID(假设返回的是1)
mysql> SELECT last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                2 |
+------------------+
1 row in set (0.00 sec)mysql>
mysql> -- 3. 对这条记录进行更新(使用正确的ID)
mysql> UPDATE auction SET bid = 7.50 WHERE id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> UPDATE auction SET bid = 9.00 WHERE id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql> UPDATE auction SET bid = 10.00 WHERE id = 1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0mysql>
mysql> -- 4. 查询日志(使用正确的ID)
mysql> SELECT * FROM auction_log WHERE id = 1 ORDER BY ts;
+--------+----+---------------------+----------------+-------+
| action | id | ts                  | item           | bid   |
+--------+----+---------------------+----------------+-------+
| create |  1 | 2025-07-16 20:33:13 | chintz pillows |  5.00 |
| update |  1 | 2025-07-16 20:37:51 | chintz pillows |  7.50 |
| update |  1 | 2025-07-16 20:37:51 | chintz pillows |  9.00 |
| update |  1 | 2025-07-16 20:37:51 | chintz pillows | 10.00 |
+--------+----+---------------------+----------------+-------+
4 rows in set (0.00 sec)如果您想完全重现书上的示例(ID=792),可以这样做:
-- 1. 首先手动插入ID=792的记录(需要暂时关闭自增)
SET FOREIGN_KEY_CHECKS=0;
INSERT INTO auction (id, item, bid) VALUES(792, 'chintz pillows', 5.00);
SET FOREIGN_KEY_CHECKS=1;-- 2. 然后执行更新操作
UPDATE auction SET bid = 7.50 WHERE id = 792;
UPDATE auction SET bid = 9.00 WHERE id = 792;
UPDATE auction SET bid = 10.00 WHERE id = 792;-- 3. 查询日志
SELECT * FROM auction_log WHERE id = 792 ORDER BY ts;16.7 使用事件调度数据库动作
mysql> describe mark_log ;
+---------+--------------+------+-----+-------------------+-----------------------------------------------+
| Field   | Type         | Null | Key | Default           | Extra                                         |
+---------+--------------+------+-----+-------------------+-----------------------------------------------+
| id      | int          | NO   | PRI | NULL              | auto_increment                                |
| ts      | timestamp    | YES  |     | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| message | varchar(100) | YES  |     | NULL              |                                               |
+---------+--------------+------+-----+-------------------+-----------------------------------------------+
3 rows in set (0.07 sec)mysql> select * from mark_log;
Empty set (0.01 sec)mysql> show variables like 'event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | ON    |
+-----------------+-------+
1 row in set, 1 warning (0.01 sec)mysql> set global event_scheduler = 1;
Query OK, 0 rows affected (0.00 sec)
http://www.xdnf.cn/news/1137151.html

相关文章:

  • Python22 —— 标准库(random库)
  • Linux的Ext系列文件系统
  • 【JVM】深入理解 JVM 类加载器
  • 【推荐100个unity插件】使用C#或者unity实现爬虫爬取静态网页数据——Html Agility Pack (HAP)库和XPath 语法的使用
  • Java学习--JVM(2)
  • 学习C++、QT---27(QT中实现记事本项目实现行列显示、优化保存文件的功能的讲解)
  • 【Linux手册】缓冲区:深入浅出,从核心概念到实现逻辑
  • 数据结构:集合操作(Set Operations): 并集(Union)、交集(Intersection)、 差集(Difference)
  • 【37】MFC入门到精通——MFC中 CString 数字字符串 转 WORD ( CString, WORD/int 互转)
  • 编译原理第六到七章(知识点学习/期末复习/笔试/面试)
  • 【真·CPU训模型!】单颗i7家用本,4天0成本跑通中文小模型训练!Xiaothink-T6-mini-Preview 技术预览版开源发布!
  • 数据投毒技术之标签翻转
  • 题解:CF1829H Don‘t Blame Me
  • React Native 基础tabBar和自定义tabBar - bottom-tabs
  • 【开源软件推荐】 SmartSub,一个可以快速识别视频/音频字幕的工具
  • JavaScript进阶篇——第八章 原型链、深浅拷贝与原型继承全解析
  • 性能优化实践:Modbus 在高并发场景下的吞吐量提升(二)
  • 【Linux】第一个小程序—进度条
  • 自动化技术在造纸行业的应用:EtherCAT转PROFIBUS DP解决方案
  • 【中等】题解力扣22:括号生成
  • MyUI1.0全新现代化 Vue.js 组件库框架上线
  • HCIE - 云计算拿下后的职业选择如何规划?
  • 摩尔投票法:高效寻找数组中的多数元素
  • 基于在线地图的路径规划测评对比-综合对比城区、农村及城乡结合处的导航
  • 阿里云-通义灵码:隐私保护机制—为数据安全筑起铜墙铁壁
  • DolphinScheduler 如何高效调度 AnalyticDB on Spark 作业?
  • Flutter在Android studio运行出现Error: Entrypoint is not a Dart file
  • SpringBoot 使用MyBatisPlus
  • web APIs(更新中)
  • 【机器学习实战【七】】机器学习特征选定与评估