如何从包含多个查询的MySQL.SQL文件中执行单个SQL查询-nodejs



我目前是第一次在node js中使用.sql文件,我有一个.sql文件如下所示。我需要什么代码来执行文件中显示的查询中的一个查询,例如第一个CREATE TABLE IF NOT EXISTS命令?任何帮助都将不胜感激!

我尝试了以下代码,但它并没有正确返回所有代码行。它仍然解析sql文件的第一行。代码和输出如下所示。

代码:

function parseSqlFile() {
try {
const fileName = './youtube(35).sql'
var sqlData = fs.readFileSync(fileName).toString()
.replace(/(rn|n|r)(--[^.].*)/gm," ") // remove newlines
.replace(/s+/g, ' ') // excess white space
.split(';') // split into all statements
.map(Function.prototype.call, String.prototype.trim)
.filter(function(el) {return el.length != 0});
console.log(sqlData)
return sqlData
} catch (err) {
console.log(err)
}
}

输出:

[
'-- MySQL Workbench Forward Engineering SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0',
'SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0',
"SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES'",
'CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8',
'USE `mydb`',
'CREATE TABLE IF NOT EXISTS `mydb`.`videos` (`id` INT NOT NULL, `title` VARCHAR(100) NULL, `date` DATETIME NULL, PRIMARY KEY (`id`)) ENGINE = InnoDB',
'CREATE TABLE IF NOT EXISTS `mydb`.`channels` (`id` INT NOT NULL, `channel_name` VARCHAR(45) NULL, PRIMARY KEY (`id`)) ENGINE = InnoDB',
'SET SQL_MODE=@OLD_SQL_MODE',
'SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS',
'SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS'
]
-- MySQL Workbench Forward Engineering
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`foo`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`foo` (
`id` INT NOT NULL,
`title` VARCHAR(100) NULL,
`date` DATETIME NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `mydb`.`foo`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`foo` (
`id` INT NOT NULL,
`foo` VARCHAR(45) NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

解决方案

第一行的注释出现在结果中,因为在标记为"//"的正则表达式中没有考虑到它删除换行符";,这需要在注释之前加一个换行符:

/(rn|n|r)(--[^.].*)/gm

请注意,此正则表达式标记错误,因为它匹配注释行,而不是换行符。

有几种方法可以更新正则表达式以匹配文件第一行的注释,但由于下一个正则表达式替换(/s+/(也应该处理换行符,最简单的方法是使其仅匹配注释行:

/^s*--[^.].*/gm

通过删除行首锚^来匹配(和删除(所有注释,而不仅仅是行上本身存在的注释,这将允许parseSqlFile处理包含嵌入注释的语句,但会导致SQL语句中包含双破折号(如果有的话(的字符串出现问题。根据SQL文件中可能出现的内容,未固定的regex可能更可取。

附加

parseSqlFile中使用的方法对于示例SQL以及一般情况下任何不包含数据的SQL应该足够。如果SQL在引号中包含分号或双破折号(包括反引号,尽管这会令人惊讶(,则会导致错误或其他失败。如果SQL在引号中包含多个连续空格字符,则该方法不太可能完全失败,但会更改数据。这对于任何基于正则表达式的解决方案来说都是一个问题,因为JS正则表达式(与大多数风格一样(不支持递归。

一个完整的SQL解析器会使任务变得简单,但它本身是一个更复杂的问题。相反,可以应用令牌化器,并对令牌流进行处理以产生所需的结果。

另一个简单的解决方案是扫描字符串,跳过引用的区域&引号区域中的转义字符,并在引号外遇到相关序列(";"或"--"(时执行操作。

最新更新