(承接自oracle数据库的内容)

mysql的基本操作

3306端口

启动mysql数据库:service mysqld start;

重启mysql数据库:systemctl restart mysqld;

查看状态:systemctl status mysqld;

停止mysql服务:systemctl stop mysqld;

启动mysql服务:systemctl start mysqld;

  • oracle数据库中有多个用户,每个用户有多张表
  • mysql数据库只有一个用户(root),有多个数据库,每个数据库下有多张表

登录mysql数据库:mysql -uroot -psyc13140;

或者:mysql -uroot -p;,然后输入密码,prevent peeping

mysql数据库CRUD

what is CRUD: create, retrieve, update, delete

create a database:

创建一个名为db1的数据库:create database mydb1;

创建一个使用utf-8字符集的数据库:create database mydb2 character set utf8;

创建一个带校验规则的mydb3数据库:create database mydb3 character set utf8 collate utf8_general_ci;

查看所有数据库:show databases;

显示创建数据库的语句信息:show create database mydb3;

修改数据库的字符集:alter database mydb1 character set utf8;

删除数据库:drop database mydb1;

mysql数据库表CRUD

由于mysql的层次结构为用户,数据库,表

所以创建数据表需要先选中库:use mydb3;

查看库中的表:show tables;

创建表:create table emp(empno int,ename varchar(20),sal int);

mysql中的数据类型:


查看表创建过程:show create table emp;

查看表的结构:desc emp;

mysql> desc emp;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| empno | int(11)     | YES  |     | NULL    |       |
| ename | varchar(20) | YES  |     | NULL    |       |
| sal   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

重命名表:rename table emp to worker;

添加一个字段:alter table emp add column height double;

修改一个字段:alter table emp modify column height float;

删除一个字段:alter table emp drop column height;

修改表的字符集:alter table emp character set utf8;

删除表:drop table emp;

mysql数据库表数据CRUD

创建表:

create table emp(
	id int,
	name varchar(20),
	sex int,
	birthday date,
	salary double,
	hiredate date,
	resume text
);

插入数据: insert into emp values(1,'daniel',1,'1999-10-19',20000,'2023-10-10','i hope so');

修改数据:update emp set salary=salary+50;

删除数据:delete from emp where name='daniel'

清空表:truncate table emp;delete from emp;

起别名:select id,name as "姓名",salary "月薪",salary*12 年薪 from emp where id=1;

练习:

创建表:

mysql> create table student(
    -> id int,
    -> name varchar(20),
    -> chinese int,
    -> englise int,
    -> math int
    -> );

查询并过滤表中的重复数据:select distinct english from student;

几个查询语句:

limit和offset

select * from article limit 1,3
select * from article limit 3 OFFSET 1

上面两种写法都表示取第2,3,4三条数据

limit后面跟两个参数的时候,第一个数表示要跳过的数量,后一位表示要取的数量,例如

select* from article limit 1,3就是跳过1条数据,从第2条数据开始取,取3条数据,也就是取2,3,4三条数据

limit后面跟一个参数的时候,该参数表示要取的数据的数量

例如select* from article limit 3表示直接取前三条数据

limitoffset组合使用的时候,limit后面只能有一个参数,表示要取的的数量offset表示要跳过的数量

例如select * from article limit 3 offset 1表示跳过1条数据,从第2条数据开始取,取3条数据,也就是取2,3,4三条数据

mysql中的函数

分为3类:时间,日期,时间戳(含有时分秒的sysdate)

mysql> select now() from dual;
+---------------------+
| now()               |
+---------------------+
| 2022-02-12 10:54:39 |
+---------------------+
1 row in set (0.00 sec)

mysql> select CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP from dual;
+--------------+--------------+---------------------+
| CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP   |
+--------------+--------------+---------------------+
| 2022-02-12   | 11:02:04     | 2022-02-12 11:02:04 |
+--------------+--------------+---------------------+
1 row in set (0.00 sec)

