Oracle Sql语句长度限制问题及解决

 IN 子句中的LIST个数最长为1000,超过该数目将报错,这里可转用一个临时表来解决;  
      
  CREATE TRIGGER语句文本的字符长度不能超过32KB(触发器中不能使用LONG, LONG RAW 类型;触发器内可以参照LOB 类型列的列值,但不能通过 :NEW 修改LOB列中的数据;)顺便说一下,触发器中的PARENT关键字,只在嵌套表触发器中有效,  
      
 11G以前,DBMS_SQL对输入的SQL长度不能超过32K,原因是输入参数只能是VARCHAR2类型,11G后,可以用CLOB作为输入参数,则取消了这个限制  
      
  一个PL/SQL的包、过程、函数、触发器的大小,在UNIX上最大是64K,而WINDOWS则是32K大小(32K这个应该不准,看下面的测试)  
      
   SQL语句可以有多长?(网友说)ORACLE文档说是64K,实际受一些工具的限制会较这个值低,但网友测试发现可以很长,甚至超过1M(我测试过 170K的都没问题)。具体多长,10G也未说明,只是与很多环境有关:数据库配置,磁盘空间,内存多少。。。  
      
   PL/SQL中,表达式/SQL本身的长度是可以达到比较长的长度(50K)左右,如:v_str:=:new.f1||:ndw.f2。。。 ; select :new.f1||:new.f2。。。 into v_str from dual; 另外发现,如果这样写:v_str := ‘a’||’b’||。。。则允许的表达式长度将大大的减少。如果表达式/SQL过长,超过了一个ORACLE包/过程允许的最大程序长度,则在编译时报 pls-123:program too large错误,这是pl/sql编译器本身的限制造成的,即表达式/SQL的长度在PL/SQL中受限于包/过程的最大大小 

=================================================

Oracle Sql语句长度限制问题及解决

      最近在写Sql语句时,碰到两个问题:
      1)ORA-01795: maximum number of expressions in a list is 1000      
      起因:写出了这样的sql语句:SELECT PALLET_ID,BOX_ID,STATUS FROM SD_CURRENT_BOX WHERE PALLET_ID IN('"+pallets+"');其中的pallets是有很多个pallet_id组合成的字符串。
      分析:很显然,根据错误提示可以知道:in 中items的限制 1000个。
      解决:用子查询来代替pallets长字串。

      2)ORA-01704: string literal too long
      起因:写出了这样的Sql语句:UPDATE PDM_MEMBERLIST SET MEMBERS='<Project> ...  此处略去n多串 <ProjectID>'.
      分析:数据库设计MEMBERS字段为xmltype格式,数据存储时候,是以字符串的形式存储。这样在xml数据量大的时候,造成sql语句过长,尝过2k的限制。
      解决: 参数化sql语句。

 ==================================================

参数化sql语句----防止sql注入攻击(下)


上一篇写的sql注入的基本原理,本来要接着写这篇的,但是由于时间的原因一直没有写成,今天是五一假期,总算是能抽空写写了。

作为一个程序员,防范sql注入的第一线是由我们来守护的,只要我们在程序中留少许的漏洞,就会给程序增强安全特性。所以我们要做的是要写安全的程序,防止sql注入在程序体现在不要拼接sql字符串,一定要参数化sql或者写存储过程,这里就说说简单的参数化sql吧。

例子中用c#和oracle实现,java中或者其他数据库中的实现也是类似的。

using System.Data.OracleClient;//引入oracle操作包

//定义DML语句

string strSQL = @"select user.name from user where user.name =:userName";

//上句中的:userName就是sql语句中参数的占位符,也就是说在数据库服务器中执行这条sql语句的时候这个占位符要被其他东西替换掉,到底用什么东西替换呢,接着往下看

