我无法修复与 SOQL 注入相关的 Sonarqube 问题,这是原始代码, Batch start 方法中调用 AggregateResultIterator 类:
global without sharing class AggregateResultIterator implements Iterator<AggregateResult> {
AggregateResult [] results {get;set;}
// tracks which result item is returned
Integer index {get; set;}
global AggregateResultIterator(String query) {
index = 0;
results = Database.query(query);
// results = Database.query(String.escapeSingleQuotes(query));
System.debug('results: ' +results);
}
global boolean hasNext() {
return results != null && !results.isEmpty() && index < results.size();
}
global AggregateResult next() {
return results[index++];
}
}
startDateFormat = String.valueOf(startDate);
endDateFormat = String.valueOf(endDate);
String query = ' SELECT OpportunityLineItemId, SUM(Revenue) Revenue, '+
' OpportunityLineItem.OpportunityId, OpportunityLineItem.Opportunity.AccountId, '+
' Order_Item__r.Supplying_Entity__c, OpportunityLineItem.Opportunity.Legal_Entity_Account__c '+
' FROM OpportunityLineItemSchedule '+
' WHERE OpportunityLineItem.Opportunity.StageName = \'Closed Won\' AND ScheduleDate >= '+ startDateFormat +' AND ScheduleDate <= ' + endDateFormat +
' GROUP BY OpportunityLineItemId, OpportunityLineItem.OpportunityId, OpportunityLineItem.Opportunity.AccountId,' +
' Order_Item__r.Supplying_Entity__c, OpportunityLineItem.Opportunity.Legal_Entity_Account__c ';
return new AggregateResultIterable(query);
问题带有行结果 = Database.query(query)。 所以我尝试了很多解决方案,但我无法让它们发挥作用。
#1。使用 String.escapeSingleQuotes(query) 方法,但这会导致此错误 --> System.QueryException: line 1:310 在字符 '' 处没有可行的替代方案
#2。我正在尝试像这样清理函数结果:
String field1 = '\'' + String.escapeSingleQuotes(getSomeId()) + '\'';
String field2 = 'SELECT Id FROM Account WHERE isPublic = true and Id = ';
Database.query(field2 + field1);
但是我不断收到此错误 --> 第 1:310 行在字符 '' 处没有可行的替代方案
如果有人可以帮助解决这个问题,我们将不胜感激。预先感谢。
一般来说 - 使用正确的绑定变量,这样你就不会遇到
\'
的问题。
在这种特殊情况下,我会重写您的 WHERE IsClosed = true AND IsWon = true
(大多数组织只有 1 个状态,这意味着“已关闭获胜”,但理论上您可以拥有更多)。
如果你想让它更接近原版:
Date startDate;
Date endDate;
Set<String> statuses = new Set<String>{'Closed Won'};
String query = ' SELECT OpportunityLineItemId, SUM(Revenue) Revenue, '+
' OpportunityLineItem.OpportunityId, OpportunityLineItem.Opportunity.AccountId, '+
' Order_Item__r.Supplying_Entity__c, OpportunityLineItem.Opportunity.Legal_Entity_Account__c '+
' FROM OpportunityLineItemSchedule '+
' WHERE OpportunityLineItem.Opportunity.StageName IN :statuses AND ScheduleDate >= :startDate AND ScheduleDate <= :endDate' +
' GROUP BY OpportunityLineItemId, OpportunityLineItem.OpportunityId, OpportunityLineItem.Opportunity.AccountId,' +
' Order_Item__r.Supplying_Entity__c, OpportunityLineItem.Opportunity.Legal_Entity_Account__c ';
如果您绑定的变量不在同一上下文中(在您用来手工制作查询字符串的地方可见,但它们不存在于实际的地方
Database.query()
),还有更多阅读内容该怎么办被调用),检查https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dynamic_soql.htm。
同样我也会在你的
中进行绑定Id i = getSomeId();
String q = 'SELECT Id FROM Account WHERE isPublic = true and Id = :i';
Database.query(q);