如何解决 不能以 DISTINCT 方式选择 text、ntext 或 image 数据类型
distinct去重,如果遇到text字段,可以用以下方法解决
1.用not exists
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核心模块将在子查询的条件一旦满足后,立刻返回结果.
例子:
(低效):
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工具来解决问题始终是一个最好的方法)
如何解决 不能以 DISTINCT 方式选择 text、ntext 或 image 数据类型的更多相关文章
- 【转载】win10解决设置默认打开方式不生效问题(双击每次都要选择默认打开程序)
win10解决设置默认打开方式不生效问题(双击每次都要选择默认打开程序) 以下文章 部分选自 https://blog.csdn.net/shan165310175/article/details/8 ...
- 8、struct2解决中文乱码的方式
首先建立一个jsp页面 列如 页面编码统一问题,这个最容易解决. <%@ page language="java" import="java.util.*" ...
- Java之解决线程安全问题的方式三:Lock锁
import java.util.concurrent.locks.ReentrantLock; /** * 解决线程安全问题的方式三:Lock锁 --- JDK5.0新增 * * 1. 面试题:sy ...
- sql distinct 不能比较或排序 text、ntext 和 image 数据类型,除非使用 IS NULL 或 LIKE 运算符
有个文章的表内容是列项,类型是text 我查询的是内容相同的文章,把其中的一个删除 select 内容 from 文章 group by 内容 having count(*)>1 查询ID和题目 ...
- SQL Server中Text和varchar(max)数据类型区别
SQL Server中Text和varchar(max)数据类型区别 以前只知道text和image是可能被SQL Server淘汰的数据类型,但具体原因不太清楚,今天读书的时候发现了text与v ...
- Duanxx的STM32学习:STM32下载方式选择
前几天熟悉了STM32的启动方式.主要由Boot0和Boot1设置 如今须要解决的就是STM32的下载的问题. 一開始的时候,我选择的是SWD下载.这样的下载方式须要Boot0=0.Boot1=0.占 ...
- 一次故障解决过程梳理:mysql varchar text timestamp
CHAR 类型的一个变体是 VARCHAR 类型,char(M),M是指字节长度,和varchar(M)一样 故障原因:mysql主键设置为int(9),但数据量已经大于int(9)的范围了 tips ...
- js 跨域的问题 (同一个主域名不同的二级域名下的跨域问题) 解决 WdatePicker.js my97日期选择控件
例如域名是 a.xx.com 和 b.xx.com 如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain. 如果iframe的时候 a包含b 为 ...
- 关于打开现有项目时数据库连接配置遇到的问题 连接字符串中的数据源值指定未安装的SQL Server的实例。要解决此问题,可选择安装匹配的SQL Server实例或修改连接字符串中的数据源值
最近在看红皮书<ASP.NET MVC 5 高级编程>时,为了更好理解,边看书,边打开源代码查看,在VS(Visual Studio 2015)中将源代码打开,发现数据库连接是关闭的,本想 ...
随机推荐
- AngularJS指令进阶 -- ngModelController详解
大家都知道AngularJS中的指令是其尤为复杂的一个部分,但是这也是其比较好玩的地方.这篇文章我们就来说一说如何在我们自定义的指令中,利用ngModel的controller来做双向数据绑定,本文对 ...
- cordova 打包工具
一.环境安装 1.安装NodeJs https://nodejs.org 直接去官网下载并按默认路径安装就可以了. 安装完成后在命令行: (测试成功!) $ npm 2.安装Cordova 命令行 ...
- 什么是J2EE的集群?
1. 前言 现在有越来越多的关键应用和大型应用是基于J2EE 来创建的,像银行系统和帐单系统这些关键应用要求有很高的可用性,而Google 和Yahoo 这样的大型应用就需要很好的可扩 ...
- java 常用API 包装 数据转换
package com.oracel.demo01; public class Sjzh { // 将基本数据类型转字符串 public static void main(String[] args) ...
- JS 100以内的质数、只能被1和自己整除
for(var i = 2;i <= 100;i++){ var biao = 1; for(var j = 2;j < i;j++){ if(i%j == 0){ biao = 0; } ...
- Node笔记(1)
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. 进程 1.process.argv 用于获取当前进程信息 0--node.exe的目录1--js文件的目录2 ...
- HTTP 请求报文和响应报文分析和解刨!!
http请求和响应报文分析 一>http请求报文主要包括三个部分:1.请求行:2.请求头:3;请求体: 1,请求行一般包括三个部分:请求方式:请求url : http协议版本. 请求方法:大部分 ...
- 使用canvas保存网页为pdf文件支持跨域
前言 之前上一篇随笔说了Canvas截图网页为图片,下来个新需求,把网页截图后保存为PDF文件供用户下载. 前文 Canvas截图网页为图片:https://www.cnblogs.com/bubub ...
- uni-app 路由navigate
uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS.Android.H5.小程序等多个平台. 公司最近在写APP应用到了uni-app 我在写的时 ...
- 【Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) B】Weakened Common Divisor
[链接] 我是链接,点我呀:) [题意] 给你n个数对(ai,bi). 让你求一个大于1的数字x 使得对于任意的i x|a[i] 或者 x|b[i] [题解] 求出第一个数对的两个数他们有哪些质因子. ...