mysql> select year(now()),month(now()),day(now()),date(now()) from dual;
+-------------+--------------+------------+-------------+
| year(now()) | month(now()) | day(now()) | date(now()) |
+-------------+--------------+------------+-------------+
|        2022 |            2 |         12 | 2022-02-12  |
+-------------+--------------+------------+-------------+
1 row in set (0.00 sec)

mysql> select date_add(now(),INTERVAL 2 year) from dual;
+---------------------------------+
| date_add(now(),INTERVAL 2 year) |
+---------------------------------+
| 2024-02-12 11:09:01             |
+---------------------------------+
1 row in set (0.00 sec)

mysql> select date_add(now(),INTERVAL -1 day) yesterday,now() today,date_add(now(),INTERVAL +1 day) tomorrow;
+---------------------+---------------------+---------------------+
| yesterday           | today               | tomorrow            |
+---------------------+---------------------+---------------------+
| 2022-02-11 11:11:08 | 2022-02-12 11:11:08 | 2022-02-13 11:11:08 |
+---------------------+---------------------+---------------------+
1 row in set (0.00 sec)

日期函数:

字符串函数:

mysql> select date_format(now(),'%Y-%m-%d') from dual;
+-------------------------------+
| date_format(now(),'%Y-%m-%d') |
+-------------------------------+
| 2022-02-12                    |
+-------------------------------+
1 row in set (0.00 sec)

mysql> select date_format(now(),'%Y-%m-%d %h:%i:%s') from dual;
+----------------------------------------+
| date_format(now(),'%Y-%m-%d %h:%i:%s') |
+----------------------------------------+
| 2022-02-12 11:22:34                    |
+----------------------------------------+
1 row in set (0.00 sec)

mysql> select str_to_date('2018-11-11 8:8:8','%Y-%m-%d %h:%i:%s') from dual;
+-----------------------------------------------------+
| str_to_date('2018-11-11 8:8:8','%Y-%m-%d %h:%i:%s') |
+-----------------------------------------------------+
| 2018-11-11 08:08:08                                 |
+-----------------------------------------------------+
1 row in set (0.00 sec)

数学函数:

mysql> select bin(255) from dual;
+----------+
| bin(255) |
+----------+
| 11111111 |
+----------+
1 row in set (0.00 sec)

mysql> select ceiling(3.14) from dual;
+---------------+
| ceiling(3.14) |
+---------------+
|             4 |
+---------------+
1 row in set (0.00 sec)

mysql> select floor(3.14) from dual;
+-------------+
| floor(3.14) |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)

mysql> select conv(10,8,2) from dual;
+--------------+
| conv(10,8,2) |
+--------------+
| 1000         |
+--------------+
1 row in set (0.00 sec)

mysql> select hex(255) from dual;
+----------+
| hex(255) |
+----------+
| FF       |
+----------+
1 row in set (0.00 sec)

mysql> select rand(now()) from dual;
+--------------------+
| rand(now())        |
+--------------------+
| 0.5498581822494587 |
+--------------------+
1 row in set (0.00 sec)

启动监听:lsnrctl start

多表查询

建表脚本:

create database if not exists scott character set utf8;

use scott;

create table bonus(
  ename VARCHAR(10),
  jod   VARCHAR(10),
  sal   int,
  comm  int
);

create table dept(
  deptno int not null,
  dname VARCHAR(14),
  loc   VARCHAR(13)
);

alter table dept add constraint PK_DEPT primary key(deptno);

create table emp(
  empno int not null,
  ename VARCHAR(10),
  job   VARCHAR(9),
  mgr   int,
  hiredate DATE,
  sal   int,
  comm  int,
  deptno int
);

alter table emp add constraint PK_EMP primary key(EMPNO);
alter table emp add constraint FK_DEPTNO foreign key(DEPTNO) references dept(DEPTNO);

create table salgrade(
  grade int,
  losal int,
  hisal int
);

insert into dept(deptno,dname,loc) values
(10,'ACCOUNTING','NEW YORK'),
(20,'RESEARCH','DALLAS'),
(30,'SALES','CHICAGO'),
(40,'DPERATIONS','BOSTON');

