变量在传递给子函数时被覆盖



有人能解释一下当传递到generateBulkInsertQueries函数时,rowsx变量是如何被覆盖的吗?我期望rowsx的长度值在整段代码

中为1

//HELPER FUNCTIONS-------------------------------------------
var generateBulkInsertQueries = (
data,
dbname,
tablename,
colnames,
batchSize=10
) => {
if ([dbname, tablename].some((element) => element.indexOf('..') > -1))
throw `generateInsertQueries() expected distinct db (${dbname}) and tables (${tablename})`;
//if the colnames param is passed use it, otherwise generate colnames form the data
if (!dbname || dbname.length < 1) throw `generateInsertQueries(): invalid dbname (${dbname})`;
let cols = colnames ? colnames : Object.keys(data[0]); //transform keys are column names
//transform values are inserted strings
let values = [];
for(let rows of splitArrayIntoChunks(data,batchSize))
{
let ss=rows.map(r=>`(${sqlConcatOneLine(r,cols)})`)
values.push({outdata:`insert into [${dbname}].[dbo].[${tablename}](${cols.map((c) => `[${c}]`).join(',')}) values ${ss.join(',')}`,indata:rows});
};
return values
};

//demo:   let  [list,chunkSize] = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], 6];
//https://stackoverflow.com/questions/8495687/split-array-into-chunks
var splitArrayIntoChunks=(list,chunkSize)=>{
list = [...Array(Math.ceil(list.length / chunkSize))].map(_ => list.splice(0,chunkSize))
//console.log(list);
return list
}

var sqlConcatOneLine=(row,cols)=>{
return cols
.map((k) => {
let ret = "''";
try {
ret = "'" + row[k].toString().replace(/'/g, '').replace(/n/g, '').replace(/r/g, '').toString() + "'";
} catch (e) {
// console.log(
//   `WARN: err inserting value (likely null) generateSQLBulkInsertQuery: ${e}`
// );
}
return ret;
})
.join(',')
}
//EXAMPLE OF ERROR STARTS HERE--------------------------------
(async ()=>{
//init the var
var rowsx = [{ col1: "1", col2: "2" }];
console.log({rowsxlen:rowsx.length,here:1})
var sqliq = generateBulkInsertQueries(rowsx, 'xx', 'yy', ['col1','col2'],1);
console.log({rowsxlen:rowsx.length,here:2})
if(rowsx.length!=1) console.log(`failed. rowsx.length!=1`)
else console.log(`success!!!!`)
})()

您已经将splice()(doc)应用于splitArrayIntoChunks的第一个参数,这是包含函数的data参数,这是您希望不发生突变的rowsx数组。

所以这里使用的分块方法改变了它的输入。要么使用非破坏性还原(参见此处,来自您使用的同一篇文章),要么复制要应用拼接的输入。(如下所示)

//HELPER FUNCTIONS-------------------------------------------
var generateBulkInsertQueries = (
data,
dbname,
tablename,
colnames,
batchSize=10
) => {
if ([dbname, tablename].some((element) => element.indexOf('..') > -1))
throw `generateInsertQueries() expected distinct db (${dbname}) and tables (${tablename})`;
//if the colnames param is passed use it, otherwise generate colnames form the data
if (!dbname || dbname.length < 1) throw `generateInsertQueries(): invalid dbname (${dbname})`;
let cols = colnames ? colnames : Object.keys(data[0]); //transform keys are column names
//transform values are inserted strings
let values = [];
for(let rows of splitArrayIntoChunks(data,batchSize))
{
let ss=rows.map(r=>`(${sqlConcatOneLine(r,cols)})`)
values.push({outdata:`insert into [${dbname}].[dbo].[${tablename}](${cols.map((c) => `[${c}]`).join(',')}) values ${ss.join(',')}`,indata:rows});
};
return values
};

//demo:   let  [list,chunkSize] = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], 6];
//https://stackoverflow.com/questions/8495687/split-array-into-chunks
var splitArrayIntoChunks=(list,chunkSize)=>{
let spliceMe = [...list];
return [...Array(Math.ceil(list.length / chunkSize))].map(_ => spliceMe.splice(0,chunkSize))
//console.log(list);
}

var sqlConcatOneLine=(row,cols)=>{
return cols
.map((k) => {
let ret = "''";
try {
ret = "'" + row[k].toString().replace(/'/g, '').replace(/n/g, '').replace(/r/g, '').toString() + "'";
} catch (e) {
// console.log(
//   `WARN: err inserting value (likely null) generateSQLBulkInsertQuery: ${e}`
// );
}
return ret;
})
.join(',')
}
//EXAMPLE OF ERROR STARTS HERE--------------------------------
(async ()=>{
//init the var
var rowsx = [{ col1: "1", col2: "2" }];
console.log({rowsxlen:rowsx.length,here:1})
var sqliq = generateBulkInsertQueries(rowsx, 'xx', 'yy', ['col1','col2'],1);
console.log({rowsxlen:rowsx.length,here:2})
if(rowsx.length!=1) console.log(`failed. rowsx.length!=1`)
else console.log(`success!!!!`)
})()

最新更新