使用 NodeJS 在 MySQL 中运行 SQL 文件

Posted

技术标签:

【中文标题】使用 NodeJS 在 MySQL 中运行 SQL 文件【英文标题】:Use NodeJS to run an SQL file in MySQL 【发布时间】:2014-04-12 04:11:39 【问题描述】:

我正在为 nodejs 使用 mysql 插件,到目前为止,它非常适合做我需要的一切。

但是我遇到了一个绊脚石。我创建了一个导出 mysql 池的 MySQL 提供程序:

var mysql = require('mysql');
var mysqlPool  = mysql.createPool(
  host     : '127.0.0.1',
  user     : 'root',
  password : ''
);

mysqlPool.getConnection(function(err, connection) 
  connection.query("INSERT INTO ....

我可以选择、创建、插入等一切都很好,但我遇到了一个任务,我想同时运行一个包含大约 10 个不同命令的小 SQL 字符串。我考虑过执行以下操作之一:

    使用 mysql 对数据库执行 SQL 文件 运行query 并启用multipleStatements

我已经编写了一些代码来将mysql 作为子进程执行,但我真的很想避免这样做:

var cp = require("child_process");
var cmdLine = "mysql --user=autobuild --password=something newdb < load.sql";
cp.exec(cmdLine, function(error,stdout,stderr) 
    console.log(error,stdout,stderr);
);  

选项二的问题是我宁愿不为每个查询启用多个语句,只为这个特定的一个。我曾考虑过创建一个新的连接,但只是在想其他方法可以做到这一点。

TL;DR? 使用 NodeJS 和 MySQL 如何在数据库中执行以下操作:

CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20) );

CREATE TABLE sofa (name VARCHAR(20), owner VARCHAR(20) );

CREATE TABLE table (name VARCHAR(20), owner VARCHAR(20) );

非常感谢任何分享他们想法的人

【问题讨论】:

【参考方案1】:

您可以使用名为multipleStatements的连接选项:

// Works with the pool too.
var connection = mysql.createConnection(multipleStatements: true);

然后,您可以传递如下查询:

connection.query('CREATE 1; CREATE 2; SELECT 3;', function(err, results) 
  if (err) throw err;

  // `results` is an array with one element for every statement in the query:
  console.log(results[0]); // [create1]
  console.log(results[1]); // [create2]
  console.log(results[2]); // [select3]
);

【讨论】:

是否有将查询流式传输到 mysql 连接?此示例假定 multipleStatements 是一个可管理的缓冲区。 请记住,当您使用 connection.execute() 函数时,多个语句将不起作用。因此,如果您不想使用 execute() 在同一连接上触发多个查询,则必须使用“connect() -> execute() -> end()”模式 在创建触发器之前使用DELIMITER时不起作用。 @user1748217 您可以使用 Node 的 fs 模块从 .sql 文件中导入文本。然后,您可以将此文本作为.query 调用中的第一个参数传递。如果文件只有一个查询,这只会在默认情况下起作用。此解决方案确保您可以传递具有多个的文件。 我还要注意,根据其文档,mysql Node 库似乎已经稍微改变了它的语法。现在您需要向它传递一个flag 属性,其值包括字符串“MULTI_STATEMENTS”。示例:const conn = mysql.createConnection(flags:"-MULTI_STATEMENTS")【参考方案2】:

这是一个大的.sql 文件友好的方式,可以在不使用multipleStatements 属性和大量缓冲区的情况下以编程方式对 MySQL 执行多个查询。请注意,这不是上传到 mysql 的最有效方式。

var mysql = require('mysql');
var fs = require('fs');
var readline = require('readline');
var myCon = mysql.createConnection(
   host: 'localhost',
   port: '3306',
   database: '',
   user: '',
   password: ''
);
var rl = readline.createInterface(
  input: fs.createReadStream('./myFile.sql'),
  terminal: false
 );
rl.on('line', function(chunk)
    myCon.query(chunk.toString('ascii'), function(err, sets, fields)
     if(err) console.log(err);
    );
);
rl.on('close', function()
  console.log("finished");
  myCon.end();
);

【讨论】:

【参考方案3】:

看起来有一个用于此目的的模块:execsql

【讨论】:

我在运行execsql的示例代码时得到Error: Cannot enqueue Query after invoking quit.【参考方案4】:

这样就可以了:

var express = require("express");
var bodyParser = require("body-parser");
var mysql = require('mysql');
var fs = require('fs');

var app = express();

app.use(bodyParser.urlencoded( extended: false ));
app.use(bodyParser.json());
app.use(express.static(__dirname));

var defaultConnection = mysql.createConnection(
  host     : 'localhost',
  user     : 'root',
  password : '',
  database: 'utpDatabase'
);

function dbCall_file (endpoint, operation, settings, filename)
    app.post(endpoint, function(request, response)
        var data = request.body;
        var path = 'path/to/queries/' + filename
        var connection = (settings == 'default') ? defaultConnection : settings;
        var callback = function(arg)
            var query = arg.replace(/[ ]0,2([a-zA-Z0-9\.\_\-]*)[ ]0,2/g, function(str, mch) return data[mch]);
            connection.query(query, function(err, rows)
                if (!err)
                    var toClient = (operation == 'select') ? rows : success: true;
                    response.send(toClient);
                 else 
                    console.log(err);
                    response.send(error: err, query: query);
                
            );
        ;

        fs.readFile(path, 'utf8', function(err, data)
            if (!err)
                callback(data);
             else 
                callback(err);
            
        );

    );
;

然后在你的 .sql 文件中将你的节点变量用双花括号包裹起来——例如,如果你想从你的 post call 中查询节点变量 data.firstName 的名字:

SELECT * FROM users WHERE name= firstName 

【讨论】:

以上是关于使用 NodeJS 在 MySQL 中运行 SQL 文件的主要内容,如果未能解决你的问题,请参考以下文章

在返回的mysql结果中查找行数(nodejs)

nodejs上使用sql

nodejs操作MySQL数据库

如何在 NodeJS 中使用 for 循环插入 SQL 表?

nodejs mysql 怎么封装模块

nodejs的mysql初始化