insert into emp(empno,ename,job,mgr,hiredate,sal,comm,deptno) values
(7369,'SMITH','CLERK',7902,'1980-12-17',800,null,20),
(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30),
(7521,'WARD','SALESMAN',7998,'1981-02-21',1250,500,30),
(7688,'JONES','MANAGER',7839,'1981-04-02',2975,null,20),
(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30),
(7698,'BLAKE','MANAGER',7839,'1981-05-01',2880,null,30),
(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,null,10),
(7788,'SCOTT','ANALYST',7566,'1987-05-23',1100,null,20),
(7839,'KING','PRESIDENT',null,'1981-11-17',5000,null,10),
(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30),
(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,null,20),
(7900,'JAMES','CLERK',7698,'1981-12-03',950,null,30),
(7902,'FORD','ANALYST',7566,'1981-12-03',3000,null,20),
(7934,'MILLER','CLERK',7782,'1982-01-23',1300,null,10);

insert into salgrade(grade,losal,hisal) values
(1,700,1200),
(2,1201,1400),
(3,1401,2000),
(4,2001,3000),
(5,3001,9999);

执行sql脚本:

mysql> source /home/daniel/scott.sql;

笛卡尔积:select e.*,d.* from emp e cross join dept d;

内连接:select e.*,d.* from emp e inner join dept d on e.deptno=d.deptno;,只返回满足连接条件的数据

左外连接,左边有值就显示:select e.*,d.* from emp e left outer join dept d on e.deptno=d.deptno;

MySQL left join 与 join 有所不同。 LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据


对于上面两张表,使用left outer join:

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程    | 10             |
| 2           | 菜鸟教程    | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| 5           | FK              | NULL           |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

以上实例中使用了 LEFT JOIN,该语句会读取左边的数据表 runoob_tbl 的所有选取的字段数据,即便在右侧表 tcount_tbl中 没有对应的 runoob_author 字段值。

右外连接与之同理,右边有值就显示:select e.*,d.* from emp e right outer join dept d on e.deptno=d.deptno;

sql99中外连接取值与关系表达式=左右位置无关。取值跟from后表的书写顺序有关

全外连接:select e.*,d.* from emp e full outer join dept d on e.deptno=d.deptno;

查询每个部门员工数:select d.deptno,d.dname,count(e.deptno) from dept d,emp e where d.deptno=e.deptno group by d.deptno,d.dname;

对于40号部门无法正常显示,使用左外连接:select d.deptno,d.dname,count(e.deptno) from dept d left outer join emp e on d.deptno=e.deptno group by d.deptno,d.dname;

修改数据:update dept set dname='OPERATIONS' where deptno=40;

自连接:

查询员工的老板:

select concat(e.ename,'\'s boss is ',ifnull(b.ename,'himself')) info
from emp e left outer join emp b
on e.mgr=b.empno;

约束


删除主键约束:alter table table_name drop primary key;

约束举例:

mysql> create table myclass(
    -> id INT(11) primary key auto_increment,
    -> name varchar(20) unique
    -> );
Query OK, 0 rows affected (0.21 sec)

mysql> create table student(
    -> id INT(11) primary key auto_increment,
    -> name varchar(20) unique,
    -> passwd varchar(15) not null,
    -> classid INT(11),
    -> constraint stu_classid_FK foreign key(classid) references myclass(id)
    -> );
Query OK, 0 rows affected (0.01 sec)

查看字符集:show variables like 'character%';


i18n=internationalization

C程序连接mysql数据库

manual文档:https://dev.mysql/doc/refman/8.0/en/

重点关注:

Connectors and APIs
Data Types
Functions and Operators
SQL Statements
Language Structure
MySQL Programs

等章节

安装mysqlclient:sudo apt-get install libmysqlclient-dev

查找头文件和库的位置:locate mysql.h

头文件和库目录:

