Proc中使用char数组、VARCHAR数组和char变量进行DELETE操作具体行数的细微区别
Proc中使用char数组、VARCHAR数组和char变量进行DELETE操作具体行数的细微区别
EXEC SQL BEGIN DECLARE SECTION; char a[10000][3]; VARCHAR b[10000][31]; char c[3]; EXEC SQL END DECLARE SECTION; ... int delete_rows=10000; ...
1. CHAR类型数组变量
EXEC SQL for :delete_rows delete FROM table_name WHERE a= :a;
由于char对应于Oracle的char类型,因此若有空格,则此时char即使用memset初始化,但也会带有后面的空格,有可能造成delete时where a=:a由于空格不匹配无法删除,例如:a赋值为'a’,但数组长度是3,因此实际where条件是a='a ',因为空格导致不能删除。
2. VARCHAR类型数组变量
EXEC SQL for :delete_rows delete FROM table_name WHERE b= :b;
对于VARCHAR类型对应于Oracle的VARCHAR类型,因此不存在1中的空格问题,会自动滤掉空格,这是最好的一种匹配方法。
对于删除的数据量,会选择delete_rows与b数组的容量中最小的一个值。
3. CHAR类型变量
这里指的是char字符串变量,不是数组,此时使用:
EXEC SQL for :delete_rows delete FROM table_name WHERE c= :c;
由于c只是一个变量字符串,此时delete_rows会失效,只会执行一次该语句,有多少条删除多少条记录。
总结:
1. 对于VARCHAR类型数组,Oracle会根据指定删除行数的整数,与array host数组变量的容量之间,选择一个最小值,保证最小删除的行。
2. 对于CHAR类型字符串,就相当于一个常量,此时Oracle由于不能判断delete ... where c=:c;实际需要删除多少行,所以干脆也不判断了,就执行一次。开始我认为for :delete_rows类似于使用where rownum <= delete_rows,但这个场景是如此判断,想必不会是rownum这种方式做。
同理,UPDATE与DELETE相同。
另外,值得提一句,EXEC SQL BEGIN DECLARE SECTION;中char和VARCHAR类型可以不是二维数组,但其它类型的变量必须不能是这种二维数组。