好,那我们来讲一下这个SOQL for循环。
同学们,当你在Apex里需要处理一个查询返回的大量记录时,你可能会习惯性地把结果放到一个列表里。但如果我们直接用列表去接一个大的查询,很容易就会撞上Apex的堆大小限制,因为所有记录一下子全塞进了内存。
SOQL for循环正是为了解决这个问题而设计的。它的巧妙之处在于,它会悄悄地在后台调用SOQL的查询和 queryMore 接口,把返回的记录拆成一小批一小批地拿回来处理。这样一来,你永远不需要一次性把所有记录都加载到堆里,也就不容易触发限制,能安全地跑完几万甚至更多行数据。
在写法上,它支持两种形式。第一种是直接循环单个 sObject 变量,比如你写 `for(Account a : [SELECT ...])`,那每次循环拿出单独的一条记录。第二种是循环一个 sObject 列表变量,像 `for(List
accs : [SELECT ...])`,这样底层会每次取回一个批次,默认是200条记录,然后你可以在内层再遍历这个列表。这两种形式用起来都很方便,而且在 WHERE 子句里,你依然可以像普通SOQL那样使用冒号绑定变量,把变量值安全地注入到查询条件里。
不过有一个重要的限制要记住,如果你的查询里包含了聚合函数,比如 COUNT、SUM 这些,它返回的结果集跟普通查询不同,后台无法去执行 queryMore 来分块。一旦这类查询在 for 循环里返回的行数超过了2000,就会在运行时直接抛出一个异常。平时写代码,如果你要用聚合查询,一定要注意这个数量边界。
最后,如果你需要更精细地控制每次取多少条记录,或者处理更复杂的游标行为,那么可以考虑使用 Apex Cursors,它能给你更底层的掌控力。
好,关于SOQL for循环,关键点就是这些。