qidao123.com技术社区-IT企服评测·应用市场
标题:
常见的SQL语句/SQL Server的使用教程
[打印本页]
作者:
干翻全岛蛙蛙
时间:
2025-5-5 06:13
标题:
常见的SQL语句/SQL Server的使用教程
1. 媒介
这是本人在学习过程中所熟知的SQL语句,使用方法、语句上会有遗漏,写法仅作参考,且语句的语法采用的是SQL Server的语法而不是My SQL。本文不包含SQL Server的安装和连接教程。
2. 数据库的创建、修改和删除
在连接成功后右击点击"新建查询"按键,便可进入到查询页面,在这里就可以编写所需要的SQL语句。
进入查询页面后,我们先创建一个学生管理数据库(StudentDB),具体的SQL 语句如下:
create database StudentDB
复制代码
写好语句后点击绿色的实行按钮便可实行,实行结果如下所示,我们已经成功创建了StudentDB数据库:
数据库名的修改和数据库删除不做具体演示,这里贴出SQL语句做参考即可
--修改数据库语句有两个,任选其一即可
exec sp_renamedb @dbname='旧数据库名',@newname='新数据库名';
Alter database 旧数据库名 modify name = 新数据库名;
--删除数据库语句
Drop databse 数据库名;
复制代码
3. 数据库表的创建、修改和删除
3.1 数据表的创建
创建了数据库但是打开表一看,发现里面没有一张表,这时候需要我们在该数据库中创建一些表,现在先创建学生信息表(StudentInfo)和成绩表(Score)。
像创建数据库时那样,右击StudentDB点击新建查询,在新的查询页面下编写SQL语句,至于为什么不在刚刚的页面下编写,是因为在刚刚创建数据库的查询页面下编写SQL 语句创建的表会创建在"数据库"文件夹下的"系统数据库"文件夹下的master数据库。现在先举行创建数据表再对表中的语法举行表明。
--学生信息表的创建
create table StudentInfo(
id int primary key identity(1,1),
name nvarchar(8),
age int not null,
sex int default(1),
score_id int
)
--成绩表的创建
create table Score(
id int primary key,
Math decimal(3,1),
Chinese decimal(3,1),
English decimal(3,1)
)
复制代码
创表语句写好后,点击运行便可在StudentDB数据库中看到这两张表,点开列和键还能看到创建的字段和主键。
接下来,便是对创表操纵里的一些语法举行表明。如下所示:
3.1.1 数据范例介绍
3.1.1.1 整数范例
int:占4个字节,共32位,其可表示的范围为
-2147483648~2147483647
,用于存储通例整数值,适用于大多数整数数据。
bigint:占8个字节,共64位,其可表示的范围为
-9 223 372 036 854 775 808 ~9 223 372 036 854 775 807
,用于存储较大的整数值,当整数大概超出 int 范围时使用。
smallint:占2个字节,共16位,其可表示的范围为
-32768 ~ 32767
,用于存储较小的整数值,可以节流存储空间。
typeint:占1个字节,共8位,其可表示的范围为
0 ~ 255
,用于存储小范围的非负整数值。
3.1.1.2 小数范例
decimal(p, s):用于存储准确的小数值,其中,p表示指定精度或对象可以或许控制的数字个数。s则是指定可放到小数点右边的小数位数或数字个数。且p和s必须遵守0<=s<=p<=38。在刚刚的创表案例中,我在成绩表都使用decimal(3, 1) (
注:实在设置成3和1会有bug,这在之后修改表的操纵中会讲
),表示语数英的成绩最多只有三个数字,且准确到小数点后一位,如果小数点后有两位及以上会举行四舍五入操纵,比方,数学成绩为85.48则会准确为85.5。
float:数据范例占8个字节,共64位,可以或许存储-1.79E+308~1.79E+308之间所有的浮点数。float数据范例可准确到第15位小数。float数据范例可以定义为float(n),n为数据的精度。
real:数据范例占4个字节,共32位,可以或许存储-3.40E+38~3.40E+38之间所有的浮点数。
3.1.1.3 字符和文本范例
nvarchar(n):可变长度的 Unicode 字符串,适用于存储变长的文本数据,支持多语言。
varchar(n):可变长度的字符型数据,适用于存储变长的 ASCII 字符串。
char(n):固定长度的字符型数据,适用于存储固定长度的字符串,比方状态码等。
text:用于存储较大的文本数据,不建议频仍使用,但可以用于存储较长的文本内容。
3.1.1.4 日期和时间范例
datetime:用于存储日期和时间。可以存储从公元1753年1月1日零时起到公元9999年12月31日23时59分59秒之间的所有日期和时间,其准确度可达三百分之一秒。datetime数据范例占用8个字节的存储空间。
date:用于存储日期部分。
time:用于存储时间部分。
smalldatetime:与datetime雷同,但其日期时间范围较小,可以存储从1900年1月1日到2079年6月6日,精度可以达到分钟。smalldatetime数据范例占用4个字节的存储空间。
3.1.1.5 二进制范例
varbinary(n):可变长的二进制范例,存储变长的二进制内容,如图片、文件等。
binary(n):定长的二进制范例,可用于存储固定长度的二进制内容。
3.1.1.6 其它数据范例
bit:用于存储布尔值,通常用于表示真/假、启用/禁用等状态。
uniqueidentifier:用于存储全局唯一标识符 (GUID),适用于唯一标识记录。
sql_variant:可以存储任意 SQL Server 数据范例的数据,但使用时需要警惕处理。
money:使用8个字节存储数据,由两部分组成,前面4个字节表示钱币值的整数部分,背面4个字节表示钱币值的小数部分。
smallmoney:雷同于money范例,使用4个字节存储数据,前面2个字节表示钱币值的整数部分,背面2个字节表示钱币值的小数部分。
3.1.2 主键和外键
在关系型数据库中,
主键(Primary Key)
和
外键(Foreign Key)
是两个紧张的概念。其中
主键
用来唯一标识关系表中每一行数据的字段或字段组合,
外键
是用来建立表与表之间关系的字段。外键是关联另一个表的主键,从而在表之间创建关系。
主键
具有以下特性:
1.唯一性:主键的值在表中必须是唯一的,不能重复。
2.非空性:主键字段的值不能为空,不能为空值被以为是一个无效的主键值。
3.稳定性:主键值一旦确定,就不应该被修改。
4.永久性:主键值在整个数据的生命周期中是唯一稳定的。
外键
具有以下特性:
1.引用关系:外键字段关联到另一个表的主键字段,以建立两个表之间的关系。
2.数据一致性:外键用于保持表之间的数据一致性,确保引用的数据存在于被引用的表中。
3.可空性:外键字段可以答应为空(null),表示该行数据没有关联到其他表的数据。
在刚刚的创表案例中,StudentInfo表和Score表都使用了id作为主键,而StudentInfo中score_id字段则作为外键用于关联Score表。这里只是对其举行一个简单介绍,具体可移步查看:MySQL底子:什么是主键和外键?它们之间有什么区别?外键有什么问题?
3.1.3 identity和default
identity
唯一游标,和My SQL中使用的
Auto-increment
结果一样,用来举行自动递增,其写法如下所示,在刚刚的案例中给StudentInfo表的id字段设置identity(1,1)表示从1开始,每次递增1,比方第一名学生的id为1,第二名则为2,以此类推。
IDENTITY(起始位置,每次递增数)
复制代码
default
默认值,在刚刚的案例中我们设置sex为default(1),表示如果性别没填写则默认值为1。(
注:为什么不用字符范例的字段来填写男和女?因为通常使用1表示男 0表示女,如许在写逻辑判定时也比较方便
)
3.2 数据表的修改和删除
3.2.1 表的修改和删除
表名的修改常采用exec语句,本案例中要修改Score表名为SC。
--修改表名的格式
exec sp_rename '旧表名','新表名';
--例如我要修改Score表的表名为SC
exec sp_rename 'Score','SC';
复制代码
修改前:
修改后:
表的删除语句常用drop语句,本案例中便不再演示,只展示相干格式。
DROP TABLE '表名'
复制代码
3.2.2 表中字段的修改和删除
在创建表时设置语数英的数据范例为decimal(3,1)咋一看挺公道的,假设某天有个小朋侪考了100分,这时在数据库写入100便会出现如许的错误。
这时想起来不应该设置成decimal(3,1),而是decimal(4,1),此时如果要修改表中字段的数据范例就需要
alter
语句。
--修改表中字段数据类型语句的格式
ALTER TABLE 表名 ALTER COLUMN 字段名 字段类型;
ALTER TABLE SC ALTER COLUMN Math decimal(4,1);
ALTER TABLE SC ALTER COLUMN Chinese decimal(4,1);
ALTER TABLE SC ALTER COLUMN English decimal(4,1);
复制代码
实行完成后,录入100分时便不会出现上述的报错了。
现在我们发现StudentInfo表中需要parent字段用来记录每个学生的父母,但建表时并没有parent字段,此时还是需要alter语句来为表添加字段。
--格式如下
ALTER TABLE 表名 ADD 新增字段名 字段类型 默认值;
ALTER TABLE StudentInfo ADD parent nvarchar(8);
复制代码
实行完成后便可看到StudentInfo表下有一个parent字段。
接下来还有字段删除、删除字段束缚或键、修改字段名语句,这里只给出相干格式,不做具体演示了。
--删除字段的语句格式
ALTER TABLE 表名 DROP COLUMN 字段名;
--删除字段约束或键的语句格式
ALTER TABLE 表名 DROP CONSTRAINT 约束名或键名;
--修改字段名的语句格式
EXEC SP_RENAME '表名.原字段名','新字段名';
复制代码
3.2.3 表注释说明和表中字段注释说明
现在我们发现表和表中字段没有注释说明,虽然现在只有两张表,表中字段也不多,但在现实项目中的表和字段远比现在案例中的多,因此需要给表和表中字段加上注释来方便阅读。
--添加表注释说明格式
EXECUTE SP_ADDEXTENDEDPROPERTY N'MS_Description', N'表注释说明', N'SCHEMA', N'DBO',N'TABLE', N'表名', NULL, NULL;
--现在我们给StudentInfo表和SC表分别加上"学生信息表"和"成绩表"的注释说明
EXECUTE sp_addextendedproperty N'描述',N'学生信息表',N'SCHEMA',N'DBO',N'TABLE',N'StudentInfo',NULL,NULL;
EXECUTE sp_addextendedproperty N'描述',N'成绩表',N'SCHEMA',N'DBO',N'TABLE',N'SC',NULL,NULL;
复制代码
加上之后结果如下。
假如哪天我们需要修改或删除表的注释说明可以使用下面两句来举行修改或删除。
--修改表注释说明的格式
EXECUTE SP_UPDATEEXTENDEDPROPERTY 'MS_Description','修改表注释说明','SCHEMA','DBO','TABLE','表名',NULL,NULL;
--删除表注释说明的格式
EXECUTE SP_DROPEXTENDEDPROPERTY 'MS_Description','SCHEMA','DBO','TABLE','表名',NULL,NULL;
复制代码
表中字段也可以举行注释说明,现在演示将StudentInfo表中age,sex,score_id和SC表中的Math,Chinese,English举行注释说明。
--添加字段的注释说明格式
EXECUTE SP_ADDEXTENDEDPROPERTY N'MS_Description', '需要注释的内容', N'SCHEMA', N'DBO', N'TABLE', N'表名', N'COLUMN', N'字段名';
--SudentInfo表的字段添加注释说明
EXECUTE sp_addextendedproperty N'描述','年龄',N'SCHEMA',N'DBO',N'TABLE',N'StudentInfo',N'COLUMN',N'age';
EXECUTE sp_addextendedproperty N'描述','性别',N'SCHEMA',N'DBO',N'TABLE',N'StudentInfo',N'COLUMN',N'sex';
EXECUTE sp_addextendedproperty N'描述','成绩id',N'SCHEMA',N'DBO',N'TABLE',N'StudentInfo',N'COLUMN',N'score_id';
--SC表的字段添加注释说明
EXECUTE sp_addextendedproperty N'描述','数学',N'SCHEMA',N'DBO',N'TABLE',N'SC',N'COLUMN',N'Math';
EXECUTE sp_addextendedproperty N'描述','语文',N'SCHEMA',N'DBO',N'TABLE',N'SC',N'COLUMN',N'Chinese';
EXECUTE sp_addextendedproperty N'描述','英语',N'SCHEMA',N'DBO',N'TABLE',N'SC',N'COLUMN',N'English';
复制代码
添加注释后的结果如下所示 。
日后如果要对表中字段的注释说明举行修改或删除,可以使用以下两句。
--修改字段注释说明格式
EXECUTE SP_UPDATEEXTENDEDPROPERTY 'MS_Description', '修改注释的内容','SCHEMA','DBO','TABLE','表名','COLUMN','字段名';
--删除字段注释说明格式
EXECUTE SP_DROPEXTENDEDPROPERTY 'MS_Description','SCHEMA','DBO','TABLE','表名','COLUMN','字段名';
复制代码
4. 表中数据的新增、删除、修改、查询
4.1 表中数据的新增
表中数据的新增可以使用insert语句,现在我们先往StudentInfo表中新增三个学生的信息。
--新增数据的格式
insert into 表名(字段1,字段2,...) vaules (字段1对应数据,字段2对应数据,...),(字段1对应数据,字段2对应数据,...),....
--向StudentInfo表新增三条数据
insert into StudentInfo(name,age,sex,score_id,parent) values ('小王',10,1,2,'大王'),('小丽',11,2,1,'大美'),('小张',11,1,3,'大张');
复制代码
新增操纵完成后就可以看到有三条数据在StudentInfo表中。
4.2 表中数据的删除
刚刚在表中又新增了一条数据,现在我想把刚刚新增的数据删除掉,可以使用delete语句举行删除。
--删除语句的格式
delete from 表名 where [条件1 and 条件2]
--如果不带where进行条件判断则是删除表中所有数据
delete from 表名
--删除刚刚新增的数据
--其实不带and name = '小王'也可以把刚刚新增的数据删除,这里只是演示where后面可以带多个条件
delete from StudentInfo where id = 7 and name = '小王'
复制代码
实行删除语句后的数据如下所示。
4.3 表中数据的修改
现在要将StudentInfo表中的小王及其父母的数据修改成小小怪和大大怪,这时就可以使用update语句举行修改。
--修改语句的格式
update 表名 set 字段1='新值',字段2='新值',... where [条件1 条件2...]
--修改小王为小小怪
update StudentInfo set name='小小怪',parent='大大怪' where id=4
复制代码
实行修改语句后的数据如下所示。
4.4 表中数据的查询
在表中数据的查询先从最简单的开始,循序渐进把左连接、右连接、内连接以及group by、order by等一起讲了。现在先贴出最简单的查询语句。
--查询语句的格式
select 字段1,字段2,...(查询所有字段可用'*') from 表 where 条件1,条件2,...
--最简单的查询语句
select * from StudentInfo
复制代码
查询结果是StudentInfo表中的所有数据。
(注:背面我感觉数据有点少又多添加了几条数据)
但是现在并不想要查看那么多数据,我只想要每个学生对应的父母是谁,这时的查询语句就可以是:
select name,parent from StudentInfo;
复制代码
现在我想要查询StudentInfo表中所有男同学,由于之前规定男同学性别对应为1,女同学性别对应为0,这时就可以在select查询语句背面添加where做条件判定:
select * from StudentInfo where sex = 1;
复制代码
多个条件就可以使用and或or举行多条件判定,比方我想知道年龄在12以下的所有男同学则可以写成:
select * from StudentInfo where sex=1 and age<12;
复制代码
group by具有聚合作用,根据某种条件举行聚合,具体用法可见我之前写的:Mysql中group by的用法。这里我演示一个案例,比方我想知道StudentInfo表中各个年龄段的人数是多少,这时就可以使用group by。
select age '年龄',count(age) '人数' from StudentInfo group by age;
复制代码
这里的count(age)表示聚合后的数量,除了count()外,最常用的还有sum(),avg(),Max(),Min(),这些都为统计函数,count()用于统计数量(出现次数),sum()用于统计里面数字加和,avg()用于求平均值,Max()用于求最大,Min()用于求最小。比如我想知道男同学和女同学中年龄最大是多少岁,这时可以写成:
select sex '性别',Max(age) '最大年龄' from StudentInfo group by sex;
复制代码
这时我们知道了女同学中最大年龄是11岁,男同学中最大年龄是12岁。
除了这些,我现在想知道每个同学的成绩,之前设计表的时候留了个score_id用于和SC表举行关联,我们可以使用连接来查询每个同学的成绩:
select name,Math,Chinese,English from StudentInfo si left join SC sc on si.score_id=sc.id;
复制代码
刚刚的语句中使用了左连接(left join),除了左连接外,还有右连接(right join)和内连接(inner join),接下来介绍这三种连接:
1.Left join(左连接):以左表为底子,ON之后给出两表相连的条件将两表连接起来。结果显示左表所有的查询信息,右表只列出ON后条件与左表满意的部分。左连接全称为左外连接,是外连接的一种。
2.Right join(右连接):以右表为底子,ON之后给出两表相连的条件将两表连接起来。结果显示右表所有的查询信息,左表只列出ON后条件与右表满意的部分。右连接全称为右外连接,是外连接的一种。
3.Inner join(内连接):同时将两表作为参考对象,根据ON后给出的两表的条件将两表连接起来。结果则是两表同时满意ON后的条件的部分才会列出。
下边使用集合的方式来表明三种连接。
现在我们成功知道了,但是我现在想知道学生的数学成绩排名,这时在两张表连接后可以使用order by来排序。
select si.id,name,Math
from
StudentInfo si
left join
SC sc
on
si.score_id=sc.id
order by
Math desc;
复制代码
order by是根据某个字段举行排序显示,背面接的关键字只有'desc'和'asc'两个,desc是降序排序,asc则是升序排序。
接下来演示一下怎样查询班里所有学生的总成绩并根据总分举行排名,这里除了最根本的select语句外,还要使用连接将StudentInfo表和SC表关联起来,再就是group by举行聚合,sum函数对语数英成绩求和,最后是使用order by举行排序。具体SQL语句如下
select
si.name,sum(sc.Math+sc.Chinese+sc.English) '总分'
from
StudentInfo si
left join
SC sc
on
si.score_id = sc.id
group by
si.name
order by
'总分' desc;
复制代码
5. 其它的一些函数用法
5.1 时间函数
SQL Server提供了一些时间函数用来返回时间,这里只做一些简单的树模。
GETDATE()
用来返回当前的日期和时间,这一函数的返回会准确到时分秒。
--本人在运行该语句时返回结果为:2024-10-21 09:52:58.767
select GETDATE();
复制代码
CURRENT_TIMESTAMP
的结果和GETDATE()的结果雷同,也是返回当前的日期和时间。
--本人在运行该语句时返回结果为:2024-10-21 09:55:19.303
select CURRENT_TIMESTAMP;
复制代码
DATEADD()
是为指定日期加上添加上指定的时间隔断,该函数有3个参数,第一个参数是时间单位,有SECOND(秒),MINUTE(分钟),HOUR(小时),DAY(天),Month(月),YEAR(年)。第二个参数是数值,比如DATEADD(DAY,2,'2024-10-21')中2表示2天后,第三个则是具体时间,可以是固定的时间,也可以是当前时间。
--返回当前时间的7天后
select DATEADD(DAY,7,GETDATE());
--返回2024-10-01的25年后,也就是2049-10-01
select DATEADD(YEAR,25,'2024-10-01');
--返回当前时间的1秒后
select DATEADD(SECOND,1,GETDATE());
复制代码
DATEDIFF()
可以返回两个日期之间的时间差。
--返回'2024-10-20'和'2024-10-01'之间的天数差,结果为19
select DATEDIFF(DAY,'2024-10-01','2024-10-20');
--返回'2024-10-01'和'2024-10-20'之间的天数差,结果为-19
select DATEDIFF(DAY,'2024-10-20','2024-10-01');
--返回'2024-10-21'和'2024-10-20'之间的小时差,结果为24
select DATEDIFF(HOUR,'2024-10-20','2024-10-21');
复制代码
DATEFROMPARTS()
根据年份、月份和日创建一个日期。
SELECT DATEFROMPARTS(2024, 10, 20);
复制代码
DATETIME2FROMPARTS()
根据年、月、日、时、分、秒、毫秒创建一个
datetime2
值。
SELECT DATETIME2FROMPARTS(2024, 10, 01, 12, 10, 01, 75);
复制代码
DATENAME()
可以根据时间返回日期部分的名称,如年、月、日、星期等。
--返回结果为星期二
SELECT DATENAME(WEEKDAY, '2024-10-01');
--返回结果为1
SELECT DATENAME(DAY, '2024-10-01');
复制代码
DATEPART()
可以返回日期部分的整数值,如年、月、日等。
SELECT DATEPART(DAY, '2024-10-19');
复制代码
DAY,MONTH,YEAR
可以返回日期中日,月,年。
select DAY(GETDATE());
select MONTH(GETDATE());
select YEAR(GETDATE());
复制代码
SWITCHOFFSET()
可以将datetimeoffset值的时间部分减去指定的时区偏移量。
SELECT SWITCHOFFSET(datetimeoffset_column, '-01:00');
复制代码
TODATETIMEOFFSET()可以将datetime2的值转换为dateoffset的值,使用指定的时区偏移量。
SELECT TODATETIMEOFFSET('2024-10-20T12:10:01', '-01:00');
复制代码
FORMAT()
可以将日期转化为指定的字符串格式 。
--将当前时间转换成年_月_日,例如'2024-10-01'
select FORMAT(GETDATE(),'yyyy-MM-dd');
复制代码
CAST()
和
CONVERT()
可以将日期转换为不同格式和数据范例。
-- 转换为只包含日期的值
SELECT CAST(GETDATE() AS DATE);
-- 使用特定的样式代码转换为字符串
SELECT CONVERT(varchar, GETDATE(), 121);
复制代码
ISDATE()
用于查抄字符串是否可以表明为有效的日期。
--真则返回1,假则返回0
SELECT ISDATE('2024-10-01');
复制代码
EOMONTH()
返回日期地点月的最后一天。
PS:之前因为事情忙(实在是懒得写)一直没写,这一次再对这篇文章举行一些增补。
5.2 ISNULL函数
ISNULL函数返回值是一个布尔值(值为True或者False),如果查询的值为空(NULL),则返回True,否则返回False,在SQL Server中使用ISNULL函数将一个空值替换为另一个值
。
下面是一个示例。
在StudentInfo表中,有学生信息的名字为空,如果我想把名字为空的值显示查询结果为"未知名字",这时可以使用ISNULL函数,语句如下
Select ISNULL(name,"未知名字") From StudentInfo;
复制代码
5.3 IFNULL函数
IFNULL是My SQL和SQLite的函数,SQL Server暂时不支持IFNULL函数,不过IFNULL函数的和ISNULL函数雷同,规则是IFNULL(expr1,expr2),即expr1的值为空时使用expr2的值替换。
5.4 NULLIF函数
NULLIF函数则是判定两个值是否相等,如果相等则返回一个NULL值,下面是一个简单示例。
--我们使用该语句查询每个学生的成绩总和
Select (Math+Chinese+English) as sumscore From SC;
复制代码
如果我想得出每科成绩占总成绩的百分比,我们很容易想到如下语句
Select
Math/(Math+Chinese+English)*100 as Math,
--数学所占百分比
Chinese/(Math+Chinese+English)*100 as Chinese,
--语文所占百分比
English/(Math+Chinese+English)*100 as English
--英语所占百分比
From
SC;
复制代码
但是该语句运行会出现错误:"遇到以零作除数错误。",因为我们总成绩中有0,所以导致了语句运行不了,这时就可以使用NULLIF函数来处理,如果总成绩为0,则替换成NULL,使用NULL做除数得到的结果为NULL,改进的语句如下。
Select
Math/NULLIF((Math+Chinese+English),0)*100 as Math,
--数学所占百分比
Chinese/NULLIF((Math+Chinese+English),0)*100 as Chinese,
--语文所占百分比
English/NULLIF((Math+Chinese+English),0)*100 as English
--英语所占百分比
From
SC;
复制代码
此时就可以正常查询,查询结果如图。
5.5 CONCAT函数
CONCAT函数用于字符串,数字等的拼接,拼接返回为一个字符串,下面是一个简单的示例,我们想把学校信息表中学生所有信息拼接成"姓名:xxx 年龄:xx 父母:xxx 性别:x"这种范例,这时就可以使用CONCAT函数。
Select
CONCAT('姓名:',name,' 年龄:',age,' 父母:',parent,' 性别:',IIF(sex=1,'男','女'))
as
'学生信息'
From
StudentInfo
复制代码
先写到这里,等有空就继续填坑。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4