要件
ある営業リストは論理上法人番号より、取引先と結び付けられる。毎日営業情報は別システムから連携され、バッチで最新データに取引先Idを付与する
分析
・取引先と営業リストのデータ量は500万件を超えるので、実行効率を考えるが必要です。
営業リストの更新日が指定日以内データだけを更新対象にする
・バッチサイズはディフォルトが200件ですが、指定できるようにする
・利用されるデータ
取引先のID、法人番号(Unique)
営業店舗リストの法人番号、最新更新日時
更新対象:営業リストの取引先ID ← 取引先のID
条件: 取引先の法人番号 = 営業リストの法人番号
営業店舗リストの最新更新日 > 指定日
実装
① Start
毎回200件の取引先を取得し、Executeに渡す
② Execute
②-1 渡された取引の法人番号とIdのマップを作成し、法人番号のリストも作成する
②-2 営業リストの法人番号分かつ指定日以内のリストを取得する
②-3 更新要の営業リストを選択し、取引先IDを付与し、更新リストに追加する
②-4 更新リストをUpdateする
ソース
global class AccountLinkRMList implements Schedulable, Database.Batchable<sObject> {
private final Integer BATCH_SIZE;
private Integer delayDay ;
// テストのため、指定日時が変えるように該当メソッドを追加した。
global void setDelayDay(Integer d){
this.delayDay=d;
}
global Integer getDelayDay(){
return this.delayDay;
}
// システムラベルから指定日数を取得し、数字以外の場合、全データが対象になる
global AccountLinkRMList() {
this(200);
Boolean Test = Pattern.matches('^[0-9]+$', System.Label.AccountLinkRMListPeriod);
if(Test==true){
this.delayDay = -Integer.valueOf(System.Label.AccountLinkRMListPeriod);
}else{
this.delayDay =1;
}
}
global AccountLinkRMList(Integer batchSize) {
BATCH_SIZE = batchSize;
}
global void execute(SchedulableContext sc) {
Database.executeBatch(this, BATCH_SIZE);
}
// 法人番号がNull以外のものは対象になる
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator([SELECT Id, corporate_number__c
FROM Account
WHERE corporate_number__c != null]
);
}
global void execute(Database.BatchableContext bc, List<sObject> scope) {
// 法人番号と取引先IDのMap
Map<String, Id> keyIdMainMap = new Map<String, Id>();
for (Account sobj : (List<Account>)scope) {
keyIdMainMap.put(sobj.corporate_number__c, sobj.Id);
}
System.debug(scope);
System.debug('b'+System.Label.AccountLinkRMListPeriod+'a');
DateTime myDate = System.today();
DateTime datePeriod = myDate;
Integer addHour = 9;
//RMBusinessSectionList__c
List<RMBusinessSectionList__c> updateList2 = New List<RMBusinessSectionList__c>();
System.debug('keyIdMainMap.keySet -- ' + keyIdMainMap.keySet());
if ( delayDay <= 0 ) {
datePeriod = myDate.addDays(delayDay);
// 日本時差 9時間
datePeriod = datePeriod.addHours(addHour);
System.debug('datePeriod -- ' + datePeriod);
updateList2 = [SELECT Id, corporate_number__c, Account__c
FROM RMBusinessSectionList__c
WHERE corporate_number__c IN :keyIdMainMap.keySet()
AND lastModifiedDate >= :datePeriod
];
}else{
System.debug('delayDay -- ' + delayDay);
updateList2 = [SELECT Id, corporate_number__c, Account__c
FROM RMBusinessSectionList__c
WHERE corporate_number__c IN :keyIdMainMap.keySet()
];
}
List<RMBusinessSectionList__c> updateList2Target = new List<RMBusinessSectionList__c>();
if (!updateList2.isEmpty()) {
for (RMBusinessSectionList__c c : updateList2) {
// 取引先IDがNull、また更新がある場合、更新対象になる
if(c.Account__c == null || c.Account__c <> keyIdMainMap.get(c.corporate_number__c) ){
c.Account__c = keyIdMainMap.get(c.corporate_number__c);
updateList2Target.add(c);
}
}
System.debug('updateList2Target -- '+updateList2Target);
update updateList2Target;
}
}
global void finish(Database.BatchableContext bc) {
}
}