OracleParameter[] param = {

new OracleParameter(":userName",txtName);

}//这里定义一个参数的数组,里面可以写入多个sql参数,咱们的这里只有一个,所以就写入一个参数,这里讲占位符和他的替换也就是参数值对应起来了,txtName就是占位符的替换值,他是用户界面中用户输入的值,就是他可能含有注入攻击的字符,这下数据库服务器知道用什么东西替换占位符了。

定义好sql语句和参数后就是执行了,执行的时候需要同时将sql语句和参数传入,这样用户输入的带有非法字符的字符串在数据库会当作参数处理,而不会当作sql语句和数据库自己的字符混乱,防止了注入攻击。

    OracleCommandcmd = new OracleCommand();

     cmd.CommandText= strSQL;//定义oracle命令的文本内容

     for(oracleParameter p in param)//将参数传入

{

cmd.Parameters.Add(p);

}

     cmd.ExecuteNonQuery();//执行命令

上面基本上是一个完整的参数化sql,不同的数据库服务器sql语句中参数的占位符不同,上面用的是oracle,参数占位符是冒号(:)加名字,在sqlserver中是用@符号加名字作为占位符,而在mysql中用问号(?)加名字来作为参数占位符,不同的数据库中参数的表示符号不一样,这个需要注意。




防止sql注入攻击(上)


Sql注入是一种入门极低破坏极大的攻击方式。如果sql是用字符串拼接出来的话,那么肯定会被注入攻击,前段时间还传出了某国外大型社交网站被SQL注入攻击。

Sql注入攻击的方式,来这里看的同志们应该很清楚了,就是在拼接字符串的时候,如果输入的是带单引号的,那么输入laf'or 1='1'--这样就会逃避条件检查,后面要是再跟一些shutdown,delete之类的条件,那么损失基本算是毁灭性的了。前几天单位开发的过程中我发现几乎大家都不重视安全,一个写代码的人不注意安全只注意实现那么写出来的代码在攻击者眼前基本就是一个没有穿衣服的美女。

下面是我一个开发人员的一些经验,主要用来防止sql注入。

1、首先对运行sql的用户赋予最小权限,这个理论也是安全领域的最小特权理论,运行一个程序一定要用最小特权运行,所以不要给用户服务DBA的权限,限制要权限之后可以防止一些毁灭性的攻击,即使攻入了也不会shutdown修改表之类的。

2、一定不要使用字符串拼接的方式构造sql,必须使用参数化sql,存储过程可以看作是参数sql,简单的就直接构造参数化sql,复杂的就写存储过程,不过存储过程中一定不要用字符串,我看有人在存储过程用字符串,这样还是不能避免被攻击,并且在调试的时候非常麻烦。

3、严把输入关,系统肯定是用来交互的,所有用户输入的这一关一定要把好,可以利用各种方式来检验用户的输入,让输入都是合法的;可以设敏感字符不让用户输入,这个虽然不是很友好,不过对与安全有保证。在验证的是可以用正则表达式或者程序验证,不管用什么方式只要把敏感字符和可疑字符拒之门外那么就无法攻击了,不过限制输入还是有缺陷,在安全理论方面,只能确定合法,不能确定不合法,比如你在界面限制了合法的,那么剩余的都是不合法的,这时候输入的肯定全部是合法的,如果你限制的是非法的,可是你能确保你限制的全是非法的?如果某一天发现一个非法的不再你限制之内那么你就会被攻击。

4、做好自己的检验和测试工作,自己可以进行sql注入攻击,利用工具检验。

5、一定要养成具有安全意识的程序员,时刻想着安全。

这几条之中最重要的是1和2,权限限制一定要注意,不然会死的很惨的,第二就是程序员的习惯了,一定要用参数化sql和数据库交互。

时间太晚了,明天还要上班呢,就到这里吧,下一篇我就通过实例来说说程序员最关心的参数化sql语句。


参考:在oracle中一条sql语句长度限制的可能因素的探讨(附加讨论windows控制台)


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值