我有一个pg查询要在spring batch partionner中执行,具有以下结构
SELECT string_agg(DISTINCT CAST(suivi.it_suivi_solde AS text), ';') AS ids
FROM T_CPT_C_SUIVI_SOLDE suivi,
T_CPT_C_CONSTAT_CREANCE constatcr
WHERE suivi.co_statut_suivi_solde = 'NTR'
AND suivi.dt_limite_paiement + :delaiMajoration * interval '1 day' < :dateLimitePaiement
AND suivi.co_sens_solde = 'D'
AND suivi.ID_PROC_DELCTX IS NULL
AND ( :listePartGestion IS NULL
OR suivi.CO_PARTICULARITE_GESTION NOT IN (:listePartGestion))
AND suivi.it_suivi_solde = constatcr.it_suivi_solde
GROUP BY suivi.IT_MIR, suivi.valeur_echeance_recouvre, suivi.dt_limite_paiement
HAVING SUM(constatcr.mt_solde)&gt; 0
当我的数据库中有数据时,我也没有例外,我得到了错误:
运算符不存在:字符变化= bytea ..
执行查询的分区程序如下:
@Setter
@Slf4j
public class JdbcToFilePartitioner implements Partitioner, InitializingBean {
@PersistenceContext
private EntityManager entityManager;
private int fetchSize = 100;
private String sqlGetIdToProcess;
private File workDirStep;
private Long nbItemMax;
@Override
public Map<String, ExecutionContext> partition(final int gridSize) {
// Création contextes d'execution pour chacune des partitions
Map<String, ExecutionContext> executionsContexte = createExecutionsContext(gridSize);
// Alimenter les partitions avec les ids à traiter
getIdsAndFillPartitionFiles(executionsContexte);
return executionsContexte;
}
/**
* Création des contextes d'execution pour chaque partition
* @param gridSize nombre de partition
* @return map contenant les contextes d'execution
*/
private Map<String, ExecutionContext> createExecutionsContext(final int gridSize) {
final Map<String, ExecutionContext> map = new HashMap<>();
for (int idPartition = 0; idPartition < gridSize; idPartition++) {
String racineNomPartition = "partition_" + LocalDateTime.now().toString("yyMMdd'_'HHmmssSSS");
String nomFichier = workDirStep + File.separator + racineNomPartition + "_" + idPartition + ".txt";
final ExecutionContext context = new ExecutionContext();
context.put(PartitionerConstantes.ID_GRID.getCode(), idPartition);
context.put(PartitionerConstantes.FILE_NAME.getCode(), nomFichier);
map.put(String.valueOf(idPartition), context);
}
return map;
}
/**
* Execute la requete de selection des identifiants à traier et rempli les fichiers de partitions de manière equitable
* @param executionsContext contexte d'execution contenant les noms de fichiers à remplir
*/
private void getIdsAndFillPartitionFiles(final Map<String, ExecutionContext> executionsContexte) {
List<BufferedWriter> fileWriters = new ArrayList<>();
try {
// Création des BufferedWriter pour chacune des partitions
for (int i = 0; i < executionsContexte.size(); i++) {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(executionsContexte.get(String.valueOf(i)).getString(
PartitionerConstantes.FILE_NAME.getCode())));
fileWriters.add(bufferedWriter);
}
// Construit le requete
StatelessSession session = ((Session) entityManager.getDelegate()).getSessionFactory().openStatelessSession();
Query query = buildQuery(session);
// Execute la requete
query.setFetchSize(fetchSize);
query.setReadOnly(true);
// query.setLockMode("a", LockMode.NONE);
ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);
int currentPartition = 0;
int nbEcriture = 0;
while (results.next()) {
fileWriters.get(currentPartition).write(results.get(0).toString());
fileWriters.get(currentPartition).newLine();
currentPartition++;
nbEcriture++;
if (currentPartition >= executionsContexte.size()) {
currentPartition = 0;
}
if (nbItemMax != null && nbEcriture >= nbItemMax) {
break;
}
}
results.close();
session.close();
for (BufferedWriter bufferedWriter : fileWriters) {
bufferedWriter.close();
}
} catch (IOException e) {
throw new UnexpectedJobExecutionException("Erreur d'accès au fichier de partition", e);
}
}
private Query buildQuery(final StatelessSession session) {
Query query = session.createSQLQuery(sqlGetIdToProcess);
if (query != null) {
if (sqlGetIdToProcess.contains(":dateLimitePaiement")) {
if (ContexteBatch.getExecution().getJobExecution().getExecutionContext().get("DELAI_TMP_CALC_MAJO") != null) {
query.setParameter(
"dateLimitePaiement",
ContexteBatch
.getDateTraitement()
.dayOfMonth()
.addToCopy(
(Integer) ContexteBatch.getExecution().getJobExecution().getExecutionContext().get("DELAI_TMP_CALC_MAJO"))
.toDate());
} else {
query.setParameter("dateLimitePaiement", ContexteBatch.getDateTraitement() != null ? ContexteBatch.getDateTraitement().toDate()
: new Date());
}
}
if (sqlGetIdToProcess.contains(":delaiMajoration")) {
query.setParameter(
"delaiMajoration",
ContexteBatch.getParametre("delaiMajoration") != null ? (Integer) ContexteBatch.getParametre("delaiMajoration") : Integer
.valueOf(0));
}
if (sqlGetIdToProcess.contains(":listePartGestion")) {
query.setParameter("listePartGestion",
ContexteBatch.getParametre("listePartGestion") != null ? (List<String>) ContexteBatch.getParametre("listePartGestion") : null);
}
} else {
log.error("La requête est null ");
}
log.info(query.toString());
return query;
}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(sqlGetIdToProcess, "La requête de partitionnement doit être configurée.");
}
}
请知道。 谢谢。
答案 0 :(得分:1)
解决方案是 CAST AS TEXT listePartGestion运算符
SELECT string_agg(DISTINCT CAST(suivi.it_suivi_solde AS text), ';') AS ids
FROM T_CPT_C_SUIVI_SOLDE suivi,
T_CPT_C_CONSTAT_CREANCE constatcr
WHERE suivi.co_statut_suivi_solde = 'NTR'
AND suivi.dt_limite_paiement + :delaiMajoration * interval '1 day' <
:dateLimitePaiement
AND suivi.co_sens_solde = 'D'
AND suivi.ID_PROC_DELCTX IS NULL
AND ( :listePartGestion IS NULL
OR suivi.CO_PARTICULARITE_GESTION NOT IN (CAST(:listePartGestion AS text)))
AND suivi.it_suivi_solde = constatcr.it_suivi_solde
GROUP BY suivi.IT_MIR, suivi.valeur_echeance_recouvre, suivi.dt_limite_paiement