【问题标题】:How to execute an individual SQL query from a MySQL .sql file containing multiple queries - nodejs如何从包含多个查询的 MySQL .sql 文件执行单个 SQL 查询 - nodejs
【发布时间】:2022-01-19 21:58:29
【问题描述】:

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

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

代码:

function parseSqlFile() {
  try {
    const fileName = './youtube(35).sql'
    var sqlData = fs.readFileSync(fileName).toString()
      .replace(/(\r\n|\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;

【问题讨论】:

  • 您在这里使用的是 MySQL 还是 MS SQL Server?
  • 这里使用 MySQL
  • 避免使用IF NOT EXISTS,因为如果它已经存在,它就不会创建表,并且您最终可能会使用旧的过时表。
  • 我会从文件阅读器开始,更多信息在这里javascript.info/file 然后考虑“;\n”是你的分割标识符来隔离 SQL 命令。最后可以使用查询方法w3schools.com/nodejs/nodejs_mysql_create_table.asp 执行您隔离的SQL 字符串命令最后编辑问题,更具体地说明您尝试了什么,遇到了什么麻烦。
  • 尝试了什么,遇到了什么麻烦添加到问题中

标签: javascript mysql sql node.js


【解决方案1】:

解决方案

第一行的注释出现在结果中,因为它没有包含在标记为“// remove newlines”的正则表达式中,这要求在注释之前有一个换行符:

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

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

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

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

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

附加

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

full SQL parser 会使任务变得简单,但它本身就是要解决的复杂得多的问题。相反,可以应用标记器,并处理标记流以产生所需的结果。

另一个简单的解决方案是扫描字符串,跳过引号区域和引号区域中的转义字符,并在引号之外遇到相关序列(';' 或 '--')时采取行动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    相关资源
    最近更新 更多