[數據庫-Mongo總結]-mysql使用總結和pymysql交互
3. MySQL
3.1 安裝
3.1.1 win
3.1.1.1 安裝
>下載mysql
>mysql-front:
Host:localhost
端口:3306
用戶:root
3.1.2 linux
3.1.2.1 安裝
>sudo apt-get install mysql-server mysql-client
>輸入密碼
3.1.2.2 連接
>mysql -uroot -p
>show databases;
>use database_name;
>select * from db;
3.1.2.3 修改配置
>cd /etc/mysql/
>cd mysql.conf.d/
>vi mysqld.cnf > bind adress注釋掉
>sudo service mysql restart
3.1.3 mac
3.1.3.1 安裝
brew install mysql
3.1.3.2 連接
>mysql -uroot -p(c1c1c1)
>show databases;
3.2設置密碼
>mysqladmin -uroot password "123" #設置初始密碼
>mysqladmin -uroot -p原密碼 password "新密碼" #修改用戶密碼
3.3登錄
>mysql #本地登錄,默認用戶root,空密碼,用戶為root@127.0.0.1
>mysql -uroot -p1234 #本地登錄,指定用戶名和密碼,用戶為root@127.0.0.1
>mysql -uroot -p1234 -h 192.168.31.95 #遠程登錄,用戶為root@192.168.31.95
>mysql -h服務器IP -P端口號 -u用戶名 --prompt命令提示符 --delemiter指定分隔符
> mysql -h127.0.0.1 -P3306 -uroot -p666666
3.4啟動
3.4.1 mac
>啟動 sudo /usr/local/mysql/support-files/mysql.server start
>重啟 sudo /usr/local/mysql/support-files/mysql.server restart
>停止 sudo /usr/local/mysql/support-files/mysql.server stop
3.4.2 linux
>service mysqld start #開啟
>chkconfig mysqld on / systemctl start mariadb #設置開機自啟
3.5忘記密碼
3.5.1 mac
>step1:蘋果->系統偏好設置->最下邊點mysql 在彈出頁面中 關閉mysql服務(點擊stop mysql server)
>step2:
>進入終端輸入:cd /usr/local/mysql/bin/
>回車后 登錄管理員權限 sudo su
>回車后輸入以下命令來禁止mysql驗證功能 ./mysqld_safe --skip-grant-tables &
>回車后mysql會自動重啟(偏好設置中mysql的狀態會變成running)
>step3:
>輸入命令 ./mysql
>回車后,輸入命令 FLUSH PRIVILEGES;
>回車后,輸入命令 SET PASSWORD FOR 'root'@'localhost' = PASSWORD('你的新密碼');
3.6 sql規范
>不區分大小寫,但是命令盡量用大寫,自定義的用小寫。
>以;為結束
>可以折行
3.7 DDL DML DCL
>創建數據庫
>create database if not exists database_name;
>create database if not exists database_name character set gbk;
默認編碼為utf-8
>查看數據庫 show databases;
>查看當前數據庫 select database();
>修改數據庫 alter dastabase db_name;
>alter dastabase db_name character set utf8;
>刪除數據庫 drop database if exists db_name;
>查看警錯誤信息 show warnings;
>查看創建表信息 show create database s;
>退出數據庫:use new_database;
3.8 數據類型 參考網址 http://www.rzrgm.cn/yuanchenqi/articles/6357507.html
>主鍵:非空且唯一 not null unique
>數字類型
>tinyint 1b (-128,127) (0,255)
>smallint 2b (-32768, 32767) (0,65535)
>mediumint 3b (-8388608, 8388607) (0, 16777215)
>int 4b
>bigint
>float
>double
>decimal
>字符串類型
>char 0-255b 定長字符串
>varchar 0-65535b 變長字符串
>tinyblob 0-255b 二進制字符串
>tinytext
>blob 0-65535b 二進制長字符串
>text 0- 65535b 長文本
>mediumblob
>mediumtext 0-167 77215b 中等長度文本數據
>longblob
>longtext 0- 4294967295b 極大文本數據
>時間類型
>date YYYY-MM-DD
>time HH:MM:SS
>year YYYY
>datetime YYYY-MM-DD HH:MM:SS
>timestamp YYYYMMDD HHMMSS
3.9 數據表操作
3.9.1 查看表
desc tab_name 查看表結構
show columns from tab_name 查看表結構
show tables 查看當前數據庫中的所有的表
show create table tab_name 查看當前數據庫表建表語句
3.9.2建表:
>CREATE TABLE employee( id TINYINT PRIMARY KEY auto_increment, name VARCHAR(25), gender boolean, age INT, department VARCHAR(20), salary DOUBLE(7,2) );
3.9.3 修改表
3.9.3.1增加列(字段)
>alter table tab_name add [column] 列名 類型[完整性約束條件][first|after 字段名];
>alter table user add addr varchar(20) not null unique first/after username;
>#添加多個字段
>alter table users2
add addr varchar(20),
add age int first,
add birth varchar(20) after name;
3.9.3.2修改一列類型
>alter table tab_name modify 列名 類型 [完整性約束條件][first|after 字段名];
>alter table users2 modify age tinyint default 20;
>alter table users2 modify age int after id;
3.9.3.3修改列名
>alter table tab_name change [column] 列名 新列名 類型 [完整性約束條件][first|after 字段名];
>alter table users2 change age Age int default 28 first;
3.9.3.4刪除一列
>alter table tab_name drop [column] 列名;
思考:刪除多列呢?刪一個填一個呢?
>alter table users2
add salary float(6,2) unsigned not null after name,
drop addr;
3.9.3.5修改表名
>rename table 表名 to 新表名;
3.9.3.6修該表所用的字符集
>alter table student character set utf8;
3.9.3.7刪除表
drop table tab_name;
3.9.3.8 添加主鍵,刪除主鍵
>alter table tab_name add primary key(字段名稱,...)
>alter table users drop primary key;
3.9.4 增加
3.9.4.1 增加一條記錄insert
>/*insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......);*/
3.9.4.2 插入多條數據
>insert into employee_new values
(4,'alvin1','1993-04-20',3000),
(5,'alvin2','1995-05-12',5000);
3.9.4.3 set插入
>insert [into] tab_name set 字段名=值
>insert into employee_new set id=12,name="alvin3";
3.9.5 修改
3.9.5.1修改表記錄
>update tab_name set field1=value1,field2=value2,......[where 語句]
/*UPDATE語法可以用新值更新原有表行中的各列。
SET子句指示要修改哪些列和要給予哪些值。
WHERE子句指定應更新哪些行。如沒有WHERE子句,則更新所有的行。*/
>update employee_new set birthday="1989-10-24" WHERE id=1;
>將yuan的薪水在原有基礎上增加1000元。
update employee_new set salary=salary+4000 where name='yuan';
3.9.6 刪除
3.9.6.1 刪除表記錄
>delete from tab_name [where ....]
/*如果不跟where語句則刪除整張表中的數據
delete只能用來刪除一行記錄
delete語句只能刪除表中的內容,不能刪除表本身,想要刪除表,用drop
TRUNCATE TABLE也可以刪除表中的所有數據,詞語句首先摧毀表,再新建表。此種方式刪除的數據不能在事務中恢復。*/
>刪除表中名稱為’alex’的記錄。
delete from employee_new where name='alex';
>刪除表中所有記錄。
delete from employee_new;
>注意auto_increment沒有被重置:
>alter table employee auto_increment=1;
>使用truncate刪除表中記錄。
truncate table emp_new;
>truncate 和 delete 的區別:
>delete:將表中數據一條一條的刪除
>truncate:將整張表刪除,再重新創建一張表名一樣的表
3.9.7 查詢 順序
SELECT *|field1,filed2 ... FROM tab_name
WHERE 條件
GROUP BY field
HAVING 篩選
ORDER BY field
LIMIT 限制條數
3.9.7.1 select .. from ..
> 查詢表中所有學生的信息。
select * from ExamResult;
>查詢表中所有學生的姓名和對應的英語成績。
select name,JS from ExamResult;
>過濾表中重復數據。
select distinct JS ,name from ExamResult;
select distinct * from ..;
3.9.7.2 select ..as....from
>select 也可以使用表達式,并且可以使用: 字段 as 別名或者:字段 別名
>在所有學生分數上加10分特長分顯示。
select name,JS+10,Django+10,OpenStack+10 from ExamResult;
>統計每個學生的總分。
select name,JS+Django+OpenStack from ExamResult;
>使用別名表示學生總分。
select name as 姓名,JS+Django+OpenStack as 總成績 from ExamResult;
select name,JS+Django+OpenStack 總成績 from ExamResult;
select name JS from ExamResult; -- what will happen?---->記得加逗號
3.9.7.3使用where子句,進行過濾查詢。
>查詢姓名為XXX的學生成績
select * from ExamResult where name='yuan';
>查詢英語成績大于90分的同學
select id,name,JS from ExamResult where JS>90;
>查詢總分大于200分的所有同學
select name,JS+Django+OpenStack as 總成績 from
ExamResult where JS+Django+OpenStack>200 ;
>where字句中可以使用:
>比較運算符:
> < >= <= <> !=
between 80 and 100 值在10到20之間
in(80,90,100) 值是10或20或30
like 'yuan%'
/*
pattern可以是%或者_,
如果是%則表示任意多字符,此例如唐僧,唐國強
如果是_則表示一個字符唐_,只有唐僧符合。兩個_則表示兩個字符:__
*/
>邏輯運算符
在多個條件直接可以使用邏輯運算符 and or not
>練習
>查詢JS分數在 70-100之間的同學。
select name ,JS from ExamResult where JS between 80 and 100;
>查詢Django分數為75,76,77的同學。
select name ,Django from ExamResult where Django in (75,98,77);
>查詢所有姓王的學生成績。--匹配多個
select * from ExamResult where name like '王%';
--查詢名字為王開頭,兩個字 --匹配一個
select * from er where name like "王_";
>查詢JS分>90,Django分>90的同學。
select id,name from ExamResult where JS>90 and Django >90;
>查找缺考數學的學生的姓名
select name from ExamResult where Database is null;
3.9.7.4 order by
>指定排序的列,排序的列即可是表中的列名,也可以是select 語句后指定的別名。
>select *|field1,field2... from tab_name order by field [Asc|Desc]
>Asc 升序、Desc 降序,其中asc為默認值 ORDER BY 子句應位于SELECT語句的結尾。
>練習:
>對JS成績排序后輸出。
select * from ExamResult order by JS;
>對總分排序按從高到低的順序輸出
select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))
總成績 from ExamResult order by 總成績 desc;
>對姓李的學生成績排序輸出
select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))
總成績 from ExamResult where name like 'a%'
order by 總成績 desc;
3.9.7.5 group by
>group by 分組查詢:
CREATE TABLE order_menu(
id INT PRIMARY KEY auto_increment,
product_name VARCHAR (20),
price FLOAT(6,2),
born_date DATE,
class VARCHAR (20)
);
INSERT INTO order_menu (product_name,price,born_date,class) VALUES
("蘋果",20,20170612,"水果"),
("香蕉",80,20170602,"水果"),
("水壺",120,20170612,"電器"),
("被罩",70,20170612,"床上用品"),
("音響",420,20170612,"電器"),
("床單",55,20170612,"床上用品"),
("草莓",34,20170612,"水果");
>注意,按分組條件分組后每一組只會顯示第一條記錄
>group by字句,其后可以接多個列名,也可以跟having子句,對group by 的結果進行篩選。
>按位置字段篩選
select * from order_menu group by 5;
>練習:對購物表按類名分組后顯示每一組商品的價格總和
select class,SUM(price)from order_menu group by class;
>練習:對購物表按類名分組后顯示每一組商品價格總和超過150的商品
select class,SUM(price)from order_menu group by class HAVING SUM(price)>150;
/*
having 和 where兩者都可以對查詢結果進行進一步的過濾,差別有:
<1>where語句只能用在分組之前的篩選,having可以用在分組之后的篩選;
<2>使用where語句的地方都可以用having進行替換
<3>having中可以用聚合函數,where中就不行。
*/
3.9.7.6 聚合函數:
>先不要管聚合函數要干嘛,先把要求的內容查出來再包上聚合函數即可。(一般和分組查詢配合使用)
>統計表中所有記錄
>COUNT(列名):統計行的個數
>統計一個班級共有多少學生?先查出所有的學生,再用count包上
select count(*) from ExamResult;
>統計JS成績大于70的學生有多少個?
select count(JS) from ExamResult where JS>70;
>統計總分大于280的人數有多少?
select count(name) from ExamResult
where (ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))>280;
>注意:count(*)統計所有行; count(字段)不統計null值.
>SUM(列名):統計滿足條件的行的內容和
>統計一個班級JS總成績?先查出所有的JS成績,再用sum包上
select JS as JS總成績 from ExamResult;
select sum(JS) as JS總成績 from ExamResult;
>統計一個班級各科分別的總成績
select sum(JS) as JS總成績,
sum(Django) as Django總成績,
sum(OpenStack) as OpenStack from ExamResult;
>統計一個班級各科的成績總和
select sum(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)) as 總成績 from ExamResult;
>統計一個班級JS成績平均分
select sum(JS)/count(*) from ExamResult ;
>注意:sum僅對數值起作用,否則會報錯。
>AVG(列名):
>求一個班級JS平均分?先查出所有的JS分,然后用avg包上。
select avg(ifnull(JS,0)) from ExamResult;
>求一個班級總分平均分select avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0))) from ExamResult ;
>Max、Min
>求班級最高分和最低分(數值范圍在統計中特別有用)
select Max((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))
最高分 from ExamResult;
select Min((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)))
最低分 from ExamResult;
>求購物表中單價最高的商品名稱及價格
>SELECT id, MAX(price) FROM order_menu;--id和最高價商品是一個商品嗎?
SELECT MAX(price) FROM order_menu;
>注意:null 和所有的數計算都是null,所以需要用ifnull將null轉換為0!ifnull(JS,0)
>with rollup的使用
3.9.7.7重點:Select from where group by having order by limit
>Mysql在執行sql語句時的執行順序:
>from where select group by having order by
>分析:
select JS as JS成績 from ExamResult where JS成績 >70; ---- 不成功
select JS as JS成績 from ExamResult having JS成績 >90; --- 成功
3.9.7.8limit
SELECT * from ExamResult limit 1;
SELECT * from ExamResult limit 2,5;--跳過前兩條顯示接下來的五條紀錄
SELECT * from ExamResult limit 2,2;
3.9.7.9使用正則表達式查詢
SELECT * FROM employee WHERE emp_name REGEXP '^yu';
SELECT * FROM employee WHERE emp_name REGEXP 'yun$';
SELECT * FROM employee WHERE emp_name REGEXP 'm{2}';//有兩個m
3.10 day47
3.10.1 mysql 多表查詢
>主表//被綁定的這張表叫主表
CREATE TABLE ClassCharger(
id TINYINT PRIMARY KEY auto_increment,
name VARCHAR (20),
age INT ,
is_marriged boolean -- show create table ClassCharger: tinyint(1)
);
INSERT INTO ClassCharger (name,age,is_marriged) VALUES ("冰冰",12,0),("丹丹",14,0),("歪歪",22,0),("姍姍",20,0),("小雨",21,0);
>子表
CREATE TABLE Student(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
charger_id TINYINT, --切記:作為外鍵一定要和關聯主鍵的數據類型保持一致
-- [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id))ENGINE=INNODB;
INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),
("alvin2",4),
("alvin3",1),
("alvin4",3),
("alvin5",1),
("alvin6",3),
("alvin7",2);
或
CREATE TABLE Student(
id INT PRIMARY KEY auto_increment,
name VARCHAR (20),
charger_id TINYINT,
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
);
ALTER TABLE Student ADD CONSTRAINT abc
FOREIGN KEY(charger_id)
REFERENCES classcharger(id);
>增加外鍵
ALTER TABLE Student ADD CONSTRAINT abc
FOREIGN KEY(charger_id)
REFERENCES classcharger(id);
>刪除外鍵
ALTER TABLE Student DROP FOREIGN KEY abc;
3.10.2 級聯刪除與set null:
3.10.2.1 父表上update/delete記錄時,同步 update/delete 子表綁定外鍵的匹配記錄
>foreign key (charger_id) references ClassCharger(id) on delete cascade
3.10.2.2 父表上update / delete時,子表上匹配的記錄設為 null --注意子表上的外鍵列不能為not null
>foreign key (charger_id) references ClassCharger(id) on delete set null
3.10.3 多表查詢:
3.10.3.1 連接查詢
3.10.3.1.1 內連接(交集):inner join -> A inner join B;A,B的順序可顛倒。
>不使用inner join時: select tableA.name, tableB.name FROM day47.tableA,day47.tableB where tableB.tableA_id = tableA.id;
//相當于下:
> SELECT * FROM day47.tableB inner join day47.tableA on tableB.tableA_id = tableA.id;
3.10.3.1.2 外連接:
>左外連接:A left join B //以A表為坐標,匹配不到的保留A 的字段,對應的值為null;
>右外連接:A right join B //以B表為坐標,匹配不到的保留B的字段,對應的值為null;
3.10.3.1.3 全連接:full join;
> select * from tableB full join tableA on tableB.tableA_id = tableA.id; //mysql不支持全外連接
> select * from tableB left join tableA on tableB.tableA_id = tableA.id
union select * from tableB right join tableA on tableB.tableA_id = tableA.id; //使用這種方式實現全外連接
>union: 會去掉相同的記錄
>union all : 會顯示所有的記錄
3.10.3.2 復合查詢和子查詢:
3.10.3.2.1 找出公司所有部門中年齡大于25歲的員工:
>select employee.emp_name, department.dept_id, department.dept_name, employee.age from department, employee where employee.dept_id = department.dept_id and employee.age > 10;
3.10.3.2.2 子查詢
> in :
> select * from employee where employee.dept_id in (select department.dept_id from department);
> 帶比較運算符:
=, !=, >, >=, <, <=, <, >,
> exists 子查詢, 返回True執行()前的語句/False 則不執行()前的語句:
select * from employee where exists (select dept_name from department where dept_id=205);
3.10.3.3 mysql索引
3.10.3.3.1 創建普通索引 -> index/key 索引名(字段名) //其中索引名可以不寫
> index -> create table emp(id int, name varchar(20), index index_name(name));//在where name時會按照索引搜索;
> key -> create table emp(id int, name varchar(20), key index_name(name));//在where name時會按照索引搜索;
3.10.3.3.2 創建唯一索引 unique -> unique index/key 索引名(字段名) //唯一索引的字段不能重復;
3.10.3.3.3 創建全局索引 fulltext -> fulltext index index_name(name)
3.10.3.3.4 創建空間索引 spatial
3.10.3.3.4 創建多列索引 index index_name(name, resume)
3.10.3.3.5 添加索引
> create -> create index index_name on db.tableA(name);
> alter -> alter table tableA add index index_name(name) [asc|desc]
3.10.3.3.6 刪除索引: drop index 索引名 on 表名;
4.python與mysql的交互
4.1 python操作pymysql
4.1.1 連接數據庫
import pymysql
#連接數據庫
# db = pymysql.connect(host,port,user,passwd,db)
db = pymysql.connect("localhost","root","666666","test")
#使用cursor()方法創建一個游標對象
cursor = db.cursor()
#使用execute()方法執行SQL語句
cursor.execute("SELECT * FROM userinfo")
#使用fetall()獲取全部數據
data = cursor.fetchall()
#打印獲取到的數據
print(data)
#關閉游標和數據庫的連接
cursor.close()
db.close()
4.1.2 數據庫增刪改操作 // commit()方法:在數據庫里增、刪、改的時候,必須要進行提交,否則插入的數據不生效。
4.1.2.1 增
import pymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "INSERT INTO userinfo (username,passwd) VALUES('jack','123')"
cursor.execute(sql)
db.commit() #提交數據
cursor.close()
db.close()
4.1.2.2 增
import pymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "INSERT INTO userinfo(username,passwd) VALUES(%s,%s)"
cursor.execute(sql,("bob","123"))
db.commit() #提交數據
cursor.close()
db.close()
4.1.2.3 增加多條
import pymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "INSERT INTO userinfo(username,passwd) VALUES(%s,%s)"
cursor.executemany(sql,[("tom","123"),("alex",'321')])
db.commit() #提交數據
cursor.close()
db.close()
4.1.2.4 查 fetchone():獲取下一行數據,第一次為首行;
import pymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "SELECT * FROM userinfo"
cursor.execute(sql)
res = cursor.fetchone() #第一次執行
print(res)
res = cursor.fetchone() #第二次執行
print(res)
cursor.close()
db.close()
4.1.2.5 查 fetchall() 獲取所有行數據源
import pymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "SELECT * FROM userinfo"
cursor.execute(sql)
res = cursor.fetchall() #第一次執行
print(res)
res = cursor.fetchall() #第二次執行
print(res)
cursor.close()
db.close()
#運行結果
((1, 'frank', '123'), (2, 'rose', '321'), (3, 'jeff', '666'), (5, 'bob', '123'), (8, 'jack', '123'), (10, 'zed', '123'))
()
4.1.2.6 查 fetchmany(4):獲取下4行數據
> cursor = db.cursor(cursor=pymysql.cursors.DictCursor) #在實例化的時候,將屬性cursor設置為pymysql.cursors.DictCursor
> cursor.scroll(1,mode='relative') # 相對當前位置移動,正數為光標向后移動,負數為光標向前移動;1,當前光標向后移動1個位置
cursor.scroll(-1, mode='relative') #表示當前光標向前移動一個位置
cursor.scroll(2,mode='absolute') # 相對絕對位置移動,表示光標移到第二位
第一個值為移動的行數,整數為向下移動,負數為向上移動,mode指定了是相對當前位置移動,還是相對于首行移動
4.1.2.7 改
4.1.2.8 刪
4.1.3 上下文協議:
import pymysql
config={
"host":"127.0.0.1",
"user":"root",
"password":"LBLB1212@@",
"database":"dbforpymysql"
}
db = pymysql.connect(**config)
with db.cursor(cursor=pymysql.cursors.DictCursor) as cursor: #獲取數據庫連接的對象
sql = "SELECT * FROM userinfo"
cursor.execute(sql)
res = cursor.fetchone()
print(res)
cursor.scroll(2,mode='relative')
res = cursor.fetchone()
print(res)
cursor.close()
db.close()
4.2 mysql事務:
4.2.1
>開啟事務: start transaction;
>回滾: rollback;
>提交事務: commit;
>保留點:savepoint;//設置臨時占位符,可以發布和回退,與整個事務回退不同。
rollback to savepoint_name;
4.2.2 pymysql 處理事務:pymysql是基于事務,不需要開啟。
> import pymysql
config = {
"host": "127.0.0.1",
"user": "root",
"password": "666666",
回滾 "db": "day48"
}
conn = pymysql.connect(**config)
cursor = conn.cursor()
try:
sql1 = "insert into lesson54(name, balance) values('bob', 2000)"
sql2 = "update lesson54 set balance=balance-30 where name='bob'"
sql3 = "update lesson54 set balance=balance+30 where name='bob'"
cursor.execute(sql1)
conn.commit()
cursor.execute(sql2)
raise Exception #代碼執行到這里,報異常,回滾到上一次commit的地方
# cursor.execute(sql3)
cursor.close()
conn.commit()
except Exception as e:
conn.rollback()
conn.commit()

浙公網安備 33010602011771號