daniel@ubuntu:~/project/c/demo$ locate mysql.h
/usr/include/mysql/mysql.h
daniel@ubuntu:~/project/c/demo$ locate libmysqlclient.so
/usr/lib/x86_64-linux-gnu/libmysqlclient.so
/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20
/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20.3.24

测试程序:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <mysql/mysql.h>

#define HOST "192.168.37.131"
#define USER "root"
#define PWD  "syc13140"
#define DB   "scott"

#define error_msg(msg) \
        printf("error:%s: in function %s at line %d, msg:%s\n",__FILE__,__func__,__LINE__,msg);


int main(void ){
        MYSQL* mysql=mysql_init(NULL);
        if(NULL==mysql){
                error_msg("mysql_init failed");
                exit(1);
        }

        mysql=mysql_real_connect(mysql,HOST,USER,PWD,DB,0,NULL,0);
        if(NULL==mysql){
                error_msg("mysql_real_connect() failed");
                exit(1);
        }

        mysql_close(mysql);
        return 0;
}

插入数据:

int main(void ){
        MYSQL* mysql=mysql_init(NULL);
        if(NULL==mysql){
                error_msg("mysql_init() failed");
                exit(1);
        }

        mysql=mysql_real_connect(mysql,HOST,USER,PWD,DB,0,NULL,0);
        if(NULL==mysql){
                error_msg("mysql_real_connect() failed");
                exit(1);
        }

        char query_str[128]="insert into dept values(1,'1name','1loc')";
        int ret=mysql_query(mysql,query_str);
        if(0!=ret){
                error_msg("mysql_query() failed");
                exit(1);
        }

        mysql_close(mysql);
        return 0;
}

makefile编写:

SRC:=$(wildcard *.c)
OBJ:=$(patsubst %.c,%,$(SRC))

LIB:= -l mysqlclient
INC:=-I /usr/include

all:$(OBJ)

%:%.c
        gcc $< -o $@ $(LIB) $(INC)

.PHONY:clean
clean:
        rm -rf $(OBJ)

删除数据:

const char* delstr="delete from dept where deptno=1";
int ret=mysql_query(mysql,delstr);
if(0!=ret){
	error_msg("mysql_query() failed");
	exit(1);
}

更新数据:

const char* update_str="update dept set dname='1NAME',loc='1LOC' where deptno=1";
int ret=mysql_query(mysql,update_str);
if(0!=ret){
	error_msg("mysql_query() failed");
	exit(1);
}

mysql_error()函数使用:

API:

const char* mysql_error(MYSQL* mysql);

使用:

const char* insert_query="insert into dept values(1,'1name','1loc')";
int ret=mysql_query(mysql,insert_query);
if(0!=ret){
	error_msg(mysql_error(mysql));
	exit(1);
}

这条数据已经存在,会造成主键冲突的错误:

daniel@ubuntu:~/project/c/demo$ ./mysql_demo
error:mysql_demo.c: in function main at line 32, msg:Duplicate entry '1' for key 'PRIMARY'

mysql_store_result获取结果集:

客户端处理结果集的方式有两种。一种方式是,通过调用mysql_store_result(),一次性地检索整个结果集。该函数能从服务器获得查询返回的所有行,并将它们保存在客户端。第二种方式是针对客户端的,通过调用mysql_use_result(),对“按行”结果集检索进行初始化处理。该函数能初始化检索结果,但不能从服务器获得任何实际行。
在这两种情况下,均能通过调用mysql_fetch_row()访问行。通过mysql_store_result(),mysql_fetch_row()能够访问以前从服务器获得的行。通过mysql_use_result(),mysql_fetch_row()能够实际地检索来自服务器的行。通过调用mysql_fetch_lengths(),能获得关于各行中数据大小的信息。
完成结果集操作后,请调用mysql_free_result()释放结果集使用的内存。
这两种检索机制是互补的。客户端程序应选择最能满足其要求的方法。实际上,客户端最常使用的是mysql_store_result()。

MYSQL_RES* mysql_store_result(MYSQL* mysql);
MYSQL_ROW mysql_fetch_row(MYSQL_RES* result);
unsigned long *mysql_fetch_lengths(MYSQL_RES* result);

