使用 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 文件的主要内容,如果未能解决你的问题,请参考以下文章