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类型可以不是二维数组,但其它类型的变量必须不能是这种二维数组。
参考:
The host variables in the WHERE clause must be either all scalars or all arrays. If they are scalars, Oracle executes the DELETE statement only once. If they are arrays, Oracle executes the statement once for each set of array components. Each execution may delete zero, one, or multiple rows. Array host variables in the WHERE clause can have different sizes. In this case, the number of times Oracle executes the statement is determined by the smaller of the following values: ■The size of the smallest array ■The value of the :host_integer in the optional FOR clause