获取结果集并查看其行列数:

int main(void ){
		//获取句柄
        MYSQL* mysql=mysql_init(NULL);
        if(NULL==mysql){
                error_msg("mysql_init failed");
                exit(1);
        }
		//连接到服务器
        mysql=mysql_real_connect(mysql,HOST,USER,PWD,DB,0,NULL,0);
        if(NULL==mysql){
                error_msg("mysql_real_connect failed");
                exit(1);
        }
		//query
        const char* query_str="select * from dept";
        int ret=mysql_query(mysql,query_str);
        if(0!=ret){
                error_msg(mysql_error(mysql));
                exit(1);
        }
		//获取结果集
        MYSQL_RES* res=mysql_store_result(mysql);
        if(NULL==res){
                error_msg(mysql_error(mysql));
                exit(1);
        }
		//查看结果集行列数
        printf("there are %llu rows in the table\n",mysql_num_rows(res));
       	printf("there are %u columns in the table\n", mysql_num_fields(res));
		//关闭连接
        mysql_close(mysql);
       	mysql_free_result(res);
        return 0;
}

遍历结果集:

int field_num = mysql_num_fields(res);
MYSQL_ROW row = NULL;
//每次循环获取一行
while (row = mysql_fetch_row(res)) {
	//遍历每一个字段
	for (int i = 0; i < field_num; ++i) {
		printf("%-10s ", row[i]);
	}
	printf("\n");
}

获取表头数据信息:

//MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result);
int field_num = mysql_num_fields(res);
//获取表头数据
MYSQL_FIELD* field = mysql_fetch_fields(res);
for (int i = 0; i < field_num; ++i) {
	printf("%12s", field[i].name);
}
printf("\n");

简单客户端的实现:

#include <mysql/mysql.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define HOST "192.168.37.131"
#define USER "root"
#define PWD "syc13140"
#define DB "scott"

#define SIZE 1024

#define error_msg(msg) \
	printf("error:%s: in function %s at line %d, msg:%s\n", __FILE__, __func__, __LINE__, msg);

int print_selected_result(MYSQL_RES* res) {
	if (NULL != res) {
		int field_num = mysql_num_fields(res);
		MYSQL_ROW row = NULL;
		//获取表头数据
		MYSQL_FIELD* field = mysql_fetch_fields(res);
		for (int i = 0; i < field_num; ++i) {
			printf("%12s", field[i].name);
		}
		printf("\n");
		//每次循环获取一行
		while (row = mysql_fetch_row(res)) {
			//遍历每一个字段
			for (int i = 0; i < field_num; ++i) {
				printf("%12s", row[i]);
			}
			printf("\n");
		}
		mysql_free_result(res);
	}
	return 0;
}

int main(void) {
	MYSQL* mysql = mysql_init(NULL);
	if (NULL == mysql) {
		error_msg("mysql_init failed");
		exit(1);
	}

	mysql = mysql_real_connect(mysql, HOST, USER, PWD, DB, 0, NULL, 0);
	if (NULL == mysql) {
		error_msg("mysql_real_connect failed");
		exit(1);
	}
	// system("clear");

	//执行sql语句
	char buf[SIZE];
	while (1) {
		memset(buf, 0, SIZE);
		write(STDOUT_FILENO, "mysql> ", strlen("mysql> "));
		//读取sql命令
		int n = read(STDIN_FILENO, buf, SIZE);
		if (1 == n) {
			continue;
		}
		if (strncasecmp("quit", buf, 4) == 0 || strncasecmp("exit", buf, 4) == 0) {
			printf("Bye\n");
			break;
		}
		//查询
		buf[strlen(buf) - 1] = 0;  //;->0
		int ret = mysql_query(mysql, buf);
		if (0 != ret) {
			error_msg(mysql_error(mysql));
			continue;
		}
		//获取结果集
		MYSQL_RES* res = mysql_store_result(mysql);
		if (NULL == res) {
			if (mysql_field_count(mysql) == 0) {  // create, updata, delete
				printf("Query OK, %llu row affected\n", mysql_affected_rows(mysql));
			} else {  // error
				error_msg(mysql_error(mysql));
				continue;
			}
		} else {  // retrieve
			print_selected_result(res);
		}
	}

	mysql_close(mysql);
	return 0;
}

