diff --git a/最后两周/C语言同步练习答案.md b/最后两周/C语言同步练习答案.md new file mode 100644 index 0000000..833745e --- /dev/null +++ b/最后两周/C语言同步练习答案.md @@ -0,0 +1,1051 @@ +## ѡṹ + +### ѡṹ-1 + +![image-20250220225958223](https://yp.smallkun.cn/markdown/image-20250220225958223.png!compress) + +```c +#include + +/* +if(){ + (Ϊʱִ) +}else{ + (Ϊʱִ) +} +*/ +int main(void){ + + int x, y, z, t;//ͱ + // 1, 2; + scanf("%d%d%d", &x, &y, &z); + if(x > y){ + t = x; + x = y; + y = t; + }//ʵxyȽ yλ + if(y > z){ + t = y; + y = z; + z = t; + }//ʵyzȽ zλ zΪ + if(x > y){ + t = x; + x = y; + y = t; + } + printf("%d %d %d\n", x, y, z); + + return 0; +} + +``` + +### ѡṹ-2 + +![image-20250220230052521](https://yp.smallkun.cn/markdown/image-20250220230052521.png!compress) + +```c +#include + +int main(void){ + + + int a; + + scanf("%d", &a); + printf("λΪ%d\n", + (a/10==0?1:(a/100==0?2:(a/1000==0?3:(a/10000==0?4:5))))); + printf("%d", a%10); + if(a%100/10 != 0){ + printf("%d", a%100/10); + } + if(a%1000/100 != 0){ + printf("%d", a%1000/100); + } + if(a%10000/1000 != 0){ + printf("%d", a%10000/1000); + } + if(a/10000 != 0){ + printf("%d", a/10000); + } + printf("\n"); + return 0; +} + +``` + +### ѡṹ-3 + +![image-20250220230133563](https://yp.smallkun.cn/markdown/image-20250220230133563.png!compress) + +```c +#include + +int main(void){ + + float a, b, result; + int flag; + printf(":"); + scanf("%f %f", &a, &b); + printf("ҪеIJ(1.ӷ 2.˷ 3.):"); + scanf("%d", &flag); + switch(flag){ + case 1:result = a+b;break; + case 2:result = a*b;break; + case 3:result = a/b;break; + } + printf("Ϊ%f\n", result); + + return 0; +} + +``` + +### ѡṹ-4 + +![image-20250220230626411](https://yp.smallkun.cn/markdown/image-20250220230626411.png!compress) + +```c +#include + +int main(void){ + + int year, month, day, days=0; + + scanf("%d-%d-%d", &year, &month, &day); + days+=day; + //1 3 5 7 8 10 12 + //ǰһ¿ʼ + switch(month-1){ + case 11:days+=30; + case 10:days+=31; + case 9:days+=30; + case 8:days+=31; + case 7:days+=31; + case 6:days+=30; + case 5:days+=31; + case 4:days+=30; + case 3:days+=31; + case 2:days+=28; + case 1:days+=31; + } + if(month>3 && (year%4==0&&year%100!=0 || year%400==0)){ + days++; + } + printf("%d\n", days); + + + return 0; +} +``` + +--- + +## ѭṹ + +### ѭṹ-1 + +![image-20250220230645828](https://yp.smallkun.cn/markdown/image-20250220230645828.png!compress) + +```c +#include + + +/* +1.ַѭ +while((ch=getchar())!='\n') + +2.жַ +ASCALL뷶Χ + +*/ +int main(){ + + char ch; + int l, d, o;//lĸĸ dΪָ oΪַ + l=d=o=0; + while((ch=getchar()) != '\n'){ + if(ch >= 'a' && ch<='z' || ch >= 'A' && ch<='Z' ){ + l++; + }else if(ch >= '0' && ch <= '9'){ + d++; + }else{ + o++; + } + } + printf("ĸ:%d ָ:%d %d\n", l, d, o); + + return 0; +} +``` + +### ѭṹ-2 + +![image-20250220230945704](https://yp.smallkun.cn/markdown/image-20250220230945704.png!compress) + +```c +/* ++öÿһ̨ +for(i=0;i<1000;i++){ + +} +i=0; +while(i<1000){ + + i++; +} +&& || ! +ʽ1&&ʽ2 +ҶΪΪ +· ʽ1Ϊ ʽ2ֱӲ ֱΪ +*/ + +#include + +int main(){ + int i; + for(i=0;i<1000;i++){ + if(i%2==1 && i%3==2 && i%5==4 && i%6==5 && i%7==0){ + printf("̨Ϊ%d\n", i); + break; + } + } + + + + + return 0; +} +``` + +### ѭṹ-3 + +![image-20250220230952843](https://yp.smallkun.cn/markdown/image-20250220230952843.png!compress) + +```c +#include +/* +:i +:j +С:k +*/ + +int main(){ + int i, j , k; + for(i=0;i<=33;i++){ + for(j=0;j<=50;j++){ + for(k=0;k<=200;k+=2){ + if(i+j+k==100 && i*3 + j*2 + k/2 == 100){ + printf(":%-2d :%-2d С:%-2d\n", i, j, k); + } + } + } + } + + + return 0; +} +``` + +### ѭṹ-4 + +![image-20250220231000056](https://yp.smallkun.cn/markdown/image-20250220231000056.png!compress) + +```c +#include + +int main(){ + + int i, s, t;//i, s洢λ,tǽȡλ֮ + for(i=1;i<9999;i++){ + t = i; + while(t > 0){ + s = (t/10==0?1:(t/100==0?2:(t/1000==0?3:4)));//λ + t = i%(int)pow(10, s-1);//ʹģȥλ + if(t*t == i){ + printf("%d:%d\n", t, i); + } + } + } + + + + return 0; +} +``` + +### ѭṹ-5 + +![image-20250220231006104](https://yp.smallkun.cn/markdown/image-20250220231006104.png!compress) + +```c +#include + +int main(){ +/* + int x, n, t=1;//tΪ2ǰҪλ + + scanf("%d", &x); + n = x;//֮ + while(t < x){//жλǷ񳬹ķΧ + n+=t*2; + //ݵǰλжǰһλǷһ + if(n/(t*10) != x/(t*10)){ + n-=(t*10); + } + t*=10;//һλ + } + printf("%d:%d\n", x, n); +*/ + int x, s = 0; + scanf("%d", &x); + while(x){ + s*=10; + s += (x%10+2)%10; + x /= 10; + } + for(;s;s/=10){ + printf("%d", s%10); + } + + return 0; +} +``` + +### ѭṹ-6 + +![image-20250220231012110](https://yp.smallkun.cn/markdown/image-20250220231012110.png!compress) + +```c +#include + +int main(){ + + int i; + for(i=5;i<=100;i++){ + if(i%5==0 || i%7==0){ + printf("%d ", i); + } + } + + return 0; +} +``` + +### ѭṹ-7 + +![image-20250220231022607](https://yp.smallkun.cn/markdown/image-20250220231022607.png!compress) + +```c +#include + +int main(){ + + int month, total = 2, i; + scanf("%d", &month); + + for(i=1;i<=month;i++){ + if(i%3==0){ + total *= 2; + } + printf("%d:%d\n", i, total); + } + + return 0; +} +``` + +### ѭṹ-8 + +![image-20250220231027969](https://yp.smallkun.cn/markdown/image-20250220231027969.png!compress) + +```c +#include + +int main(){ + int i, j, k; + + for(i=0;i<=3;i++){ + for(j=1;j<=5;j++){ + for(k=0;k<=6;k++){ + if(i+j+k==8){ + printf(":%d :%d :%d\n", i, j, k); + } + } + } + } + + return 0; +} +``` + +### ѭṹ-9 + +![image-20250220231034218](https://yp.smallkun.cn/markdown/image-20250220231034218.png!compress) + +```c +#include + +int main(){ + int num, n=2, first = 1; + scanf("%d", &num); + + printf("%d=",num); + while(num > 1){ + if(num%n==0){ + first?printf("%d", n):printf("*%d", n); + first=0; + num/=n; + }else{ + n++; + } + } + + return 0; +} +``` + +### ѭṹ-10 + +![image-20250220231039716](https://yp.smallkun.cn/markdown/image-20250220231039716.png!compress) + +```c +#include + +int main(){ + int x; + while(1){ + scanf("%d", &x); + if(x == 0){ + break; + } + printf("%d:%s\n", x, (x%5==0&&x%7==0?"Yes":"No")); + } + + return 0; +} +``` + +--- + +## + +### -1 + +![image-20250220231426147](https://yp.smallkun.cn/markdown/image-20250220231426147.png!compress) + +```c +#include + +int main(){ + int num[30], i, j; + float result[6]; + for(i=0;i<30;i++){ + num[i] = 2+2*i; + } + + for(i=0;i<30;i+=5){ + result[i/5] = (num[i]+ num[i+1] + num[i+2] + num[i+3] + num[i+4])/5.0; + } + + for(i=0;i<6;i++){ + printf("%.2f ", result[i]); + } + printf("\n"); + + return 0; +} + +``` + +### -2 + +![image-20250220231434409](https://yp.smallkun.cn/markdown/image-20250220231434409.png!compress) + +```c +#include + +int fib(int n){ + if(n== 0 || n==1){ + return 1; + } + return fib(n-1) + fib(n-2); +} + +int main(){ + int num[15], i; + + for(i=0;i<15;i++){ + num[i] = fib(i); + } + + for(i=0;i<15;i++){ + printf("%d ", num[i]); + } + printf("\n"); + + return 0; +} + +/* +int main(){ + int num[15] = {1, 1}, i; + + for(i=2;i<15;i++){ + num[i] = num[i-1] + num[i-2]; + } + for(i=0;i<15;i++){ + printf("%d ", num[i]); + } + printf("\n"); + + return 0; +} +*/ +``` + +### -3 + +![image-20250220231441384](https://yp.smallkun.cn/markdown/image-20250220231441384.png!compress) + +```c +#include +#include + +int main(){ + char a[200], b[200];//ַȡַab + char *p, *q;//ָ ֱ洢ַaַb׵ַ + + gets(a); + gets(b);//ӿ̨ȡ + if(strlen(b) > 5){ + b[5] = '\0'; + }//жַǷ5 5 򽫵Ԫظijɽ + p = a;//pָa׵ַ + q = b;//qָb׵ַ + while(*p != '\0'){//ҵaλõĵַ + p++; + } + //bĵһԪؿʼֵa + while(*q != '\0'){ + *p++ = *q++; + } + *p = '\0';//ǽ + printf("a=%s\n", a); + printf("b=%s\n", b); + + + return 0; +} +``` + +### -4 + +![image-20250220231447834](https://yp.smallkun.cn/markdown/image-20250220231447834.png!compress) + +```c +#include +#include +#include + +int main(){ + int num[10], i; + srand((unsigned)time(NULL)); + + for(i=0;i<10;i++){ + num[i] = rand()%101; + printf("%d ", num[i]); + } + printf("\n"); + + return 0; +} + +``` + +### -5 + +![image-20250220231704799](https://yp.smallkun.cn/markdown/image-20250220231704799.png!compress) + +```c +#include +#include +#include +#include //涨˻͵ֵСֵ + +int main(){ + int num[3][4], i, j, min=INT_MAX, i_index, j_index; + srand((unsigned)time(NULL)); + + for(i=0;i<3;i++){ + for(j=0;j<4;j++){ + num[i][j] = rand()%101; + printf("%2d ", num[i][j]); + if(num[i][j] < min){ + min = num[i][j]; + i_index = i; + j_index = j; + } + } + printf("\n"); + } + printf("min=%d i=%d j=%d\n", min, i_index, j_index); + return 0; +} + +``` + +--- + +## + +### -1 + +![image-20250227231121624](https://yp.smallkun.cn/markdown/image-20250227231121624.png!compress) + +```c +#include +#include +#include + +/* +1 2 3 |6 +4 5 6 |15 +7 8 9 |24 +------------- +12 15 18 +*/ +void getSum(int array[100][100], int n, int m){ + int i, j, sum; + for(i=0;i + +void change(char *p){ + //alex apple + *p++ -= 32;//a-> -32 ->A + while(*p != '#'){ + if(*(p-1) == ' '){ + *p -= 32; + } + p++; + } + *p = '\0'; +} + +int main(){ + char str[1024]; + + gets(str);//ȡһַ سж + change(str); + puts(str); + + + return 0; +} + +``` + + + +### -3 + +![image-20250227231154429](https://yp.smallkun.cn/markdown/image-20250227231154429.png!compress) + +```c +#include + +//ݴη +int power(int n){ + int s = 1, i; + for(i=1;i<=n;i++){ + s *= 2; + } + return s; +} +//׳ +int factorial(int n){ + int s = 1, i; + for(i=1;i<=n;i++){//1~n + s*=i; + } + return s; +} + +int main(){ + int n, i, s = 0; + scanf("%d", &n); + for(i=1;i<=n;i++){ + s += power(i) * factorial(i); + } + printf("%d\n", s); + + return 0; +} + +``` + + + +## ָ + +### ָ-1 + +![image-20250227231209008](https://yp.smallkun.cn/markdown/image-20250227231209008.png!compress) + +```c +#include + +int main(){ + int a[10], b[10]; + int i; + int *p, *q; + + for(i=0, p=a;i<10;i++){ + scanf("%d", p++); + } + for(i=0, p=a, q=b;i<10;i++){ + if(*p%2==0){ + *q++=*p; + } + p++; + } + for(i=0, p=b;i +/* +1 2 3 4 5 6 7 8 9 10 +1 3 4 5 6 7 8 9 10 +*/ +int main(){ + int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int n = 10; + int i; + int *p, *q; + p = a+1; + q = a+2; + for(i=0;i<8;i++){//ѭĴ + *p++ = *q++; + } + n--; + for(i=0;i + +int main(){ + char str[] = "AbcDEfg"; + char *p = str; + + while(*p != '\0'){ + if(*p >= 'a' && *p <= 'z'){ + *p -= 32; + }else{ + *p += 32; + } + p++; + } + puts(str); + + return 0; +} + +``` + + + +### ָ-4 + +![image-20250227231243197](https://yp.smallkun.cn/markdown/image-20250227231243197.png!compress) + +```c +#include +#include + +int main(){ + char str[5][20]; + char (*p)[20], (*max)[20];// (*)[];ָ + int i; + for(i=0, p =str;i<5;i++){ + scanf("%s", p++); + } + max = p; + + for(i=1, p =str+1;i<5;i++){ + if(strcmp(*p, *max)){ + max = p; + } + p++; + } + printf("max = %s\n", max); + + return 0; +} + +``` + + + +## Ԥ + +### Ԥ-1 + +![image-20250227231302316](https://yp.smallkun.cn/markdown/image-20250227231302316.png!compress) + +```c +#include +#define MAXD(x, y) (x>y?x:y) + +int main(){ + int a, b; + scanf("%d %d", &a, &b); + //(1>2?1:2) MAXD滻Ŀ + printf("%d \n", MAXD(a, b)); + + return 0; +} +``` + +### Ԥ-2 + +![image-20250227231314793](https://yp.smallkun.cn/markdown/image-20250227231314793.png!compress) +```c +#include +#define f(n) (n%5==0 && n%7==0?"ܱ\n":"ܱ\n") +int main(){ + //#define ָ нв滻ɴ + int num; + scanf("%d", &num); + + puts(f(num)); + + return 0; +} +``` + + +### Ԥ-3 + +![image-20250227231325297](https://yp.smallkun.cn/markdown/image-20250227231325297.png!compress) + +```c +#include + +#define CHANGE 0 //1ӡ 0 +//! Ctrl + .ע +int main(){ + char str[100], i=0; + scanf("%s", str); +#if CHANGE + while(str[i] != '\0'){ + if(str[i] >= 'a' && str[i] <= 'y' || str[i] >= 'A' && str[i] <= 'Y' ){ + str[i]++; + }else if(str[i] == 'z' || str[i] == 'Z'){ + str[i]-=25; + } + i++; + } +#endif + puts(str); + + return 0; +} +``` + +## ṹ + +### ṹ-1 + +![image-20250227231339018](https://yp.smallkun.cn/markdown/image-20250227231339018.png!compress) +```c +#include + +typedef struct student{ + int num; + char name[20]; + float socre[3]; +}student; +//student Ϊһ +//дtypedefṹΪ struct student + +void output(student stuList[5]){ + int i; + + for(i=0;i<5;i++){ + printf("%d\t%s\t%f\t%f\t%f\n", stuList[i].num, stuList[i].name, stuList[i].socre[0], + stuList[i].socre[1], stuList[i].socre[2]); + } +} +int main(){ + student stuList[5];//һṹ5ṹ + int i; + for(i=0;i<5;i++){ + scanf("%d %s %f %f %f", &stuList[i].num, stuList[i].name, &stuList[i].socre[0], + &stuList[i].socre[1], &stuList[i].socre[2]); + } + output(stuList); + return 0; +} +``` + + +### ṹ-2 + +![image-20250227231421233](https://yp.smallkun.cn/markdown/image-20250227231421233.png!compress) + +```c +#include + +typedef struct student{ + int num; + char name[20]; + float socre[3]; +}student; +//student Ϊһ +//дtypedefṹΪ struct student + +void output(student stuList[5]){ + int i; + + for(i=0;i<5;i++){ + printf("%d\t%s\t%f\t%f\t%f\n", stuList[i].num, stuList[i].name, stuList[i].socre[0], + stuList[i].socre[1], stuList[i].socre[2]); + } +} + +void input(student stuList[5]){ + int i; + for(i=0;i<5;i++){ + scanf("%d %s %f %f %f", &stuList[i].num, stuList[i].name, &stuList[i].socre[0], + &stuList[i].socre[1], &stuList[i].socre[2]); + } +} +int main(){ + student stuList[5];//һṹ5ṹ + + input(stuList); + output(stuList); + return 0; +} +``` + +### ṹ-3 + +![image-20250227231434183](https://yp.smallkun.cn/markdown/image-20250227231434183.png!compress) +```c +#include +typedef struct score{ + float medScore; + float endScore; +}score; + +int main(){ + score s; + scanf("%f %f", &s.medScore, &s.endScore); + + printf("avg=%.2f\n", (s.medScore + s.endScore)/2); + return 0; +} +``` + + +## ļ + +### ļ-1 + +![image-20250227231459946](https://yp.smallkun.cn/markdown/image-20250227231459946.png!compress) + + + + + +### ļ-2 + +![image-20250227231509693](https://yp.smallkun.cn/markdown/image-20250227231509693.png!compress) + + + +### ļ-3 + +![image-20250227231516025](https://yp.smallkun.cn/markdown/image-20250227231516025.png!compress) + + + diff --git a/最后两周/C语言基础进阶合集版编程题.md b/最后两周/C语言基础进阶合集版编程题.md new file mode 100644 index 0000000..e69de29 diff --git a/最后两周/C语言基础进阶合集版编程题.pdf b/最后两周/C语言基础进阶合集版编程题.pdf new file mode 100644 index 0000000..c734591 Binary files /dev/null and b/最后两周/C语言基础进阶合集版编程题.pdf differ diff --git a/最后两周/MySQL数据库操作综合练习题答案.md b/最后两周/MySQL数据库操作综合练习题答案.md new file mode 100644 index 0000000..4a69594 --- /dev/null +++ b/最后两周/MySQL数据库操作综合练习题答案.md @@ -0,0 +1,651 @@ +### 练习一 + +![image-20250315225248590](https://yp.smallkun.cn/markdown/image-20250315225248590.png!compress) + +```sql +#(1)创建数据库 +CREATE DATABASE test04_Market DEFAULT CHARACTER SET utf8; +USE test04_Market; +#(2)创建数据表 +CREATE TABLE customers( + c_num INT(11) PRIMARY KEY AUTO_INCREMENT, + c_name VARCHAR(50), + c_contact VARCHAR(50), + c_city VARCHAR(50), + c_birth DATETIME NOT NULL +); +#(3)更改字段的位置 +#AFTER/BEFORE 字段名 设置位置在指定字段前/后 +ALTER TABLE 表名 MODIFY 字段名 数据类型 AFTER/BEFORE 字段名; +ALTER TABLE customers MODIFY c_contact VARCHAR(50) AFTER c_birth; +#(4)更改字段的数据类型 +ALTER TABLE customers MODIFY c_name VARCHAR(70); +#(5)更改字段名 +ALTER TABLE customers CHANGE c_contact c_phone VARCHAR(50); +#(6)添加字段 +ALTER TABLE customers ADD c_gender CHAR(1); +#(7)更改表名 +ALTER TABLE customers RENAME TO customers_info; +#(8)删除字段 +ALTER TABLE customers_info DROP c_city; +``` + +![image-20250315225304324](https://yp.smallkun.cn/markdown/image-20250315225304324.png!compress) + +```sql +#(1)创建表时 添加外键约束并指定外键约束名称 +CREATE TABLE orders( + o_num INT(11) PRIMARY KEY AUTO_INCREMENT, + o_date DATE, + c_id INT(11), + CONSTRAINT fk_cid FOREIGN KEY(c_id) REFERENCES customers_info(c_num) +); +#(2) +#删除指定外键 +ALTER TABLE orders DROP FOREIGN KEY orders_ibfk_1; +#删除指定表 +DROP TABLE orders; +``` + +--- + +### 练习二 + +![image-20250315225318753](https://yp.smallkun.cn/markdown/image-20250315225318753.png!compress) + +![image-20250315225328264](https://yp.smallkun.cn/markdown/image-20250315225328264.png!compress) + +```sql +#(1)创建表、插入记录 +CREATE TABLE pet( + `name` VARCHAR(20) NOT NULL COMMENT '宠物名称', + `owner` VARCHAR(20) COMMENT '宠物主人', + species VARCHAR(20) NOT NULL COMMENT '种类', + sex CHAR(1) NOT NULL COMMENT '性别', + birth YEAR NOT NULL COMMENT '出生日期', + death YEAR COMMENT '死亡日期' +); +INSERT INTO pet() +VALUES +('Fluffy', 'Harold', 'cat', 'f', 2003, 2010), +('Claws', 'Gwen', 'cat', 'm', 2004,NULL ), +('Buffy', NULL, 'dog', 'f', 2009, NULL), +('Fang', 'Benny', 'dog', 'm', 2000, NULL), +('Bowser', 'Diane', 'dog', 'm', 2003, 2009), +('Chirpy', NULL, 'bird', 'f', 2008, NULL); +#(2)更新记录 +UPDATE pet +SET `owner` = 'Kevin' +WHERE `name` = 'Fang'; +#(3) +UPDATE pet +SET `owner` = 'Kevin' +WHERE `owner` IS NULL; +#(4) +DELETE FROM pet +WHERE death IS NOT NULL; +#(5) +TRUNCATE pet; +``` + +--- + +### 练习三 + +![image-20250315225417117](https://yp.smallkun.cn/markdown/image-20250315225417117.png!compress) + +![image-20250315225431297](https://yp.smallkun.cn/markdown/image-20250315225431297.png!compress) + +```sql +#1.创建数据库 +CREATE DATABASE test_compay DEFAULT CHARACTER SET utf8; + +#2.创建表 +CREATE TABLE department( + depid INT PRIMARY KEY AUTO_INCREMENT, + depname VARCHAR(20) NOT NULL, + deinfo VARCHAR(50) +); +CREATE TABLE employee( + empid INT PRIMARY KEY AUTO_INCREMENT, + `name` VARCHAR(20) NOT NULL, + sex CHAR(1) NOT NULL DEFAULT '男', + title VARCHAR(20) NOT NULL, + birthday DATE NOT NULL, + depid INT, + CONSTRAINT fk_eid_did FOREIGN KEY(depid) REFERENCES department(depid) +); +CREATE TABLE salary( + empid INT, + basesalary DECIMAL(10, 2), + titleSalary DECIMAL(10, 2), + decuction DECIMAL(10, 2) +); +#3添加外键并设置级联更新、级联删除 +ALTER TABLE salary ADD CONSTRAINT fk_sal_eid FOREIGN KEY(empid) +REFERENCES employee(empid) ON UPDATE CASCADE ON DELETE CASCADE; +#4插入记录 +INSERT INTO department (depid, depname, deinfo) +VALUES +(111, '生产部', NULL), +(222, '销售部', NULL), +(333, '人事部', NULL), +(444, '财务部', '负责公司财务管理'), +(555, '技术部', '负责技术研发与支持'), +(666, '市场部', '负责市场推广与品牌建设'), +(777, '客服部', '负责客户服务与支持'), +(888, '采购部', '负责公司物资采购'), +(999, '法务部', '负责公司法律事务'), +(1010, '行政部', '负责公司日常行政管理'), +(1011, '研发部', '负责新产品研发'), +(1012, '培训部', '负责员工培训与发展'); + +INSERT INTO employee (empid, name, sex, title, birthday, depid) +VALUES +(1001, '张三', '男', '高级工程师', '1975-1-1', 111), +(1002, '李四', '女', '助工', '1985-1-1', 111), +(1003, '王五', '男', '工程师', '1978-11-11', 222), +(1004, '赵六', '男', '工程师', '1999-1-1', 222), +(1005, '陈七', '女', '会计师', '1980-5-15', 444), +(1006, '刘八', '男', '软件工程师', '1990-8-20', 555), +(1007, '孙九', '女', '市场经理', '1985-12-25', 666), +(1008, '周十', '男', '客服专员', '1992-3-10', 777), +(1009, '吴十一', '女', '采购经理', '1988-7-22', 888), +(1010, '郑十二', '男', '法务顾问', '1983-9-30', 999), +(1011, '王十三', '女', '行政助理', '1995-4-18', 1010), +(1012, '李十四', '男', '研发工程师', '1991-11-5', 1011), +(1013, '赵十五', '女', '培训讲师', '1987-6-12', 1012), +(1014, '孙十六', '男', '技术支持', '1993-2-14', 555), +(1015, '杨十七', '女', '销售代表', '1994-8-8', 222); + +INSERT INTO salary (empid, basesalary, titleSalary, decuction) +VALUES +(1001, 2200, 1100, 200), +(1002, 1200, 200, NULL), +(1003, 2900, 700, 200), +(1004, 1950, 700, 150), +(1005, 2500, 800, 100), +(1006, 3000, 1200, 250), +(1007, 2800, 1000, 200), +(1008, 1800, 300, 50), +(1009, 3200, 900, 300), +(1010, 3500, 1000, 400), +(1011, 2000, 400, 100), +(1012, 3100, 1100, 200), +(1013, 2700, 800, 150), +(1014, 2300, 700, 100), +(1015, 2600, 600, 200); +``` + +![image-20250315225441802](https://yp.smallkun.cn/markdown/image-20250315225441802.png!compress) + +```sql +#5 +SELECT e.empid, e.`name`, e.title, d.depname, s.basesalary + s.titleSalary, s.basesalary + s.titleSalary-IFNULL(s.decuction, 0) +FROM employee e, department d, salary s +WHERE e.depid = d.depid AND e.empid = s.empid; +#6 +SELECT e.`name`, s.basesalary +FROM employee e, department d, salary s +WHERE e.depid = d.depid AND e.empid = s.empid AND d.depname = '销售部'; +#7 +SELECT * +FROM employee e +WHERe e.`name` LIKE '张%' AND TIMESTAMPDIFF(YEAR,e.birthday, NOW()) < 40; +#8 +SELECT e.`name`, s.basesalary, s.titleSalary +FROM employee e, salary s +WHERE e.sex = '男' AND e.empid AND s.empid; +#9 +SELECT e.`name`, e.title, d.depname +FROM employee e, department d, salary s +WHERE e.depid = d.depid AND e.empid = s.empid AND s.basesalary < 2000; +#10 +SELECT COUNT(*) +FROM employee; +#11 +SELECT COUNT(*) +FROM department d; +#12 +SELECT AVG(s.basesalary + s.titleSalary), MAX(s.basesalary + s.titleSalary), MIN(s.basesalary + s.titleSalary) +FROM employee e, salary s +WHERE e.empid = s.empid; +#13 +SELECT d.depname, AVG(s.basesalary + s.titleSalary) +FROM employee e, salary s, department d +WHERE e.empid = s.empid AND e.depid = d.depid +GROUP BY d.depid; +#14 +SELECT d.depname, AVG(s.basesalary + s.titleSalary) avg +FROM employee e, salary s, department d +WHERE e.empid = s.empid AND e.depid = d.depid +GROUP BY d.depid +HAVING avg<2000; +#15 +SELECT e.empid, e.`name`, s.basesalary, s.titleSalary, s.decuction +FROM employee e, salary s, department d +WHERE e.empid = s.empid AND e.depid = d.depid +ORDER BY s.titleSalary, s.basesalary; +#16 +SELECT e.empid, e.`name`, e.birthday, + IF(YEAR(e.birthday) < 1980, '老年', + IF(YEAR(e.birthday)< 1990, '中年', '青壮年')) +FROM employee e; +#17 +SELECT e.*, depname +FROM employee e, department d +WHERE e.depid = d.depid; +#18 +SELECT d.*, e.* +FROM employee e, department d +WHERE e.depid = d.depid; +#19 +SELECT * +FROM employee e +WHERE e.title LIKE '%工程师%' AND e.sex = '男'; +#20 +SELECT d.depname, e.sex, COUNT(*), AVG(s.basesalary) +FROM employee e, department d, salary s +WHERE e.depid = d.depid AND e.empid = s.empid +GROUP BY d.depid, e.sex; +``` + + + +--- + +### 练习四 + +![image-20250315225803115](https://yp.smallkun.cn/markdown/image-20250315225803115.png!compress) + +![image-20250315225818026](https://yp.smallkun.cn/markdown/image-20250315225818026.png!compress) + +```sql +#1 +CREATE DATABASE test_school DEFAULT CHARACTER SET 'UTF8'; +#2 +DROP TABLE department; +CREATE TABLE department( + depNo INT(10) PRIMARY KEY COMMENT '部门号', + depName VARCHAR(50) NOT NULL COMMENT '部门名称', + depNote VARCHAR(20) COMMENT '部门备注' +); +CREATE TABLE teacher( + number INT PRIMARY KEY COMMENT '教工号', + `name` VARCHAR(30) NOT NULL COMMENT '姓名', + sex VARCHAR(4) COMMENT '性别', + birth DATE COMMENT '出生日期', + depNo INT COMMENT '部门号', + salary FLOAT COMMENT '工资', + address VARCHAR(100) COMMENT '家庭住址' +); +INSERT INTO department() +VALUES +(601, '软件技术系', '软件技术等专业'), +(602, '网络技术系', '多媒体技术等专业'), +(603, '艺术设计系', '广告艺术设计等专业'), +(604, '管理工程系', '连锁经营管理等专业'); + +INSERT INTO teacher() +VALUES +(2001, 'Tom', '女', '1970-01-10', 602, 4500, '四川省绵阳市'), +(2002, 'Lucy', '男', '1983-12-18', 601, 2500, '北京市昌平区'), +(2003, 'Mike', '男', '1990-06-01', 604, 1500, '重庆市渝中区'), +(2004, 'James', '女', '1980-10-20', 602, 3500, '四川省成都市'), +(2005, 'Jack', '男', '1975-05-30', 603, 1200, '重庆市南岸区'); +``` + +![image-20250315225829272](https://yp.smallkun.cn/markdown/image-20250315225829272.png!compress) + +```sql +#4 +SELECT * +FROM teacher; +#5 +SELECT t.number '教工号', d.depName '部门名称' +FROM teacher t, department d +WHERE t.depNo = d.depNo AND t.address LIKE '%北京%'; +#6 +SELECT t.number, t.`name` +FROM teacher t +ORDER BY t.salary DESC +LIMIT 1; +#7 +SELECT t.number, t.`name` +FROM teacher t +WHERE t.salary BETWEEN 2500 AND 4000; +#8 +SELECT t.`name`, t.sex, t.salary +FROM teacher t, department d +WHERE t.depNo = d.depNo AND d.depName = '网络技术系'; +``` + +--- + +### 练习五 + +![image-20250315230015174](https://yp.smallkun.cn/markdown/image-20250315230015174.png!compress) + +```sql +-- 创建数据库并设置字符集为 utf8mb4 +CREATE DATABASE test_student CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE test_student; + +-- 创建表 Classes +CREATE TABLE Classes ( + 专业 VARCHAR(50), + 班级 VARCHAR(50), + 姓名 VARCHAR(50), + 性别 VARCHAR(10), + 座位 INT +); + +-- 向表 Classes 插入数据 +INSERT INTO Classes (专业, 班级, 姓名, 性别, 座位) VALUES +('计算机网络', '1班', '张三', '男', 8), +('软件工程', '2班', '李四', '男', 12), +('计算机维护', '1班', '王五', '男', 9), +('计算机网络', '2班', 'LILY', '女', 15), +('软件工程', '1班', '小强', '男', 20), +('计算机维护', '1班', 'CoCo', '女', 18); + +-- 创建表 Score +CREATE TABLE Score ( + 姓名 VARCHAR(50), + 英语 INT, + 数学 INT, + 语文 INT +); + +-- 向表 Score 插入数据 +INSERT INTO Score (姓名, 英语, 数学, 语文) VALUES +('张三', 65, 75, 98), +('李四', 87, 45, 86), +('王五', 98, 85, 65), +('LILY', 75, 86, 87), +('小强', 85, 60, 58), +('CoCo', 96, 87, 70); + +-- 创建表 Records +CREATE TABLE Records ( + 姓名 VARCHAR(50), + 记录 VARCHAR(50) +); + +-- 向表 Records 插入数据 +INSERT INTO Records (姓名, 记录) VALUES +('小强', '迟到'), +('小强', '事假'), +('李四', '旷课'), +('李四', '旷课'), +('李四', '迟到'), +('CoCo', '病假'), +('LILY', '事假'); +``` + +![image-20250315230025538](https://yp.smallkun.cn/markdown/image-20250315230025538.png!compress) + +```sql +#3 +UPDATE score s +SET s.`语文` = 88 +WHERE s.`姓名` = '张三'; + +#4 +SELECT AVG(s.`英语`), AVG(s.`数学`), AVG(s.`语文`) +FROM classes c, score s +WHERE c.`姓名` = s.`姓名` AND c.`班级` = 1 AND c.`专业` = '计算机维护'; + +#5 +SELECT * +FROM score s +WHERE s.`数学` < 60 OR s.`英语` < 60 OR s.`语文` < 60; + +#6 +SELECT * +FROM score s +WHERE s.`姓名` IN ( + SELECT r.`姓名` + FROM records r + GROUP BY r.`姓名` + HAVING COUNT(*) > 2 +); +``` + +--- + +### 练习六 + +![image-20250315230057816](https://yp.smallkun.cn/markdown/image-20250315230057816.png!compress) + +```sql +-- 创建数据库 test_xuankedb 并设置字符集为 utf8mb4 +CREATE DATABASE test_xuankedb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE test_xuankedb; + +-- 创建学生表 Student +CREATE TABLE Student ( + Sn0 VARCHAR(20) PRIMARY KEY, -- 学号,主键 + Sname VARCHAR(50), -- 姓名 + Ssex VARCHAR(10), -- 性别 + Sage INT, -- 年龄 + Sdept VARCHAR(50) -- 所在系 +); + +-- 创建课程表 Course +CREATE TABLE Course ( + Cn0 VARCHAR(20) PRIMARY KEY, -- 课程号,主键 + Cname VARCHAR(100), -- 课程名 + Cpn0 VARCHAR(20), -- 选修课号 + Ccredit INT -- 学分 +); + +-- 创建成绩表 SG +CREATE TABLE SG ( + Sn0 VARCHAR(20), -- 学号 + Cn0 VARCHAR(20), -- 课程号 + Grade INT, -- 成绩 + PRIMARY KEY (Sn0, Cn0), -- 复合主键 (学号, 课程号) + FOREIGN KEY (Sn0) REFERENCES Student(Sn0), -- 外键,引用 Student 表 + FOREIGN KEY (Cn0) REFERENCES Course(Cn0) -- 外键,引用 Course 表 +); + +INSERT INTO Student (Sno, Sname, Ssex, Sage, Sdept, Scome) VALUES +('05001', '张三', '男', 20, '计算机系', '2021-09-01'), +('05002', '李四', '女', 21, '数学系', '2021-09-01'), +('05003', '王五', '男', 22, '计算机系', '2021-09-01'), +('05004', '李洋', '男', 19, '物理系', '2021-09-01'), +('05019', '赵六', '女', 20, '计算机系', '2021-09-01'); + +INSERT INTO Course (Cno, Cname, Cpno, Ccredit) VALUES +('1', '数据库', NULL, 4), +('2', '数学', NULL, 3), +('3', '物理', NULL, 3), +('4', '操作系统', '1', 4); + +INSERT INTO SG (Sno, Cno, Grade) VALUES +('05001', '1', 85), +('05001', '2', 90), +('05002', '1', 78), +('05002', '3', 88), +('05003', '1', 92), +('05003', '4', 76), +('05004', '3', 95), +('05019', '1', 80), +('05019', '4', 85); +``` + +--- + +### 练习七 + +![image-20250315230113710](https://yp.smallkun.cn/markdown/image-20250315230113710.png!compress) + +![image-20250315230128412](https://yp.smallkun.cn/markdown/image-20250315230128412.png!compress) + +```sql +-- 创建数据库 test_library 并设置字符集为 utf8mb4 +CREATE DATABASE test_library CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE test_library; + +-- 创建表 press(出版社) +CREATE TABLE press ( + pressid INT PRIMARY KEY, -- 出版社编号,主键 + pressname VARCHAR(100), -- 出版社名称 + address VARCHAR(100) -- 出版社地址 +); + +-- 创建表 sort(种类) +CREATE TABLE sort ( + sortno INT PRIMARY KEY, -- 种类编号,主键 + scount INT, -- 数量 + describes VARCHAR(100) -- 描述 +); + +-- 创建表 book(图书) +CREATE TABLE book ( + bid INT PRIMARY KEY, -- 图书编号,主键 + bname VARCHAR(100), -- 图书名称 + bsortno INT, -- 种类编号 + pressid INT, -- 出版社编号 + FOREIGN KEY (bsortno) REFERENCES sort(sortno), -- 外键,引用 sort 表 + FOREIGN KEY (pressid) REFERENCES press(pressid) -- 外键,引用 press 表 +); + +-- 向 press 表插入数据 +INSERT INTO press (pressid, pressname, address) VALUES +(100, '外研社', '上海'), +(101, '北大出版社', '北京'), +(102, '教育出版社', '北京'); + +-- 向 sort 表插入数据 +INSERT INTO sort (sortno, scount, describes) VALUES +(11, 50, '小说'), +(12, 100, '科幻'), +(13, 100, '神话'); + +-- 向 book 表插入数据 +INSERT INTO book (bid, bname, bsortno, pressid) VALUES +(1, '红与黑', 11, 100), +(2, '幻城', 12, 102), +(3, '希腊神话', 13, 102); + +#5 +SELECT b.* +FROM book b, press p +WHERE p.pressid = b.pressid AND p.pressid = 100; + +#6 +SELECT b.* +FROM book b, press p +WHERE p.pressid = b.pressid AND p.pressname = '外研社'; + +#7 +SELECT * +FROM sort s +WHERE s.scount > 100; + +#8 +SELECT p.* +FROM book b, press p +WHERE p.pressid = b.pressid +GROUP BY b.pressid +HAVING COUNT(*) = ( + SELECT COUNT(*) + FROM book b, press p + WHERE p.pressid = b.pressid + GROUP BY b.pressid + ORDER BY COUNT(*) DESC + LIMIT 1 +); +``` + +--- + +### 练习八 + +![image-20250315230214156](https://yp.smallkun.cn/markdown/image-20250315230214156.png!compress) + +![image-20250315230227129](https://yp.smallkun.cn/markdown/image-20250315230227129.png!compress) + +```sql +-- 创建数据库 test_tour 并设置字符集为 utf8mb4 +CREATE DATABASE test_tour CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +USE test_tour; + +-- 创建表 agency(旅行社表) +CREATE TABLE agency ( + id INT PRIMARY KEY, -- 旅行社编号,主键 + name VARCHAR(100) NOT NULL, -- 旅行社名 + address VARCHAR(100) NOT NULL, -- 旅行社地址 + areaid INT -- 所属区域编号 +); + +-- 创建表 travel(旅行线路表) +CREATE TABLE travel ( + tid INT PRIMARY KEY, -- 旅行线路编号,主键 + time VARCHAR(50) NOT NULL, -- 所需时间 + position VARCHAR(100) NOT NULL, -- 目的地 + money FLOAT, -- 花费 + aid INT NOT NULL, -- 所属旅行社编号 + count INT, -- 报名人数 + FOREIGN KEY (aid) REFERENCES agency(id) -- 外键,引用 agency 表 +); + +-- 向 agency 表插入数据 +INSERT INTO agency (id, name, address) VALUES +(101, '青年旅行社', '北京海淀'), +(102, '天天旅行社', '天津海院'); + +-- 向 travel 表插入数据 +INSERT INTO travel (tid, time, position, money, aid, count) VALUES +(1, '5天', '八达岭', 3000, 101, 10), +(2, '7天', '水长城', 5000, 101, 14), +(3, '8天', '水长城', 6000, 102, 11); + +#4 +SELECT a.* +FROM travel t, agency a +WHERE t.aid =a.id +GROUP BY a.id +HAVING COUNT(*) = ( + SELECT COUNT(*) + FROM travel t, agency a + WHERE t.aid =a.id + GROUP BY a.id + ORDER BY COUNT(*) DESC + LIMIT 1 +); + +#5 +SELECT t.* +FROM travel t +WHERE t.count = ( + SELECT t.count + FROM travel t + ORDER BY t.count DESC + LIMIT 1 +); + +#6 +SELECT * +FROM travel t +WHERE t.money < 5000; + +#7 +SELECT a.`name` +FROM travel t, agency a +WHERE t.aid =a.id AND t.money = ( + SELECT t.money + FROM travel t, agency a + WHERE t.aid =a.id + ORDER BY t.money DESC + LIMIT 1 +); + +#8 +SELECT SUM(t.time) +FROM travel t, agency a +WHERE t.aid =a.id AND a.`name` = '青年旅行社'; +``` + diff --git a/最后两周/存储函数练习题.md b/最后两周/存储函数练习题.md new file mode 100644 index 0000000..f4ce487 --- /dev/null +++ b/最后两周/存储函数练习题.md @@ -0,0 +1,155 @@ +### 语法结构 + +```sql +DELIMITER // + +CREATE FUNCTION calculate_annual_salary ( + monthly_salary DECIMAL(10, 2) +) +RETURNS DECIMAL(10, 2) +DETERMINISTIC | NOT DETERMINISTIC #结果确定/不确定 +BEGIN + RETURN monthly_salary * 12; +END // + +DELIMITER ; +``` + + + +### 表结构与数据 + +```sql +-- 创建数据库 +CREATE DATABASE company CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- 使用数据库 +USE company; + +-- 创建 department 表 +CREATE TABLE department ( + dept_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '部门ID,主键', + dept_name VARCHAR(100) NOT NULL COMMENT '部门名称', + location VARCHAR(100) NOT NULL COMMENT '部门所在地' +); + +-- 创建 job 表 +CREATE TABLE job ( + job_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '职位ID,主键', + job_title VARCHAR(100) NOT NULL COMMENT '职位名称', + min_salary DECIMAL(10, 2) NOT NULL COMMENT '最低工资', + max_salary DECIMAL(10, 2) NOT NULL COMMENT '最高工资' +); + +-- 创建 employee 表 +CREATE TABLE employee ( + emp_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '员工ID,主键', + emp_name VARCHAR(100) NOT NULL COMMENT '员工姓名', + salary DECIMAL(10, 2) NOT NULL COMMENT '员工工资', + hire_date DATE NOT NULL COMMENT '入职日期', + dept_id INT COMMENT '部门ID,外键', + job_id INT COMMENT '职位ID,外键', + FOREIGN KEY (dept_id) REFERENCES department(dept_id), + FOREIGN KEY (job_id) REFERENCES job(job_id) +); + +INSERT INTO department (dept_name, location) VALUES +('HR', 'New York'), +('IT', 'San Francisco'), +('Finance', 'Chicago'), +('Marketing', 'Los Angeles'), +('Sales', 'Boston'), +('Operations', 'Houston'), +('Research', 'Seattle'), +('Customer Support', 'Austin'); + +INSERT INTO job (job_title, min_salary, max_salary) VALUES +('Manager', 60000.00, 100000.00), +('Developer', 50000.00, 80000.00), +('Analyst', 45000.00, 70000.00), +('Designer', 40000.00, 65000.00), +('Sales Executive', 35000.00, 60000.00), +('HR Specialist', 40000.00, 70000.00), +('Finance Analyst', 50000.00, 75000.00), +('Marketing Coordinator', 45000.00, 70000.00), +('Operations Manager', 55000.00, 90000.00), +('Research Scientist', 60000.00, 95000.00), +('Customer Support Representative', 35000.00, 55000.00); + +INSERT INTO employee (emp_name, salary, hire_date, dept_id, job_id) VALUES +('Alice', 70000.00, '2020-01-15', 1, 1), +('Bob', 65000.00, '2019-03-22', 2, 2), +('Charlie', 55000.00, '2018-07-30', 2, 3), +('David', 60000.00, '2021-05-10', 3, 4), +('Eva', 50000.00, '2017-11-05', 4, 5), +('Frank', 75000.00, '2016-09-12', 5, 1), +('Grace', 48000.00, '2022-02-20', 1, 2), +('Henry', 52000.00, '2021-08-15', 2, 3), +('Ivy', 58000.00, '2020-04-10', 3, 4), +('Jack', 62000.00, '2019-12-01', 4, 5), +('Katie', 53000.00, '2021-07-25', 5, 6), +('Leo', 67000.00, '2018-05-18', 6, 7), +('Mona', 49000.00, '2020-11-30', 7, 8), +('Nina', 71000.00, '2019-02-14', 8, 9), +('Oscar', 56000.00, '2022-03-05', 1, 10), +('Paul', 63000.00, '2021-09-12', 2, 11), +('Quincy', 54000.00, '2020-06-20', 3, 1), +('Rachel', 59000.00, '2019-08-15', 4, 2), +('Steve', 68000.00, '2018-12-10', 5, 3), +('Tina', 51000.00, '2022-01-22', 6, 4), +('Uma', 72000.00, '2021-04-18', 7, 5), +('Victor', 57000.00, '2020-07-30', 8, 6), +('Wendy', 64000.00, '2019-10-05', 1, 7), +('Xander', 50000.00, '2022-05-12', 2, 8), +('Yara', 69000.00, '2021-03-25', 3, 9), +('Zack', 55000.00, '2020-09-15', 4, 10), +('Amy', 61000.00, '2019-06-20', 5, 11), +('Brian', 74000.00, '2018-04-10', 6, 1), +('Cathy', 52000.00, '2022-07-18', 7, 2), +('Derek', 67000.00, '2021-12-01', 8, 3); +``` + +### 练习题 + +#### 练习题 1: 计算员工年薪 + +创建一个存储函数 `calculate_annual_salary`,接受员工的月薪作为参数,返回其年薪(假设年薪为月薪的 12 倍)。 + +#### 练习题 2: 计算员工工龄 + +创建一个存储函数 `calculate_years_of_service`,接受员工的入职日期作为参数,返回该员工的工龄(以年为单位)。 + +#### 练习题 3: 根据部门计算平均工资 + +创建一个存储函数 `calculate_avg_salary_by_dept`,接受部门 ID 作为参数,返回该部门的平均工资。 + +#### 练习题 4: 根据职位计算平均工资 + +创建一个存储函数 `calculate_avg_salary_by_job`,接受职位 ID 作为参数,返回该职位的平均工资。 + +#### 练习题 5: 计算员工税后工资 + +创建一个存储函数 `calculate_net_salary`,接受员工的工资作为参数,返回其税后工资(假设税率为 15%)。 + +#### 练习题 6: 判断员工是否满足加薪条件 + +创建一个存储函数 `is_eligible_for_raise`,接受员工的工资和工龄作为参数,返回一个布尔值(1 或 0)。加薪条件如下: + +- 如果工资低于 60000 且工龄大于等于 3 年,返回 1(满足条件)。 +- 否则返回 0(不满足条件)。 + +#### 练习题 7: 计算部门总工资 + +创建一个存储函数 `calculate_total_salary_by_dept`,接受部门 ID 作为参数,返回该部门所有员工的总工资。 + +#### 练习题 8: 计算职位总工资 + +创建一个存储函数 `calculate_total_salary_by_job`,接受职位 ID 作为参数,返回该职位所有员工的总工资。 + +#### 练习题 9: 判断员工是否属于高薪部门 + +创建一个存储函数 `is_high_salary_department`,接受部门 ID 作为参数,返回一个布尔值(1 或 0)。如果该部门的平均工资大于等于 70000,返回 1(高薪部门),否则返回 0(非高薪部门)。 + +#### 练习题 10: 计算员工的总收入 + +创建一个存储函数 `calculate_total_income`,接受员工的工资和奖金(假设奖金为工资的 10%)作为参数,返回其总收入(工资 + 奖金)。 \ No newline at end of file diff --git a/最后两周/存储过程练习题.md b/最后两周/存储过程练习题.md new file mode 100644 index 0000000..41fbb3d --- /dev/null +++ b/最后两周/存储过程练习题.md @@ -0,0 +1,529 @@ +### 语法结构 + +```sql +DELIMITER // + +CREATE PROCEDURE GetEmployeeCountByDept ( + IN dept_id INT, + OUT employee_count INT +) +BEGIN + SELECT COUNT(*) INTO employee_count + FROM employee + WHERE dept_id = dept_id; +END // + +DELIMITER ; + +IF condition THEN + -- 条件为真时执行的代码 +ELSEIF another_condition THEN + -- 另一个条件为真时执行的代码 +ELSE + -- 所有条件都不满足时执行的代码 +END IF; + +CASE expression + WHEN value1 THEN + -- 当 expression = value1 时执行的代码 + WHEN value2 THEN + -- 当 expression = value2 时执行的代码 + ELSE + -- 当 expression 不匹配任何值时执行的代码 +END CASE; + +CASE + WHEN condition1 THEN + -- 当 condition1 为真时执行的代码 + WHEN condition2 THEN + -- 当 condition2 为真时执行的代码 + ELSE + -- 当所有条件都不满足时执行的代码 +END CASE; +``` + + + +--- + +### 表结构与数据 + +```sql +-- 创建数据库 +CREATE DATABASE company CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- 使用数据库 +USE company; + +-- 创建 department 表 +CREATE TABLE department ( + dept_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '部门ID,主键', + dept_name VARCHAR(100) NOT NULL COMMENT '部门名称', + location VARCHAR(100) NOT NULL COMMENT '部门所在地' +); + +-- 创建 job 表 +CREATE TABLE job ( + job_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '职位ID,主键', + job_title VARCHAR(100) NOT NULL COMMENT '职位名称', + min_salary DECIMAL(10, 2) NOT NULL COMMENT '最低工资', + max_salary DECIMAL(10, 2) NOT NULL COMMENT '最高工资' +); + +-- 创建 employee 表 +CREATE TABLE employee ( + emp_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '员工ID,主键', + emp_name VARCHAR(100) NOT NULL COMMENT '员工姓名', + salary DECIMAL(10, 2) NOT NULL COMMENT '员工工资', + hire_date DATE NOT NULL COMMENT '入职日期', + dept_id INT COMMENT '部门ID,外键', + job_id INT COMMENT '职位ID,外键', + FOREIGN KEY (dept_id) REFERENCES department(dept_id), + FOREIGN KEY (job_id) REFERENCES job(job_id) +); + +INSERT INTO department (dept_name, location) VALUES +('HR', 'New York'), +('IT', 'San Francisco'), +('Finance', 'Chicago'), +('Marketing', 'Los Angeles'), +('Sales', 'Boston'), +('Operations', 'Houston'), +('Research', 'Seattle'), +('Customer Support', 'Austin'); + +INSERT INTO job (job_title, min_salary, max_salary) VALUES +('Manager', 60000.00, 100000.00), +('Developer', 50000.00, 80000.00), +('Analyst', 45000.00, 70000.00), +('Designer', 40000.00, 65000.00), +('Sales Executive', 35000.00, 60000.00), +('HR Specialist', 40000.00, 70000.00), +('Finance Analyst', 50000.00, 75000.00), +('Marketing Coordinator', 45000.00, 70000.00), +('Operations Manager', 55000.00, 90000.00), +('Research Scientist', 60000.00, 95000.00), +('Customer Support Representative', 35000.00, 55000.00); + +INSERT INTO employee (emp_name, salary, hire_date, dept_id, job_id) VALUES +('Alice', 70000.00, '2020-01-15', 1, 1), +('Bob', 65000.00, '2019-03-22', 2, 2), +('Charlie', 55000.00, '2018-07-30', 2, 3), +('David', 60000.00, '2021-05-10', 3, 4), +('Eva', 50000.00, '2017-11-05', 4, 5), +('Frank', 75000.00, '2016-09-12', 5, 1), +('Grace', 48000.00, '2022-02-20', 1, 2), +('Henry', 52000.00, '2021-08-15', 2, 3), +('Ivy', 58000.00, '2020-04-10', 3, 4), +('Jack', 62000.00, '2019-12-01', 4, 5), +('Katie', 53000.00, '2021-07-25', 5, 6), +('Leo', 67000.00, '2018-05-18', 6, 7), +('Mona', 49000.00, '2020-11-30', 7, 8), +('Nina', 71000.00, '2019-02-14', 8, 9), +('Oscar', 56000.00, '2022-03-05', 1, 10), +('Paul', 63000.00, '2021-09-12', 2, 11), +('Quincy', 54000.00, '2020-06-20', 3, 1), +('Rachel', 59000.00, '2019-08-15', 4, 2), +('Steve', 68000.00, '2018-12-10', 5, 3), +('Tina', 51000.00, '2022-01-22', 6, 4), +('Uma', 72000.00, '2021-04-18', 7, 5), +('Victor', 57000.00, '2020-07-30', 8, 6), +('Wendy', 64000.00, '2019-10-05', 1, 7), +('Xander', 50000.00, '2022-05-12', 2, 8), +('Yara', 69000.00, '2021-03-25', 3, 9), +('Zack', 55000.00, '2020-09-15', 4, 10), +('Amy', 61000.00, '2019-06-20', 5, 11), +('Brian', 74000.00, '2018-04-10', 6, 1), +('Cathy', 52000.00, '2022-07-18', 7, 2), +('Derek', 67000.00, '2021-12-01', 8, 3); +``` + + + +--- + +### 练习题 + +#### 练习题 1: 插入新员工 + +创建一个存储过程 `add_employee`,接受员工姓名、工资、入职日期、部门ID和职位ID作为参数,并将其插入到 `employee` 表中。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS add_employee; +CREATE PROCEDURE add_employee(IN emp_name VARCHAR(100), IN salary DECIMAL(10,2), IN hire_date DATE, IN dept_id INT, IN job_id INT) +BEGIN + INSERT INTO employee() + VALUES(DEFAULT, emp_name, salary, hire_date, dept_id, job_id); +END $$ +DELIMITER ; + +CALL add_employee('李泽龙', 6666, '2025-3-20', 1, 1); +``` + + + +#### 练习题 2: 更新员工工资 + +创建一个存储过程 `update_employee_salary`,接受员工ID和新的工资作为参数,更新该员工的工资。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS update_employee_salary; +CREATE PROCEDURE update_employee_salary(IN emp_id INT, IN salary DECIMAL(10, 2)) +BEGIN + UPDATE employee e + SET e.salary = salary + WHERE e.emp_id = emp_id; +END $$ +DELIMITER ; +CALL update_employee_salary(1, 60000); +``` + + + +#### 练习题 3: 删除员工 + +创建一个存储过程 `delete_employee`,接受员工ID作为参数,删除该员工的记录。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS delete_employee; +CREATE PROCEDURE delete_employee(IN id INT) +BEGIN + DELETE FROM employee + WHERE emp_id = id; +END $$ +DELIMITER ; + +CALL delete_employee(1); +``` + + + +#### 练习题 4: 查询部门员工 + +创建一个存储过程 `get_department_employees`,接受部门ID作为参数,返回该部门所有员工的详细信息。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_department_employees; +CREATE PROCEDURE get_department_employees(IN id INT) +BEGIN + SELECT e.* + FROM employee e + WHERE e.dept_id = id; +END $$ +DELIMITER ; +CALL get_department_employees(1); +``` + + + +#### 练习题 5: 查询职位员工 + +创建一个存储过程 `get_job_employees`,接受职位ID作为参数,返回该职位所有员工的详细信息。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_job_employees; +CREATE PROCEDURE get_job_employees(IN id INT) +BEGIN + SELECT e.* + FROM employee e + WHERE e.job_id = id; +END $$ +DELIMITER ; +CALL get_job_employees(1); +``` + + + +#### 练习题 6: 计算部门平均工资 + +创建一个存储过程 `calculate_avg_salary_by_dept`,接受部门ID作为参数,返回该部门的平均工资。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS calculate_avg_salary_by_dept; +CREATE PROCEDURE calculate_avg_salary_by_dept(IN id INT) +BEGIN + SELECT AVG(e.salary) + FROM employee e + WHERE e.dept_id = id; +END $$ +DELIMITER ; +CALL calculate_avg_salary_by_dept(1); +``` + + + +#### 练习题 7: 计算职位平均工资 + +创建一个存储过程 `calculate_avg_salary_by_job`,接受职位ID作为参数,返回该职位的平均工资。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS calculate_avg_salary_by_job; +CREATE PROCEDURE calculate_avg_salary_by_job(IN id INT) +BEGIN + SELECT AVG(e.salary) + FROM employee e + WHERE e.job_id = id; +END $$ +DELIMITER ; +CALL calculate_avg_salary_by_job(1); +``` + + + +#### 练习题 8: 查询高薪员工 + +创建一个存储过程 `get_high_salary_employees`,接受一个工资阈值作为参数,返回所有工资高于该阈值的员工。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_high_salary_employees; +CREATE PROCEDURE get_high_salary_employees(IN sal DECIMAL(10, 2)) +BEGIN + SELECT e.* + FROM employee e + WHERE e.salary > sal; +END $$ +DELIMITER ; +CALL get_high_salary_employees(50000); +``` + + + +#### 练习题 9: 查询员工工龄 + +创建一个存储过程 `get_employee_years_of_service`,接受员工ID作为参数,返回该员工的工龄(以年为单位)。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_employee_years_of_service; +CREATE PROCEDURE get_employee_years_of_service(IN id INT) +BEGIN + SELECT -TIMESTAMPDIFF(YEAR,NOW(),e.hire_date) + FROM employee e + WHERE e.emp_id = id; +END $$ +DELIMITER ; +CALL get_employee_years_of_service(1); +``` + + + +#### 练习题 10: 查询部门员工总数 + +创建一个存储过程 `get_department_employee_count`,接受部门ID作为参数,返回该部门的员工总数。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_department_employee_count; +CREATE PROCEDURE get_department_employee_count(IN id INT) +BEGIN + SELECT COUNT(*) + FROM employee e + WHERE e.dept_id = id; +END $$ +DELIMITER ; +CALL get_department_employee_count(1); +``` + + + +#### 练习题 11: 查询职位员工总数 + +创建一个存储过程 `get_job_employee_count`,接受职位ID作为参数,返回该职位的员工总数。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_job_employee_count; +CREATE PROCEDURE get_job_employee_count(IN id INT) +BEGIN + SELECT COUNT(*) + FROM employee e + WHERE e.job_id = id; +END $$ +DELIMITER ; +CALL get_job_employee_count(1); +``` + + + +#### 练习题 12: 查询员工详细信息 + +创建一个存储过程 `get_employee_details`,接受员工ID作为参数,返回该员工的姓名、工资、部门名称和职位名称。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_employee_details; +CREATE PROCEDURE get_employee_details(IN emp_id INT) +BEGIN + SELECT e.emp_name, e.salary, d.dept_name, j.job_title + FROM employee e, department d, job j + WHERE e.emp_id = emp_id AND e.dept_id = d.dept_id AND e.job_id = j.job_id; +END $$ +DELIMITER ; +CALL get_employee_details(1); +``` + + + +#### 练习题 13: 查询部门最高工资 + +创建一个存储过程 `get_department_max_salary`,接受部门ID作为参数,返回该部门的最高工资。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_department_max_salary; +CREATE PROCEDURE get_department_max_salary(IN id INT) +BEGIN + SELECT MAX(e.salary) + FROM employee e + WHERE e.dept_id = id; +END $$ +DELIMITER ; +CALL get_department_max_salary(1); +``` + + + +#### 练习题 14: 查询职位最低工资 + +创建一个存储过程 `get_job_min_salary`,接受职位ID作为参数,返回该职位的最低工资。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_job_min_salary; +CREATE PROCEDURE get_job_min_salary(IN id INT) +BEGIN + SELECT MIN(e.salary) + FROM employee e + WHERE e.dept_id = id; +END $$ +DELIMITER ; +CALL get_job_min_salary(1); +``` + + + +#### 练习题 15: 查询员工工资排名 + +创建一个存储过程 `get_employee_salary_rank`,接受员工ID作为参数,返回该员工在公司中的工资排名。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_employee_salary_rank; +CREATE PROCEDURE get_employee_salary_rank(IN emp_id INT) +BEGIN + SELECT COUNT(*) + 1 + FROM employee e + WHERE e.salary > ( + SELECT e.salary + FROM employee e + WHERE e.emp_id = emp_id + ); +END $$ +DELIMITER ; + +CALL get_employee_salary_rank(2); +``` + + + +#### 练习题 16: 查询部门工资总和 + +创建一个存储过程 `get_department_total_salary`,接受部门ID作为参数,返回该部门所有员工的工资总和。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_department_total_salary; +CREATE PROCEDURE get_department_total_salary(IN id INT) +BEGIN + SELECT SUM(e.salary) + FROM employee e + WHERE e.dept_id = id; +END $$ +DELIMITER ; +CALL get_department_total_salary(1); +``` + + + +#### 练习题 17: 查询职位工资总和 + +创建一个存储过程 `get_job_total_salary`,接受职位ID作为参数,返回该职位所有员工的工资总和。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_job_total_salary; +CREATE PROCEDURE get_job_total_salary(IN id INT) +BEGIN + SELECT SUM(e.salary) + FROM employee e + WHERE e.job_id = id; +END $$ +DELIMITER ; +CALL get_job_total_salary(1); +``` + + + +#### 练习题 18: 查询员工入职年份分布 + +创建一个存储过程 `get_employees_by_hire_year`,接受年份作为参数,返回该年份入职的所有员工。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_employees_by_hire_year; +CREATE PROCEDURE get_employees_by_hire_year(IN y INT) +BEGIN + SELECT * + FROM employee e + WHERE YEAR(e.hire_date) = y; +END $$ +DELIMITER ; +CALL get_employees_by_hire_year(2020); +``` + + + +#### 练习题 19: 查询部门工资分布 + +创建一个存储过程 `get_department_salary_distribution`,接受部门ID作为参数,返回该部门工资的分布情况(如最高、最低、平均工资)。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_department_salary_distribution; +CREATE PROCEDURE get_department_salary_distribution(IN id INT) +BEGIN + SELECT MAX(e.salary), MIN(e.salary), AVG(e.salary) + FROM employee e + WHERE e.dept_id = id; +END $$ +DELIMITER ; +CALL get_department_salary_distribution(1); +``` + + + +#### 练习题 20: 查询职位工资分布 + +创建一个存储过程 `get_job_salary_distribution`,接受职位ID作为参数,返回该职位工资的分布情况(如最高、最低、平均工资)。 + +```sql +DELIMITER $$ +DROP PROCEDURE IF EXISTS get_job_salary_distribution; +CREATE PROCEDURE get_job_salary_distribution(IN id INT) +BEGIN + SELECT MAX(e.salary), MIN(e.salary), AVG(e.salary) + FROM employee e + WHERE e.job_id = id; +END $$ +DELIMITER ; +CALL get_job_salary_distribution(1); +``` + diff --git a/最后两周/触发器练习题.md b/最后两周/触发器练习题.md new file mode 100644 index 0000000..4a8d963 --- /dev/null +++ b/最后两周/触发器练习题.md @@ -0,0 +1,610 @@ +### 语法结构 + +```sql +DELIMITER // +CREATE TRIGGER trigger_name +{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name +FOR EACH ROW +BEGIN + -- 触发器的逻辑代码 + -- 可以包含 SQL 语句、流程控制语句(如 IF、CASE 等)、变量声明等 +END// +DELIMITER ; +``` + +### 表结构和数据 + +```sql +-- 创建数据库 +CREATE DATABASE company CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; + +-- 使用数据库 +USE company; + +-- 创建 department 表 +CREATE TABLE department ( + dept_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '部门ID,主键', + dept_name VARCHAR(100) NOT NULL COMMENT '部门名称', + location VARCHAR(100) NOT NULL COMMENT '部门所在地' +); + +-- 创建 job 表 +CREATE TABLE job ( + job_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '职位ID,主键', + job_title VARCHAR(100) NOT NULL COMMENT '职位名称', + min_salary DECIMAL(10, 2) NOT NULL COMMENT '最低工资', + max_salary DECIMAL(10, 2) NOT NULL COMMENT '最高工资' +); + +-- 创建 employee 表 +CREATE TABLE employee ( + emp_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '员工ID,主键', + emp_name VARCHAR(100) NOT NULL COMMENT '员工姓名', + salary DECIMAL(10, 2) NOT NULL COMMENT '员工工资', + hire_date DATE NOT NULL COMMENT '入职日期', + dept_id INT COMMENT '部门ID,外键', + job_id INT COMMENT '职位ID,外键', + FOREIGN KEY (dept_id) REFERENCES department(dept_id), + FOREIGN KEY (job_id) REFERENCES job(job_id) +); + +INSERT INTO department (dept_name, location) VALUES +('HR', 'New York'), +('IT', 'San Francisco'), +('Finance', 'Chicago'), +('Marketing', 'Los Angeles'), +('Sales', 'Boston'), +('Operations', 'Houston'), +('Research', 'Seattle'), +('Customer Support', 'Austin'); + +INSERT INTO job (job_title, min_salary, max_salary) VALUES +('Manager', 60000.00, 100000.00), +('Developer', 50000.00, 80000.00), +('Analyst', 45000.00, 70000.00), +('Designer', 40000.00, 65000.00), +('Sales Executive', 35000.00, 60000.00), +('HR Specialist', 40000.00, 70000.00), +('Finance Analyst', 50000.00, 75000.00), +('Marketing Coordinator', 45000.00, 70000.00), +('Operations Manager', 55000.00, 90000.00), +('Research Scientist', 60000.00, 95000.00), +('Customer Support Representative', 35000.00, 55000.00); + +INSERT INTO employee (emp_name, salary, hire_date, dept_id, job_id) VALUES +('Alice', 70000.00, '2020-01-15', 1, 1), +('Bob', 65000.00, '2019-03-22', 2, 2), +('Charlie', 55000.00, '2018-07-30', 2, 3), +('David', 60000.00, '2021-05-10', 3, 4), +('Eva', 50000.00, '2017-11-05', 4, 5), +('Frank', 75000.00, '2016-09-12', 5, 1), +('Grace', 48000.00, '2022-02-20', 1, 2), +('Henry', 52000.00, '2021-08-15', 2, 3), +('Ivy', 58000.00, '2020-04-10', 3, 4), +('Jack', 62000.00, '2019-12-01', 4, 5), +('Katie', 53000.00, '2021-07-25', 5, 6), +('Leo', 67000.00, '2018-05-18', 6, 7), +('Mona', 49000.00, '2020-11-30', 7, 8), +('Nina', 71000.00, '2019-02-14', 8, 9), +('Oscar', 56000.00, '2022-03-05', 1, 10), +('Paul', 63000.00, '2021-09-12', 2, 11), +('Quincy', 54000.00, '2020-06-20', 3, 1), +('Rachel', 59000.00, '2019-08-15', 4, 2), +('Steve', 68000.00, '2018-12-10', 5, 3), +('Tina', 51000.00, '2022-01-22', 6, 4), +('Uma', 72000.00, '2021-04-18', 7, 5), +('Victor', 57000.00, '2020-07-30', 8, 6), +('Wendy', 64000.00, '2019-10-05', 1, 7), +('Xander', 50000.00, '2022-05-12', 2, 8), +('Yara', 69000.00, '2021-03-25', 3, 9), +('Zack', 55000.00, '2020-09-15', 4, 10), +('Amy', 61000.00, '2019-06-20', 5, 11), +('Brian', 74000.00, '2018-04-10', 6, 1), +('Cathy', 52000.00, '2022-07-18', 7, 2), +('Derek', 67000.00, '2021-12-01', 8, 3); +``` + +### `SIGNAL` 语句的基本语法 + +```sql +SIGNAL SQLSTATE '状态码' +SET MESSAGE_TEXT = '错误消息'; +``` + +- **SQLSTATE**:一个 5 字符的字符串,表示错误的状态码。MySQL 使用 `'45000'` 表示用户定义的错误。 +- **MESSAGE_TEXT**:自定义的错误消息,用于描述错误的原因。 + +### 练习题 + +#### 练习题 1: 工资范围验证 + +创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据之前,检查员工的工资是否在其对应职位的 `min_salary` 和 `max_salary` 范围内。如果超出范围,阻止插入并抛出错误。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_insert; +CREATE TRIGGER before_employee_insert +BEFORE INSERT ON employee +FOR EACH ROW +BEGIN + + IF NEW.salary > ( + SELECT j.max_salary + FROM job j + WHERE j.job_id = NEW.job_id + ) OR NEW.salary < ( + SELECT j.min_salary + FROM job j + WHERE j.job_id = NEW.job_id + ) THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '工资值错误,不在职务工资范围内'; + END IF; +END $$ +DELIMITER ; + +INSERT INTO employee +VALUES(DEFAULT, '雷昊', 0, NOW(), 1, 1); +``` + + + +#### 练习题 2: 自动更新部门人数 + +创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新 `department` 表中的部门人数(假设 `department` 表新增一个字段 `employee_count`)。 + +```sql +ALTER TABLE department ADD employee_count INT UNSIGNED; + +DELIMITER $$ +DROP TRIGGER IF EXISTS after_employee_insert; +CREATE TRIGGER after_employee_insert +AFTER INSERT ON employee +FOR EACH ROW +BEGIN + UPDATE department d + SET d.employee_count = ( + SELECT COUNT(*) + FROM employee e + WHERE e.dept_id = d.dept_id + ); +END $$ +DELIMITER ; + +INSERT INTO employee +VALUES(DEFAULT, '雷昊', 60000.00, NOW(), 1, 1); +``` + + + +#### 练习题 3: 工资变更日志 + +创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `salary` 字段后,将变更记录插入到一个新的日志表 `salary_log` 中,记录员工 ID、旧工资、新工资和变更时间。 + +```sql +DROP TABLE IF EXISTS salary_log; +CREATE TABLE salary_log( + emp_id INT, + old_salary DECIMAL(10, 2), + new_slaray DECIMAL(10, 2), + update_date DATE +); + +DELIMITER $$ +DROP TRIGGER IF EXISTS after_employee_update; +CREATE TRIGGER after_employee_update +BEFORE UPDATE ON employee +FOR EACH ROW +BEGIN + IF NEW.salary <> OLD.salary THEN + INSERT INTO salary_log() + VALUES(NEW.emp_id, OLD.salary, NEW.salary, NOW()); + END IF; +END $$ +DELIMITER ; + +UPDATE employee e +SET e.salary = 10 +WHERE e.emp_id = 1; +``` + + + +#### 练习题 4: 删除员工时备份数据 + +创建一个触发器 `before_employee_delete`,在删除 `employee` 表数据之前,将被删除的员工数据插入到一个备份表 `employee_backup` 中。 + +```sql +CREATE TABLE employee_backup AS +SELECT * +FROM employee +WHERE 0; + +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_delete; +CREATE TRIGGER before_employee_delete +BEFORE DELETE ON employee +FOR EACH ROW +BEGIN + INSERT INTO employee_backup() + VALUES(OLD.emp_id, OLD.emp_name, OLD.salary, OLD.hire_date, OLD.dept_id, OLD.job_id); +END $$ +DELIMITER ; + +DELETE FROM employee +WHERE emp_id = 20; +``` + + + +#### 练习题 5: 自动设置默认职位 + +创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,如果未指定 `job_id`,则自动将其设置为 `job` 表中的默认职位(假设默认职位的 `job_id` 为 1)。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_insert; +CREATE TRIGGER before_employee_insert +BEFORE INSERT ON employee +FOR EACH ROW +BEGIN + IF NEW.job_id IS NULL THEN + SET NEW.job_id = 1; + END IF; +END $$ +DELIMITER ; + +INSERT INTO employee +VALUES(DEFAULT, '雷昊', 60000.00, NOW(), 1, NULL); +``` + + + +#### 练习题 6: 防止修改入职日期 + +创建一个触发器 `before_employee_update`,在更新 `employee` 表数据时,防止修改 `hire_date` 字段。如果尝试修改,抛出错误。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_update; +CREATE TRIGGER before_employee_update +BEFORE UPDATE ON employee +FOR EACH ROW +BEGIN + IF NEW.hire_date <> OLD.hire_date THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT='不允许修改用户的入职时间'; + END IF; +END $$ +DELIMITER ; +UPDATE employee e +SET e.hire_date = '2025-3-20' +WHERE e.emp_id = 1; +``` + + + +#### 练习题 7: 自动计算工龄 + +创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,自动计算员工的工龄(以年为单位),并将其存储到一个新字段 `years_of_service` 中。 + +```sql +ALTER TABLE employee ADD years_of_service INT; + +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_insert; +CREATE TRIGGER before_employee_insert +BEFORE INSERT ON employee +FOR EACH ROW +BEGIN + SET NEW.years_of_service = TIMESTAMPDIFF(YEAR,NEW.hire_date,NOW()); +END $$ +DELIMITER ; + +SELECT TIMESTAMPDIFF(YEAR,e.hire_date,NOW()) +FROM employee e; + +INSERT INTO employee +VALUES(DEFAULT, '雷昊', 60000.00, '2022-12-31', 1, 1, NULL); +``` + + + +#### 练习题 8: 防止删除部门 + +创建一个触发器 `before_department_delete`,在删除 `department` 表数据之前,检查该部门是否还有员工。如果有员工,阻止删除并抛出错误。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_department_delete; +CREATE TRIGGER before_department_delete +BEFORE DELETE ON department +FOR EACH ROW +BEGIN + IF (SELECT COUNT(*) FROM employee e WHERE e.dept_id = OLD.dept_id) > 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '该部门有员工无法删除'; + END IF; +END $$ +DELIMITER ; + +DELETE FROM department +WHERE dept_id = 1; +``` + + + +#### 练习题 9: 自动更新职位工资范围 + +创建一个触发器 `after_job_update`,在更新 `job` 表的 `min_salary` 或 `max_salary` 字段后,自动调整 `employee` 表中相关员工的工资,使其符合新的工资范围。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS after_job_update; +CREATE TRIGGER after_job_update +AFTER UPDATE ON job +FOR EACH ROW +BEGIN + UPDATE employee + SET salary = IF(salary > NEW.max_salary, NEW.max_salary, IF(salary < NEW.min_salary, min_salary, salary)) + WHERE job_id = NEW.job_id; +END $$ +DELIMITER ; +``` + + + +#### 练习题 10: 记录部门变更 + +创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `dept_id` 字段后,将变更记录插入到一个新的日志表 `department_change_log` 中,记录员工 ID、旧部门 ID、新部门 ID 和变更时间。 + +```sql +CREATE TABLE department_change_log( + emp_id INT, + old_dept_id INT, + new_dept_id INT, + update_date DATE +); + +DELIMITER $$ +DROP TRIGGER IF EXISTS after_employee_update; +CREATE TRIGGER after_employee_update +AFTER UPDATE ON employee +FOR EACH ROW +BEGIN + IF NEW.dept_id <> OLD.dept_id THEN + INSERT INTO department_change_log() + VALUES(NEW.emp_id, OLD.dept_id, NEW.dept_id, NOW()); + END IF; +END $$ +DELIMITER ; +``` + + + +#### 练习题 11: 防止插入重复职位 + +创建一个触发器 `before_job_insert`,在插入 `job` 表数据之前,检查职位名称是否已存在。如果存在,阻止插入并抛出错误。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_job_insert; +CREATE TRIGGER before_job_insert +BEFORE INSERT ON job +FOR EACH ROW +BEGIN + IF (SELECT COUNT(*) FROM job WHERE job_id = NEW.job_id) = 1 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '职位名称已存在'; + END IF; +END $$ +DELIMITER ; +``` + + + +#### 练习题 12: 自动更新员工总数 + +创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新一个统计表 `employee_statistics` 中的员工总数。 + +```sql +CREATE TABLE employee_statistics( + marking VARCHAR(20), + num INT +); +INSERT INTO employee_statistics() +VALUES('count', 0); + +DELIMITER $$ +DROP TRIGGER IF EXISTS after_employee_insert; +CREATE TRIGGER after_employee_insert +AFTER INSERT ON employee +FOR EACH ROW +BEGIN + UPDATE employee_statistics + SET num = (SELECT COUNT(*) FROM employee) + WHERE marking = 'count'; +END $$ +DELIMITER ; +``` + + + +#### 练习题 13: 防止修改部门所在地 + +创建一个触发器 `before_department_update`,在更新 `department` 表数据时,防止修改 `location` 字段。如果尝试修改,抛出错误。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_department_update; +CREATE TRIGGER before_department_update +BEFORE UPDATE ON department +FOR EACH ROW +BEGIN + IF NEW.location <> OLD.location THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '无法更新部分的位置'; + END IF; +END $$ +DELIMITER ; +``` + + + +#### 练习题 14: 自动调整工资 + +创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,如果工资低于职位的最低工资,则自动将其调整为最低工资。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_insert; +CREATE TRIGGER before_employee_insert +BEFORE INSERT ON employee +FOR EACH ROW +BEGIN + IF NEW.salary < (SELECT min_salary FROM job WHERE job_id = NEW.job_id ) THEN + SET NEW.salary = min_salary; + END IF; +END $$ +DELIMITER ; +``` + + + +#### 练习题 15: 记录职位变更 + +创建一个触发器 `after_employee_update`,在更新 `employee` 表的 `job_id` 字段后,将变更记录插入到一个新的日志表 `job_change_log` 中,记录员工 ID、旧职位 ID、新职位 ID 和变更时间。 + +```sql +CREATE TABLE job_change_log( + emp_id INT, + old_job_id INT, + new_job_id INT, + update_date DATE +); +DELIMITER $$ +DROP TRIGGER IF EXISTS after_employee_update; +CREATE TRIGGER after_employee_update +AFTER UPDATE ON employee +FOR EACH ROW +BEGIN + IF NEW.job_id <> OLD.job_id THEN + INSERT INTO job_change_log() + VALUES(NEW.emp_id, OLD.job_id, NEW.job_id, NOW()); + END IF; +END $$ +DELIMITER ; +``` + + + +#### 练习题 16: 防止删除职位 + +创建一个触发器 `before_job_delete`,在删除 `job` 表数据之前,检查该职位是否还有员工。如果有员工,阻止删除并抛出错误。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_job_delete; +CREATE TRIGGER before_job_delete +BEFORE DELETE ON job +FOR EACH ROW +BEGIN + IF (SELECT COUNT(*) FROM employee WHERE job_id = OLD.job_id) > 0 THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '该职位还有员工'; + END IF; +END $$ +DELIMITER ; +``` + + + +#### 练习题 17: 自动更新部门平均工资 + +创建一个触发器 `after_employee_insert`,在插入 `employee` 表数据之后,自动更新 `department` 表中的部门平均工资(假设 `department` 表新增一个字段 `avg_salary`)。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS after_employee_insert; +CREATE TRIGGER after_employee_insert +AFTER INSERT ON employee +FOR EACH ROW +BEGIN + UPDATE department d + SET d.avg_salary = (SELECT AVG(e.salary) FROM employee e WHERE d.dept_id = e.dept_id) + WHERE NEW.dept_id = d.dept_id; + +END $$ +DELIMITER ; +``` + + + +#### 练习题 18: 防止插入未来入职日期 + +创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,检查 `hire_date` 是否晚于当前日期。如果是,阻止插入并抛出错误。 + +```sql +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_insert; +CREATE TRIGGER before_employee_insert +BEFORE INSERT ON employee +FOR EACH ROW +BEGIN + IF NEW.hire_date < CURDATE() THEN + SIGNAL SQLSTATE '45000' + SET MESSAGE_TEXT = '入职日期不得晚于当前日期'; + END IF; + +END $$ +DELIMITER ; +``` + + + +#### 练习题 19: 自动生成员工编号 + +创建一个触发器 `before_employee_insert`,在插入 `employee` 表数据时,自动生成一个唯一的员工编号(格式为 `EMP-年份-序号`,例如 `EMP-2023-001`),并将其存储到一个新字段 `emp_code` 中。 + +```sql +ALTER TABLE employee ADD emp_code VARCHAR(30); + +DELIMITER $$ +DROP TRIGGER IF EXISTS before_employee_insert; +CREATE TRIGGER before_employee_insert +BEFORE INSERT ON employee +FOR EACH ROW +BEGIN + SET NEW.emp_code = CONCAT('EMP-',YEAR(NOW()),'-', (LAST_INSERT_ID()+1)); +END $$ +DELIMITER ; +INSERT INTO employee +VALUES(DEFAULT, '雷昊', 0, NOW(), 1, 1, NULL, NULL); +``` + + + +#### 练习题 20: 记录员工离职 + +创建一个触发器 `after_employee_delete`,在删除 `employee` 表数据之后,将被删除的员工信息插入到一个离职记录表 `employee_exit_log` 中,记录员工 ID、姓名、离职时间和原因(假设原因由用户输入)。 + +```sql +CREATE TABLE employee_exit_log( + emp_id INT, + emp_name VARCHAR(20), + quit_date DATE, + quit_reason VARCHAR(50) +); + +DELIMITER $$ +DROP TRIGGER IF EXISTS after_employee_delete; +CREATE TRIGGER after_employee_delete +AFTER DELETE ON employee +FOR EACH ROW +BEGIN + INSERT INTO employee_exit_log() + VALUES(OLD.emp_id, OLD.emp_name, NOW(), NULL); +END $$ +DELIMITER ; +``` + diff --git a/调考试题/准易3月/Prog1.c b/调考试题/准易3月/Prog1.c index ec0df4a..7453a45 100644 --- a/调考试题/准易3月/Prog1.c +++ b/调考试题/准易3月/Prog1.c @@ -1,16 +1,16 @@ /*---------------------------------------------------------------------- -【程序设计】 +ơ ------------------------------------------------------------------------ -编写一个 C 语言函数,函数接收一个整数数组 arr 以及数组的长度 size 作为参数,使用 bool 类型返回该数组中是否存在重复的元素。在 main 函数中,输入多个正整数(输入非数字字符表示输入结束)并调用该函数,根据返回结果输出相应的提示信息。 -示例: -【请输入多个整数(输入非数字字符结束输入):】1 2 3 4 5 5 6 a -数组中存在重复元素。 +дһ C Ժһ arr Լij size Ϊʹ bool ͷظǷظԪء main УַʾøúݷؽӦʾϢ +ʾ +ַ룩1 2 3 4 5 5 6 a +дظԪء ------------------------------------------------------------------------ -注意:部分源程序给出如下。请勿改动主函数 main 或其它函数中给出的内容,仅在 - Program-End之间填入若干语句。 - 不要删除标志否则不得分。 - 不要修改或删除Program-End之外的内容否则不得分。 +ע⣺Դ¡Ķ main иݣ + Program-End֮䡣 + Ҫɾ־򲻵÷֡ + Ҫ޸ĻɾProgram-End֮ݷ򲻵÷֡ ----------------------------------------------------------------------*/ #include #include @@ -36,12 +36,12 @@ int main() { int *arr = (int *)malloc(capacity * sizeof(int)); if (arr == NULL) { - printf("内存分配失败!\n"); + printf("ڴʧܣ\n"); return 1; } int size = 0; int num; - printf("【请输入多个整数(输入非数字字符结束输入):】"); + printf("ַ룩"); while (scanf("%d", &num) == 1) { @@ -50,7 +50,7 @@ int main() { arr = (int *)realloc(arr, capacity * sizeof(int)); if (arr == NULL) { - printf("内存分配失败!\n"); + printf("ڴʧܣ\n"); return 1; } } @@ -62,9 +62,9 @@ int main() { if (hasDuplicates(arr, size)) { - printf("数组中存在重复元素。\n"); + printf("дظԪء\n"); } else { - printf("数组中不存在重复元素。\n"); + printf("вظԪء\n"); } diff --git a/调考试题/准易3月/Prog2.c b/调考试题/准易3月/Prog2.c index bac2be0..d85fda8 100644 --- a/调考试题/准易3月/Prog2.c +++ b/调考试题/准易3月/Prog2.c @@ -1,43 +1,43 @@ /*---------------------------------------------------------------------- -【程序设计】 +ơ ------------------------------------------------------------------------ -现在有一位赛车手要驾驶一台电动摩托车去完成多段赛程。这台电动摩托车的电池电量存储 -上限是 100 度电哦,它有一个标称的平均电耗,也就是每行驶 100 公里,就会消耗 10度 -电。这里有个很重要的前提条件要大家牢记呀,每一段赛程的距离都是小于 600 公里的哦, -并且每次出发的时候,电动摩托车的电池都是充满电的状态呢。还有一个关键的规则得注意 -哦,如果电动摩托车到达某个地点之后,赛车手查看发现电池内剩余的电量低于电池总电量 -的 10%(也就是 100×10% = 10 度电或者更少啦),那这个时候就必须得在这个地方给电 -动摩托车充电了呢,请帮忙计算一下,这名驾驶员在赛程中的哪几段赛程前是需要充电的。 +һλҪʻһ̨綯Ħгȥɶ̡̨綯Ħгĵص洢 + 100 ȵŶһƵƽģҲÿʻ 100 ͻ 10 +硣иҪǰҪμѽÿһ̵ľ붼С 600 Ŷ +ÿγʱ򣬵綯Ħгĵضdz״̬ءһؼĹע +Ŷ綯Ħгijصֲ֮鿴ֵʣĵڵܵ + 10%Ҳ 10010% = 10 ȵ߸ʱͱط +Ħгأæһ£ʻԱеļǰҪġ -示例1: -【请输入赛程段数:】 +ʾ1 +̶ 5 -【请输入各段赛程距离,单位公里:】 +̾룬λ 380 200 390 400 300 -【需要在以下几段赛程前充电:】 -第 3 段赛程前 -第 5 段赛程前 +Ҫ¼ǰ磺 + 3 ǰ + 5 ǰ -示例2: -【请输入赛程段数:】 +ʾ2 +̶ 4 -【请输入各段赛程距离,单位公里:】 +̾룬λ 190 140 110 80 -无需充电。 +硣 ------------------------------------------------------------------------ -注意:部分源程序给出如下。请勿改动主函数 main 或其它函数中给出的内容,仅在 - Program-End之间填入若干语句。 - 不要删除标志否则不得分。 - 不要修改或删除Program-End之外的内容否则不得分。 +ע⣺Դ¡Ķ main иݣ + Program-End֮䡣 + Ҫɾ־򲻵÷֡ + Ҫ޸ĻɾProgram-End֮ݷ򲻵÷֡ ----------------------------------------------------------------------*/ #include -#include // 引入stdlib.h用于动态内存分配相关操作 +#include // stdlib.hڶ̬ڴز -#define TANK_CAPACITY 100 // 电池总容量(单位:度) -#define LOW_FUEL_LIMIT (0.10 * TANK_CAPACITY) // 低电量阈值(10%) -#define AVG_CONSUMPTION_PER_100KM 10 // 平均电耗(单位:度/百公里) -#define FUEL_CONSUMPTION_PER_KM (AVG_CONSUMPTION_PER_100KM / 100.0) // 每公里电耗(单位:度/公里) +#define TANK_CAPACITY 100 // λȣ +#define LOW_FUEL_LIMIT (0.10 * TANK_CAPACITY) // ͵ֵ10% +#define AVG_CONSUMPTION_PER_100KM 10 // ƽģλ/ٹ +#define FUEL_CONSUMPTION_PER_KM (AVG_CONSUMPTION_PER_100KM / 100.0) // ÿģλ/ int checkRefuelStops(int trips[], int count, int results[]) { int refuel_count = 0; @@ -56,17 +56,17 @@ int checkRefuelStops(int trips[], int count, int results[]) { int main() { int num_trips; - printf("【请输入赛程段数:】\n"); + printf("̶\n"); scanf("%d", &num_trips); int *trips = (int *)malloc(num_trips * sizeof(int)); if (trips == NULL) { - printf("内存分配失败!\n"); + printf("ڴʧܣ\n"); return 1; } - printf("【请输入各段赛程距离,单位公里:】\n"); + printf("̾룬λ\n"); for (int i = 0; i < num_trips; ++i) { scanf("%d", &trips[i]); } @@ -74,7 +74,7 @@ int main() { int *results = (int *)malloc(num_trips * sizeof(int)); if (results == NULL) { - printf("内存分配失败!\n"); + printf("ڴʧܣ\n"); free(trips); return 1; } @@ -82,12 +82,12 @@ int main() { int refuel_count = checkRefuelStops(trips, num_trips, results); if (refuel_count > 0) { - printf("【需要在以下几段赛程前充电:】\n"); + printf("Ҫ¼ǰ磺\n"); for (int i = 0; i < refuel_count; i++) { - printf("第 %d 段赛程前\n", results[i]); + printf(" %d ǰ\n", results[i]); } } else { - printf("无需充电。\n"); + printf("硣\n"); } free(trips);