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

slhcrj9b  于 2022-12-21  发布在  Java
关注(0)|答案(1)|浏览(119)

有人能解释一下rowsx变量在传入generateBulkInsertQueries函数时是如何被覆盖的吗?我希望在整个代码段中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!!!!`)
})()
cuxqih21

cuxqih211#

我们已经将一个splice()doc)应用于splitArrayIntoChunks的第一个参数,它是包含函数的data参数,也就是我们不希望发生变化的rowsx数组。
所以这里使用的分块方法改变了它的输入。要么使用非破坏性reduce(see here,来自您使用的同一篇文章),要么复制一个输入以应用拼接。(下面演示了这个方法)

//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!!!!`)
})()

相关问题