fix: add batch processing to prevent SQL Server 2100 parameter limit error

- Add batch processing in getSourceNumbersFromInputs() with 2000 batch size
- Reduce batch size from 2000 to 1500 in queryBySourceNumbers() and queryBySourceNumbersDistinct()
- Add batch processing to queryByPlanNumbers() and getUniqueMaterialNames()
- Fixes issue where large order quantities caused parameter limit exceeded error
This commit is contained in:
Misaka_Company
2026-03-04 18:05:35 +08:00
parent b62ae10650
commit bfa2445c76
3 changed files with 76 additions and 45 deletions

View File

@@ -162,37 +162,52 @@ async function getSourceNumbersFromInputs(
// Column name: 生产订单号 (SourceNumber) // Column name: 生产订单号 (SourceNumber)
if (productionIds.length > 0) { if (productionIds.length > 0) {
const contractTableName = getTableName('productionContractData_26年压力表合同数据') const contractTableName = getTableName('productionContractData_26年压力表合同数据')
const batchSize = 2000
if (isSqlServer) { if (isSqlServer) {
const sql = require('mssql') const sql = require('mssql')
const placeholders = productionIds.map((_, idx) => `@p${idx}`).join(',') const allOrderNumbers: string[] = []
const params: Record<string, { value: string; type: any }> = {}
productionIds.forEach((id, idx) => { for (let i = 0; i < productionIds.length; i += batchSize) {
params[`p${idx}`] = { value: id, type: sql.NVarChar } const batch = productionIds.slice(i, i + batchSize)
}) const placeholders = batch.map((_, idx) => `@p${idx}`).join(',')
const params: Record<string, { value: string; type: any }> = {}
const contractSql = ` batch.forEach((id, idx) => {
SELECT DISTINCT 生产订单号 params[`p${idx}`] = { value: id, type: sql.NVarChar }
FROM ${contractTableName} })
WHERE 总排号 IN (${placeholders})
` const contractSql = `
const contractResult = await (dbService as SqlServerService).queryWithParams( SELECT DISTINCT 生产订单号
contractSql, FROM ${contractTableName}
params WHERE 总排号 IN (${placeholders})
) `
const dbOrderNumbers = contractResult.rows.map((row) => row. as string) const contractResult = await (dbService as SqlServerService).queryWithParams(
orderNumbers.push(...dbOrderNumbers) contractSql,
params
)
const dbOrderNumbers = contractResult.rows.map((row) => row. as string)
allOrderNumbers.push(...dbOrderNumbers)
}
orderNumbers.push(...allOrderNumbers)
} else { } else {
const placeholders = productionIds.map(() => '?').join(',') const allOrderNumbers: string[] = []
const contractSql = `
SELECT DISTINCT 生产订单号 for (let i = 0; i < productionIds.length; i += batchSize) {
FROM ${contractTableName} const batch = productionIds.slice(i, i + batchSize)
WHERE 总排号 IN (${placeholders}) const placeholders = batch.map(() => '?').join(',')
` const contractSql = `
const contractResult = await (dbService as MySqlService).query(contractSql, productionIds) SELECT DISTINCT 生产订单号
const dbOrderNumbers = contractResult.rows.map((row) => row. as string) FROM ${contractTableName}
orderNumbers.push(...dbOrderNumbers) WHERE 总排号 IN (${placeholders})
`
const contractResult = await (dbService as MySqlService).query(contractSql, batch)
const dbOrderNumbers = contractResult.rows.map((row) => row. as string)
allOrderNumbers.push(...dbOrderNumbers)
}
orderNumbers.push(...allOrderNumbers)
} }
} }

View File

