2014-10-14 3 views
4

Я использую node-mssqlОбъемные данные вставки в MSSQL таблицы с помощью узла MSSQL

Мой файл запроса, как показано ниже

BEGIN TRANSACTION 
DECLARE @status NVARCHAR(30); 
SET @status = 'create'; 
DECLARE @i UNIQUEIDENTIFIER; 
SET @i = NEWID(); 
DECLARE @t DATETIME2; 
SET @t = SYSUTCDATETIME(); 
IF NOT EXISTS( 
    SELECT * FROM user WHERE email = @email AND company_id= @company_id 
) BEGIN 
SET @i = NEWID(); 
INSERT INTO user (comapny_id, id, email, password) VALUES (@company_id, @i, @email, @password); 
INSERT INTO user_transaction(id, date, type) VALUES (@i, @t, @status); 
SELECT @i as 'id', @email as 'email'; 
END ELSE BEGIN 
SELECT NULL as 'id', @email as 'email'; 
END 
COMMIT TRANSACTION 

И мой createuser запрос в query.js файле

datastore.getQueryFromSqlFile('create_user', (err: any, query: string) => { 
    if (err) { 
     done(err); 
    } else { 
     var request = new sql.Request(connectionOrTransaction); 
     request.input('email', sql.NVarChar(200), email); 
     request.input('password', sql.NVarChar(200), some_password); 
     request.input('company_id', sql.UniqueIdentifier, company_id); 
     request.query(query, function (err, data) {}); 

Теперь мне нужно изменить их, чтобы вставить большую часть пользовательских данных, импортированных из файла CSV (> 20000 записей) Я думал о том, чтобы делать что-то вроде

async.mapSeries(Object.keys(users), function (item, callback) { 
    query.createuser(email, company_id, function (err, data) { 
     callback(err, err ? 'Error message: ' + data : data);   
    }); 
}, function (err, results) { 
}) 

Но это не эффективно, так как я получаю таймаут соединения. Увеличение connectionTimeout или requestTimeout в файле конфигурации не очень помогает.

Как я могу сделать запрос быстрее для массовой вставки около 20000-40000 записей за одну попытку?

ответ

1

Для меня это выглядит как работа для подготовленного заявления.

var ps = new sql.PreparedStatement(); 
ps.input('email', sql.VarChar); 
ps.input('password', sql.VarChar); 
ps.input('company_id', sql.Int); 
ps.prepare(" ... your sql ... ", function(err) { 
    // ... error checks 

    // users must be an array of users 
    async.mapSeries(users, function(user, next) { 
     ps.execute({email: user.email, password: user.password, company_id: user.company_id}, next); 
    }, function(err) { 
     // ... error checks 

     ps.unprepare(function(err) { 
      // ... error checks 

      // done ! 
     }); 
    }); 
}); 

Каждый execute называется один запрос, так что вы не должны timeouted по requestTimeout. connectionTimeout - это то, что влияет только на фазу соединения. Когда вы подключитесь к db, важно только requestTimeout.

Смежные вопросы