mysql预处理语句

绝大多数情况下,某需求某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行了。
所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements。
预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。

语法:

prepare stmt_name from "preparable_stmt";
execute stmt_name [using @var1_name[,using @var2_name]...];
drop prepare stmt_name;

实例:

mysql> prepare stmt1 from "select sqrt(pow(?,2)+pow(?,2)) as hypotenuse";
Query OK, 0 rows affected (0.00 sec)
Statement prepared

mysql> set @a=3;
Query OK, 0 rows affected (0.00 sec)

mysql> set @b=4;
Query OK, 0 rows affected (0.00 sec)

mysql> execute stmt1 using @a,@b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
1 row in set (0.00 sec)

C语言实现:

int main(void) {
	MYSQL* mysql = mysql_init(NULL);
	mysql = mysql_real_connect(mysql, HOST, USER, PWD, DB, 0, NULL, 0);

	//准备预处理语句
	MYSQL_STMT* stmt = mysql_stmt_init(mysql);
	const char* stmt_str = "select sqrt(pow(?,2)+pow(?,2)) as hypotenuse";
	int ret = mysql_stmt_prepare(stmt, stmt_str, strlen(stmt_str));

	//准备并绑定参数
	int para[2] = {3, 4};
	MYSQL_BIND bind_para[2];
	for (int i = 0; i < 2; ++i) {
		bind_para[i].buffer_type = MYSQL_TYPE_LONG;
		bind_para[i].buffer = (char*)(para + i);
		bind_para[i].is_null = 0;
		bind_para[i].length = 0;
	}
	mysql_stmt_bind_param(stmt, bind_para);
	//执行
	ret = mysql_stmt_execute(stmt);

	//查看影响到的行数
	int affected_rows = mysql_stmt_affected_rows(stmt);
	fprintf(stdout, " total affected rows: %lu\n", (unsigned long)affected_rows);

	mysql_stmt_close(stmt);
	mysql_close(mysql);

	return 0;
}

触发器

在某个表发生更改时自动处理的一系列动作,可以响应以下三种语句:

DELETE
INSERT
UPDATE

因此一个表最多6个触发器,分别位于这三条语句之前和之后

创建触发器:

CREATE TRIGGER newproduct AFTER INSERT ON products
FOR EACH ROW SELECT "Product added";

删除触发器:

DROP TRIGGER newproduct;

使用INSERT触发器实时显示AUTO_INCREMENT后的值:

CREATE TRIGGER neworder AFTER INSERT ON orders
FOR EACH ROW SELECT NEW.order_num;

使用DELETE触发器将被删除的行保存到存档表中:

CREATE TRIGGER deleteorder BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
	INSERT INTO archive_order(order_num,order_date,cust_id)
	VALUES(OLD.order_num,OLD.order_date,OLD.cust_id);
END;

使用UPDATE触发器进行数据检查:

CREATE UPDATE TRIGGER updatevendor BEFORE UPDATE ON vendors
FOR EACH ROW SET NEW.vend_state=Upper(NEW.vend_state);

mysql事务

设置自动提交和手动提交:

set autocommit=0;
set autocommit=1;

C语言实现:

//开启事务并设置为手动提交
int mysql_OperationTran(MYSQL* mysql) {
	if (NULL != mysql) {
		mysql_query(mysql, "start transaction");
		mysql_query(mysql, "set autocommit=0");
		return 0;
	}
	return 1;
}

//手动提交
int mysql_Commit(MYSQL* mysql) {
	if (NULL != mysql) {
		mysql_query(mysql, "commit");
		return 0;
	}
	return 1;
}

更多推荐

MySQL数据库学习笔记