distinct去重,若是遇到text字段,能够用如下方法解决html
1.用not existssql
select * from tab a
where not exists (
select 1 from tab b
where b.col1 = a.col1
and b.col2 = a.col2
...
)数据库
2.转成字符型
CONVERT(VARCHAR(8000),你的字段)安全
select distinct * from (函数
select id, convert(varchar(8000), ntextCol) as colName from XXX工具
)测试
用EXISTS替换DISTINCT: 当提交一个包含一对多表信息(好比部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 通常能够考虑用EXIST替换, EXISTS 使查询更为迅速,由于RDBMS核心模块将在子查询的条件一旦知足后,马上返回结果.优化
例子:网站
(低效):spa
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO
(高效):
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
用EXISTS的确能够替代DISTINCT,不过以上方案仅适合DEPT_NO为惟一主键的状况。 若是要去掉重复记录,需参照如下方法:
SELECT * FROM EMP WHERE DEPT_NO EXISTS(select Max(DEPT_NO) FROM DEPT D , EMP E WHERE E.DEPT_NO = D.DEPT_NO GROUP BY D.DEPT_NO)
获得重复记录数
SELECT * FROM EMP WHERE DEPT_NO NOT EXISTS(select Max(DEPT_NO) FROM DEPT D , EMP E WHERE E.DEPT_NO = D.DEPT_NO GROUP BY D.DEPT_NO)
在咱们进行sql注入的过程当中经常会用到union查询方法,大多数状况下使用union查询法可让咱们很快的知道目标的数据组织方式。然而当咱们遇到ntext、text或image数据类型时,union查询就不太管用了。以sql server为例,在这种状况下会抛出以下错误:ntext 数据类型不能选为 DISTINCT,由于它不可比。
这里,我以sql server数据库为测试环境来进行分析。由于ntext、text、image数据字段可能存储很是多的数据,默认的状况下,数据库为提升效率会强制排除以上类型的字段中的相同的数据,这样就至关于在sql查询语句中加入了distinct关键字。而又由于这种类型的数据量可能很是大,数据库没法对这种类型的字段进行有效的比较,而distinct又要求数据库进行数据比较,从而致使带有unionr的sql语句执行错误,形成上述现象。
了解了出错的原理咱们就能够在执等的sql语句中加入相应的条件来使sql能正确执行。从上面能够看出,sql语句没法执行的缘由是由于数据库去检查union的数据是否相同,那么咱们只须要去掉这个默认的条件就能够了。解决的方法就是在union关键字后边加上“all”关键字。
下面用实例来演示这种类型的union注入。首先建立两个表: CREATE TABLE [dbo].[ntextTest]( [id] [int] NOT NULL, [name] [nchar](10) NULL, [target] [ntext] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] CREATE TABLE [dbo].[support]( [col1] [nchar](10) NULL, [col2] [nchar](10) NULL ) ON [PRIMARY] 而后分别在这两个表中插入数据: insert into ntextTest values(1,'aaa','adfsfs') insert into ntextTest values(2,'test','aaaa') insert into support values('aa','bb') 以后执行下列查询: select * from ntextTest union select 1,2,col1 from support 一如即往,没有成功。再执行: select * from ntextTest union all select 1,col1,col2 from support 此次正常返回结果!接下来被卡住的sql注入能够继续进行了。
上面所讲的问题的前提是ntext、text、image等数据类型出如今union查询的前面部分,在进行sql注入时,注入对象原有的查询语句中包含ntext数据类型便是这种状况。还有另外一种状况是在咱们注入时但愿查询ntext数据字段的内容。这种状况还有以有另外一种操做方式。好比要注入一个地址:http://www.test.com/show.asp?id=1,假定其后后的sql查询语句为:select id,productName,productInfo from product where id=@id,其中productName和productInfo都为nvarchar类型,若是咱们想要查询这个网站后台的article表中的文章的内容(用content表示,为ntext类型)能够用substring 函数来实现。用substring 能够将ntext数据截取一部分出来做为nvarchar类型返回,这样能够绕过ntext类型。如咱们作以下构造:http://www.test.com/show.asp?id=1 and 1=2 union select 1,2,…,substring(content,1,200),...n from article where id=XX 下面附上substring详细用法:
substring函数: { 返回值:返回字符、binary、text 或 image 表达式的一部分。 语法:SUBSTRING ( expression , start , length ) 参数: expression:是字符串、二进制字符串、text、image、列或包含列的表达式。不要使用包含聚合函数的表达式。 start:是一个整数,指定子串的开始位置。 length:是一个整数,指定子串的长度(要返回的字符数或字节数)。 返回类型: 1)、若是 expression 是支持的字符数据类型,则返回字符数据。 2)、若是 expression 是支持的 binary 数据类型,则返回二进制数据。 返回字符串的类型与给定表达式的类型相同(表中显示的除外)。
}
给定的表达式 | 返回类型 |
---|---|
text | varchar |
image | varbinary |
ntext | nvarchar |
注释: 在字符数中必须指定使用 ntext、char 或 varchar 数据类型的偏移量(start 和 length)。在字节数中必须指定使用 text、image、binary 或 varbinary 数据类型的偏 移量。
ps:以后以写这篇文章是由于本人在注入过程当中遇到了上面的问题,百度了很久都没有找到有用的信息。相信不少像我同样的小菜遇到这样的问题也难以解决,但愿这篇文章对小菜有所帮助。另本人初学安全技术,不少东西只知其一;不知其二,不免出错,若是老鸟们发现了还请指点!
用NOT EXISTS替代NOT IN
在子查询中,NOT IN子句将执行一个内部的排序和合并。 不管在哪一种状况下,NOT IN都是最低效的 (由于它对子查询中的表执行了一个全表遍历)。 为了不使用NOT IN ,咱们能够把它改写成外链接(Outer Joins)或NOT EXISTS.
例如:
SELECT … FROM EMP WHERE DEPT_NO NOT IN (SELECT DEPT_NO FROM DEPT WHERE DEPT_CAT=’A’); |
为了提升效率。改写为:
(方法一: 高效)
SELECT …. FROM EMP A,DEPT B WHERE A.DEPT_NO = B.DEPT(+) AND B.DEPT_NO IS NULL AND B.DEPT_CAT(+) = ‘A’ |
(方法二: 最高效)
SELECT …. FROM EMP E WHERE NOT EXISTS (SELECT ‘X’ FROM DEPT D WHERE D.DEPT_NO = E.DEPT_NO AND DEPT_CAT = ‘A’); 用EXISTS替换DISTINCT
当提交一个包含一对多表信息(好比部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 通常能够考虑用EXIST替换
例如:
低效:
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO |
高效:
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X’ FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO); |
EXISTS 使查询更为迅速,由于RDBMS核心模块将在子查询的条件一旦知足后,马上返回结果。
识别‘低效执行’的SQL语句
用下列SQL工具找出低效SQL:
SELECT EXECUTIONS , DISK_READS, BUFFER_GETS, ROUND((BUFFER_GETS-DISK_READS)/BUFFER_GETS,2) Hit_radio, ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run, SQL_TEXT FROM V$SQLAREA WHERE EXECUTIONS>0 AND BUFFER_GETS > 0 AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 ORDER BY 4 DESC; |
(虽然目前各类关于SQL优化的图形化工具层出不穷,可是写出本身的SQL工具来解决问题始终是一个最好的方法)