@@ -313,7 +313,7 @@ export class ConfigManager {
// Order number parsing table configuration // Order number parsing table configuration
lines.push('# 订单号解析表配置') lines.push('# 订单号解析表配置')
lines.push('# 表名:包含 productionID 和 生产订单号 映射关系的表') lines.push('# 表名:包含 productionID 和 生产订单号 映射关系的表')
lines.push(`DB_TABLE_NAME=productionContractData_26 年压力表合同数据`) lines.push(`DB_TABLE_NAME=productionContractData_26年压力表合同数据`)
lines.push('# 字段名:总排号 (对应 productionID)') lines.push('# 字段名:总排号 (对应 productionID)')
lines.push(`DB_FIELD_PRODUCTION_ID=总排号`) lines.push(`DB_FIELD_PRODUCTION_ID=总排号`)
lines.push('# 字段名:生产订单号 (对应生产订单号)') lines.push('# 字段名:生产订单号 (对应生产订单号)')

View File

@@ -208,7 +208,7 @@ export class DiscreteMaterialPlanDAO {
const dbService = await this.getDatabaseService() const dbService = await this.getDatabaseService()
const tableName = this.getTableName() const tableName = this.getTableName()
const isSqlServer = dbService.type === 'sqlserver' const isSqlServer = dbService.type === 'sqlserver'
const batchSize = 2000 const batchSize = 1500
const allResults: any[] = [] const allResults: any[] = []
for (let i = 0; i < sourceNumbers.length; i += batchSize) { for (let i = 0; i < sourceNumbers.length; i += batchSize) {
@@ -250,7 +250,7 @@ export class DiscreteMaterialPlanDAO {
const dbService = await this.getDatabaseService() const dbService = await this.getDatabaseService()
const tableName = this.getTableName() const tableName = this.getTableName()
const isSqlServer = dbService.type === 'sqlserver' const isSqlServer = dbService.type === 'sqlserver'
const batchSize = 2000 const batchSize = 1500
const allResults: any[] = [] const allResults: any[] = []
for (let i = 0; i < sourceNumbers.length; i += batchSize) { for (let i = 0; i < sourceNumbers.length; i += batchSize) {
@@ -365,16 +365,24 @@ export class DiscreteMaterialPlanDAO {
const dbService = await this.getDatabaseService() const dbService = await this.getDatabaseService()
const tableName = this.getTableName() const tableName = this.getTableName()
const isSqlServer = dbService.type === 'sqlserver' const isSqlServer = dbService.type === 'sqlserver'
const placeholders = this.buildPlaceholders(planNumbers.length, isSqlServer) const batchSize = 1500
const allResults: any[] = []
const sqlString = ` for (let i = 0; i < planNumbers.length; i += batchSize) {
SELECT * const batch = planNumbers.slice(i, i + batchSize)
FROM ${tableName} const placeholders = this.buildPlaceholders(batch.length, isSqlServer)
WHERE PlanNumber IN (${placeholders})
`
const result = await dbService.query(sqlString, planNumbers) const sqlString = `
return result.rows SELECT *
FROM ${tableName}
WHERE PlanNumber IN (${placeholders})
`
const result = await dbService.query(sqlString, batch)
allResults.push(...result.rows)
}
return allResults
} catch (error) { } catch (error) {
log.error('Query by plan numbers error', { log.error('Query by plan numbers error', {
error: error instanceof Error ? error.message : String(error) error: error instanceof Error ? error.message : String(error)
@@ -703,17 +711,25 @@ export class DiscreteMaterialPlanDAO {
const isSqlServer = dbService.type === 'sqlserver' const isSqlServer = dbService.type === 'sqlserver'
if (sourceNumbers && sourceNumbers.length > 0) { if (sourceNumbers && sourceNumbers.length > 0) {
const placeholders = this.buildPlaceholders(sourceNumbers.length, isSqlServer) const batchSize = 1500
const allNames: string[] = []
const sqlString = ` for (let i = 0; i < sourceNumbers.length; i += batchSize) {
SELECT DISTINCT MaterialName const batch = sourceNumbers.slice(i, i + batchSize)
FROM ${tableName} const placeholders = this.buildPlaceholders(batch.length, isSqlServer)
WHERE SourceNumber IN (${placeholders})
AND MaterialName IS NOT NULL
`
const result = await dbService.query(sqlString, sourceNumbers) const sqlString = `
return result.rows.map((row) => row.MaterialName as string).filter(Boolean) SELECT DISTINCT MaterialName
FROM ${tableName}
WHERE SourceNumber IN (${placeholders})
AND MaterialName IS NOT NULL
`
const result = await dbService.query(sqlString, batch)
allNames.push(...result.rows.map((row) => row.MaterialName as string).filter(Boolean))
}
return allNames
} else { } else {
const sqlString = ` const sqlString = `
SELECT DISTINCT MaterialName SELECT DISTINCT MaterialName