• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    一篇文章带你掌握SQLite3基本用法

    发布者: 天下网吧 | 发布时间: 2025-6-18 14:44| 查看数: 119| 评论数: 0|帖子模式

    一、基本语法


    1.常用指令
    1. .open filename --打开文件
    2. -- 注解
    3. .show --显示SQLite 命令提示符的默认设置
    4. .q --退出
    5. .databases --显示数据库(注:显示打开的数据库)
    6. .help  --帮助
    7. .dump  --导入导出数据库
    8. .tables  --查看表
    复制代码
    2.数据类型

    存储类型描述
    NULL空值
    int整形
    text一个文本字符串
    blob一个blob数据
    integer一个带符号的整数,根据值的大小存储在1、2
    、3、4、6或8字节中
    real值是一个浮点值,存储为8字节的浮点数
    ............

    3.创建数据库
    1. .open test.db --没有就创建
    2. sqlite3 DatabaseName.db
    复制代码

    上面的命令将在当前目录下创建一个文件 testDB.db。该文件将被 SQLite 引擎用作数据库。如果您已经注意到 sqlite3 命令在成功创建数据库文件之后,将提供一个 sqlite> 提示符。
    .databases 命令用于检查它是否在数据库列表中。
    .open 操作


    4. 导入/导出数据库
    1. sqlite3 test.db .dump > filename --导出
    2. sqlite3 test.db < filename --导入
    复制代码

    上面的转换流整个 testDB.db 数据库的内容到 SQLite 的语句中,并将其转储到 ASCII 文本文件 testDB.sql 中。您可以通过简单的方式从生成的 testDB.sql 恢复,如下所示 我删掉testDB.db后:


    5.创建表
    1. --注意,在打开数据库时才能操作
    2. CREATE TABLE database_name.table_name(
    3.    column1 datatype  PRIMARY KEY(one or more columns),
    4.    column2 datatype,
    5.    column3 datatype,
    6.    .....
    7.    columnN datatype,
    8. );
    复制代码
    CREATE TABLE 是告诉数据库系统创建一个新表的关键字。CREATE TABLE 语句后跟着表的唯一的名称或标识。您也可以选择指定带有 table_name 的 database_name。

    如上图所示,我们创建了COMPANY     DEPARTMENT两个表。其中ID 作为主键,NOT NULL 的约束表示在表中创建纪录时这些字段不能为 NULL。

    6.查看表的详细信息
    1. .schema --注意:打开数据库时才能操作
    复制代码


    7.删除表
    1. DROP TABLE database_name.table_name;
    复制代码

    如上,删除了名为DEPARTMENT的表

    8.插入数据
    1. INSERT INTO TABLE_NAME [(column1, column2, column3,...columnN)]  
    2. VALUES (value1, value2, value3,...valueN);
    复制代码
    在这里,column1, column2,...columnN 是要插入数据的表中的列的名称。
    如果要为表中的所有列添加值,您也可以不需要在 SQLite 查询中指定列名称。但要确保值的顺序与列在表中的顺序一致。SQLite 的 INSERT INTO 语法如下:
    1. INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);
    复制代码
    现在,我已经创建了COMPANY表,如下
    1. CREATE TABLE COMPANY(
    2.    ID INT PRIMARY KEY     NOT NULL,
    3.    NAME           TEXT    NOT NULL,
    4.    AGE            INT     NOT NULL,
    5.    ADDRESS        CHAR(50),
    6.    SALARY         REAL
    7. );
    复制代码
    现在,下面的语句将在 COMPANY 表中创建六个记录:
    1. INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
    2. VALUES (1, 'Paul', 32, 'California', 20000.00 );

    3. INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
    4. VALUES (2, 'Allen', 25, 'Texas', 15000.00 );

    5. INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
    6. VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );

    7. INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
    8. VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );

    9. INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
    10. VALUES (5, 'David', 27, 'Texas', 85000.00 );

    11. INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
    12. VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );
    复制代码
    输出结果如下:

    我们也可以使用第二种语法在COMPANY 表中创建一个记录,如下所示:
    1. INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );
    复制代码
    输出结果如下:


    9.格式化输出
    1. .header on
    2. .mode column
    3. .timer on --开启CPU定时器
    4. SELECT * FROM table_name; --显示表table_name
    复制代码
    非格式化输出

    格式化输出


    10.输出表

    完整输出
    1. .header on
    2. .mode column
    3. SELECT * FROM COMPANY;
    复制代码

    输出指定列
    1. .header on
    2. .mode column
    3. SELECT ID, NAME, SALARY FROM COMPANY; --只输出ID, NAME和SALARY三列
    复制代码

    设置输出列的宽度
    1. .width num1,num1,num3....
    2. SELECT * FROM COMPANY;
    复制代码
    下面 .width 命令设置第一列的宽度为 10,第二列的宽度为 20,第三列的宽度为 10。输出结果如下:


    11.运算符

    sqlite运算符主要用于 SQLite 语句的 WHERE 子句中执行操作,如比较和算术运算。
    运算符用于指定 SQLite 语句中的条件,并在语句中连接多个条件。
    算术运算符:
    运算符描述实例+加法 - 把运算符两边的值相加a + b 将得到 30-减法 - 左操作数减去右操作数a - b 将得到 -10*乘法 - 把运算符两边的值相乘a * b 将得到 200/除法 - 左操作数除以右操作数b / a 将得到 2%取模 - 左操作数除以右操作数后得到的余数b % a will give 0
    比较运算符
    运算符描述实例+加法 - 把运算符两边的值相加a + b 将得到 30-减法 - 左操作数减去右操作数a - b 将得到 -10*乘法 - 把运算符两边的值相乘a * b 将得到 200/除法 - 左操作数除以右操作数b / a 将得到 2%取模 - 左操作数除以右操作数后得到的余数b % a will give 0逻辑运算符
    运算符描述实例==检查两个操作数的值是否相等,如果相等则条件为真。(a == b) 不为真。=检查两个操作数的值是否相等,如果相等则条件为真。(a = b) 不为真。!=检查两个操作数的值是否相等,如果不相等则条件为真。(a != b) 为真。<>检查两个操作数的值是否相等,如果不相等则条件为真。(a <> b) 为真。>检查左操作数的值是否大于右操作数的值,如果是则条件为真。(a > b) 不为真。<检查左操作数的值是否小于右操作数的值,如果是则条件为真。(a < b) 为真。>=检查左操作数的值是否大于等于右操作数的值,如果是则条件为真。(a >= b) 不为真。<=检查左操作数的值是否小于等于右操作数的值,如果是则条件为真。(a <= b) 为真。!<检查左操作数的值是否不小于右操作数的值,如果是则条件为真。(a !< b) 为假。!>检查左操作数的值是否不大于右操作数的值,如果是则条件为真。(a !> b) 为真。位运算符  
    pqp & qp | q0000010111111001下面直接上例子
    我有COMPANY 表如下:
    1. ID          NAME        AGE         ADDRESS     SALARY
    2. ----------  ----------  ----------  ----------  ----------
    3. 1           Paul        32          California  20000.0
    4. 2           Allen       25          Texas       15000.0
    5. 3           Teddy       23          Norway      20000.0
    6. 4           Mark        25          Rich-Mond   65000.0
    7. 5           David       27          Texas       85000.0
    8. 6           Kim         22          South-Hall  45000.0
    9. 7           James       24          Houston     10000.0
    复制代码
    用 SELECT列出SALARY 大于 50,000.00 的所有记录:
    1. SELECT * FROM COMPANY WHERE SALARY > 50000;
    复制代码
    输出结果如下:

    用 SELECT列出SALARY 等于的所有记录:
    1. SELECT * FROM COMPANY WHERE SALARY = 20000;
    复制代码
    输出结果如下:

    用 SELECT列出AGE 大于等于 25 SALARY大于等于 65000.00的所有记录:
    1. SELECT * FROM COMPANY WHERE AGE >= 25 AND SALARY >= 65000;
    复制代码
    输出结果如下:


    12.where子句

    SQLite的 WHERE 子句用于指定从一个表或多个表中获取数据的条件。如果满足给定的条件,即为真(true)时,则从表中返回特定的值。您可以使用 WHERE 子句来过滤记录,只获取需要的记录。WHERE 子句不仅可用在 SELECT 语句中,它也可用在 UPDATE、DELETE 语句中,等等。用例参考运算符。

    13.删除记录表中的数据

    SQLite中,删除记录表数据为DELETE语句,我们可以使用带有 WHERE 子句的 DELETE。
    语法如下:
    1. DELETE FROM table_name WHERE [condition];
    复制代码
    我们有以下记录表:

    删除ID为7的列:
    1. DELETE FROM COMPANY WHERE ID = 7;
    复制代码
    再次输出结果:


    14.update语句

    SQLite 的 UPDATE 查询用于修改表中已有的记录。可以使用带有 WHERE 子句的 UPDATE 查询来更新选定行,否则所有的行都会被更新。
    语法:
    1. UPDATE table_name 
    2. SET column1 = value1, column2 = value2...., columnN = valueN
    3. WHERE [condition];
    复制代码
    注:这三行实为同一行。
    现在我有数据表如下:

    把COMPANY表中ID 为 6 的客户地址改为Texas:
    1. UPDATE COMPANY SET ADDRESS = 'Texas' WHERE ID = 6;
    复制代码
    修改结果:

    如果您想修改 COMPANY 表中 ADDRESS 和 SALARY 列的所有值,则不需要使用 WHERE 子句,UPDATE 查询如下:
    1. UPDATE COMPANY SET ADDRESS = 'Texas', SALARY = 20000.00;
    复制代码
    修改结果:


    二、C/C++操作         


    1.接口API

    下面接口能满足我们的基本需求,需要学习更多的操作,我们可以参考官方文档。
    序号API & 描述1sqlite3_open(const char *filename, sqlite3 **ppDb)该例程打开一个指向 SQLite 数据库文件的连接,返回一个用于其他 SQLite 程序的数据库连接对象。
    如果 filename 参数是 NULL 或 ':memory:',那么 sqlite3_open() 将会在 RAM 中创建一个内存数据库,这只会在 session 的有效时间内持续。
    如果文件名 filename 不为 NULL,那么 sqlite3_open() 将使用这个参数值尝试打开数据库文件。如果该名称的文件不存在,sqlite3_open() 将创建一个新的命名为该名称的数据库文件并打开。
    2sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void *data, char **errmsg)该例程提供了一个执行 SQL 命令的快捷方式,SQL 命令由 sql 参数提供,可以由多个 SQL 命令组成。
    在这里,第一个参数 sqlite3 是打开的数据库对象,sqlite_callback 是一个回调,data 作为其第一个参数,errmsg 将被返回用来获取程序生成的任何错误。
    sqlite3_exec() 程序解析并执行由 sql 参数所给的每个命令,直到字符串结束或者遇到错误为止。
    3sqlite3_close(sqlite3*)该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。
    如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。

    2.连接数据库

    下面的 C 代码段显示了如何连接到一个现有的数据库。如果数据库不存在,那么它就会被创建,最后将返回一个数据库对象。
    1. #include <stdio.h>
    2. #include <sqlite3.h>

    3. int main(int argc, char* argv[])
    4. {
    5.    sqlite3 *db;
    6.    char *zErrMsg = 0;
    7.    int rc;

    8.    rc = sqlite3_open("test.db", &db);

    9.    if( rc ){
    10.       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    11.       exit(0);
    12.    }else{
    13.       fprintf(stderr, "Opened database successfully\n");
    14.    }
    15.    sqlite3_close(db);
    16. }
    复制代码
    编译命令      
    1. gcc lianjie.c -l sqlite3
    复制代码
    运行结果

    终端输入ls -l命令发现多了个test.db文件,如图:


    3.创建表

    C语言创建表与终端创建操作差不多,只不过命令由sqlite3_exec()函数的sql参数传入。格式如下:
    1. sql = "CREATE TABLE COMPANY("  \
    2.          "ID INT PRIMARY KEY     NOT NULL," \
    3.          "NAME           TEXT    NOT NULL," \
    4.          "AGE            INT     NOT NULL," \
    5.          "ADDRESS        CHAR(50)," \
    6.          "SALARY         REAL );";
    复制代码
    示例代码:
    1. #include <stdio.h>#include <stdlib.h>#include <sqlite3.h>  static int callback(void *NotUsed, int argc, char **argv, char **azColName){   int i;   for(i=0; i<argc; i++){      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");   }   printf("\n");   return 0;} int main(int argc, char* argv[]){   sqlite3 *db;   char *zErrMsg = 0;   int  rc;   char *sql;    /* Open database */   rc = sqlite3_open("test.db", &db);   if( rc ){      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));      exit(0);   }else{      fprintf(stdout, "Opened database successfully\n");   }    /* Create SQL statement */   sql = "CREATE TABLE COMPANY("  \
    2.          "ID INT PRIMARY KEY     NOT NULL," \
    3.          "NAME           TEXT    NOT NULL," \
    4.          "AGE            INT     NOT NULL," \
    5.          "ADDRESS        CHAR(50)," \
    6.          "SALARY         REAL );";    /* Execute SQL statement */   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);   if( rc != SQLITE_OK ){   fprintf(stderr, "SQL error: %s\n", zErrMsg);      sqlite3_free(zErrMsg);   }else{      fprintf(stdout, "Table created successfully\n");   }   sqlite3_close(db);   return 0;}
    复制代码
    输出结果:

    再次ls -l:

    我们可以看到,test.db文件大小明显变大了。

    4.插入数据

    与创建表类似,sql参数设为:
    1.   sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
    2.          "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
    3.          "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
    4.          "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
    5.          "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
    6.          "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
    7.          "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
    8.          "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";
    复制代码
    示例代码:
    1. #include <stdio.h>#include <stdlib.h>#include <sqlite3.h> static int callback(void *NotUsed, int argc, char **argv, char **azColName){   int i;   for(i=0; i<argc; i++){      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");   }   printf("\n");   return 0;} int main(int argc, char* argv[]){   sqlite3 *db;   char *zErrMsg = 0;   int rc;   char *sql;    /* Open database */   rc = sqlite3_open("test.db", &db);   if( rc ){      fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));      exit(0);   }else{      fprintf(stderr, "Opened database successfully\n");   }    /* Create SQL statement */   sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
    2.          "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
    3.          "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
    4.          "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
    5.          "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
    6.          "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
    7.          "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
    8.          "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";    /* Execute SQL statement */   rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);   if( rc != SQLITE_OK ){      fprintf(stderr, "SQL error: %s\n", zErrMsg);      sqlite3_free(zErrMsg);   }else{      fprintf(stdout, "Records created successfully\n");   }   sqlite3_close(db);   return 0;}
    复制代码
    输出结果:


    5.查表操作

    sqlite3_exec()给我们提供了一个回调函数,其声明如下:
    1. typedef int (*sqlite3_callback)(
    2. void*,    /* Data provided in the 4th argument of sqlite3_exec() */
    3. int,      /* The number of columns in row */
    4. char**,   /* An array of strings representing fields in the row */
    5. char**    /* An array of strings representing column names */
    6. );
    复制代码
    第一个参数:即第四个参数传入的数据
    第二个参数:行中的列数
    第三个参数:表示行中字段的字符串数组,即各行中的数据
    第四个参数:表示列名的字符串数组,创建链表时设置的
    执行流程:查表,是否还有符合条件数据。有,执行sqlite3_callback()函数;没有,退出
    用法讲完了,下面看例子:      
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <sqlite3.h>

    4. static int callback(void *data, int argc, char **argv, char **azColName){
    5.    int i;
    6.    fprintf(stderr, "%s: ", (const char*)data);
    7.    for(i=0; i<argc; i++){
    8.       printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    9.    }
    10.    printf("\n");
    11.    return 0;
    12. }

    13. int main(int argc, char* argv[])
    14. {
    15.    sqlite3 *db;
    16.    char *zErrMsg = 0;
    17.    int rc;
    18.    char *sql;
    19.    const char* data = "Callback function called";

    20.    /* Open database */
    21.    rc = sqlite3_open("test.db", &db);
    22.    if( rc ){
    23.       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    24.       exit(0);
    25.    }else{
    26.       fprintf(stderr, "Opened database successfully\n");
    27.    }

    28.    /* Create SQL statement */
    29.    sql = "SELECT * from COMPANY";

    30.    /* Execute SQL statement */
    31.    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
    32.    if( rc != SQLITE_OK ){
    33.       fprintf(stderr, "SQL error: %s\n", zErrMsg);
    34.       sqlite3_free(zErrMsg);
    35.    }else{
    36.       fprintf(stdout, "Operation done successfully\n");
    37.    }
    38.    sqlite3_close(db);
    39.    return 0;
    40. }
    复制代码
    上面程序显示了如何从前面创建的 COMPANY 表中获取并显示记录,输出结果如下:

    这里我没有特殊指明查询条件,表示查询全部。

    6.数据删除操作

    sql参数设置:
    1. sql = "DELETE from COMPANY where ID=2; " \\删除ID等于2的行
    2.          "SELECT * from COMPANY";        \\显示表
    复制代码
    这里跟上面不同的是多了一个命令,表面sql参数可由多个命令组成。
    示例代码:
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <sqlite3.h>

    4. static int callback(void *data, int argc, char **argv, char **azColName){
    5.    int i;
    6.    fprintf(stderr, "%s: ", (const char*)data);
    7.    for(i=0; i<argc; i++){
    8.       printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    9.    }
    10.    printf("\n");
    11.    return 0;
    12. }

    13. int main(int argc, char* argv[])
    14. {
    15.    sqlite3 *db;
    16.    char *zErrMsg = 0;
    17.    int rc;
    18.    char *sql;
    19.    const char* data = "Callback function called";

    20.    /* Open database */
    21.    rc = sqlite3_open("test.db", &db);
    22.    if( rc ){
    23.       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    24.       exit(0);
    25.    }else{
    26.       fprintf(stderr, "Opened database successfully\n");
    27.    }

    28.    /* Create merged SQL statement */
    29.    sql = "DELETE from COMPANY where ID=2; " \
    30.          "SELECT * from COMPANY";

    31.    /* Execute SQL statement */
    32.    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
    33.    if( rc != SQLITE_OK ){
    34.       fprintf(stderr, "SQL error: %s\n", zErrMsg);
    35.       sqlite3_free(zErrMsg);
    36.    }else{
    37.       fprintf(stdout, "Operation done successfully\n");
    38.    }
    39.    sqlite3_close(db);
    40.    return 0;
    41. }
    复制代码
    输出:


    7.UPDATE 操作

    操作示例:
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <sqlite3.h>

    4. static int callback(void *data, int argc, char **argv, char **azColName){
    5.    int i;
    6.    fprintf(stderr, "%s: ", (const char*)data);
    7.    for(i=0; i<argc; i++){
    8.       printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    9.    }
    10.    printf("\n");
    11.    return 0;
    12. }

    13. int main(int argc, char* argv[])
    14. {
    15.    sqlite3 *db;
    16.    char *zErrMsg = 0;
    17.    int rc;
    18.    char *sql;
    19.    const char* data = "Callback function called";

    20.    /* Open database */
    21.    rc = sqlite3_open("test.db", &db);
    22.    if( rc ){
    23.       fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    24.       exit(0);
    25.    }else{
    26.       fprintf(stderr, "Opened database successfully\n");
    27.    }

    28.    /* Create merged SQL statement */
    29.    sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1; " \
    30.          "SELECT * from COMPANY";

    31.    /* Execute SQL statement */
    32.    rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
    33.    if( rc != SQLITE_OK ){
    34.       fprintf(stderr, "SQL error: %s\n", zErrMsg);
    35.       sqlite3_free(zErrMsg);
    36.    }else{
    37.       fprintf(stdout, "Operation done successfully\n");
    38.    }
    39.    sqlite3_close(db);
    40.    return 0;
    41. }
    复制代码
    输出结果:


    三:结语

    现在,关于sqlite3的基本用法都讲完了,有不对的地方欢迎指出。
    到此这篇关于SQLite3基本用法的文章就介绍到这了,更多相关SQLite3基本用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:https://www.jb51.net/article/251308.htm
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    浏览过的版块

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表