【问题标题】:The callback error query is not the same one i send, which lead to a syntax error回调错误查询与我发送的不同,导致语法错误
【发布时间】:2021-12-05 12:47:40
【问题描述】:

我有这个循环遍历用户输入的循环 我想将它们添加到mysql 但我有这个错误不断弹出,说我的查询中有语法错误 我记录了我发送的查询并且很好 回调错误查询和我发的不一样

这是循环

 for (var j = 0; j <= intLength - 1; j++) {
                    console.log(intItem[j], "intents looop");
                    const query1 =
                      " INSERT INTO intents (intent, version_id,status_intent) VALUES ('" +
                      intItem[j] +
                      "', (SELECT MAX (versions.version_id) from versions), '" +
                      enableStatus +
                      "')";
                    console.log(query1, "query11");
s
                        connection.query(
                          query1,
                          params,
                          function (err, results) {
                            if (err) {
                              console.log(
                                err,
                                "error from new project in insert to intents"
                              );
                            }
                          }
                        );
                      }

这就是回调错误查询 sql: " INSERT INTO intents (intent, version_id,status_intent) VALUES ('what'test11'', (SELECT MAX (versions.version_id) from versions), 'enable')"

这是确切的错误...

  code: 'ER_PARSE_ERROR',
  errno: 1064,
  sqlMessage: "You have an error in your SQL syntax; check the 
  manual that corresponds to your MySQL server version for the 
  right syntax to use near 'test103'', (SELECT MAX 
  (versions.version_id) from versions), 'enable')' at line 1",
  sqlState: '42000',
  index: 0,
  sql: " INSERT INTO intents (intent, version_id,status_intent) 
  VALUES ('what'test103'', (SELECT MAX (versions.version_id) from 
  versions), 'enable')"

这是连接到数据库之前的查询...

INSERT INTO intents (intent, version_id,status_intent) VALUES 
('what?', (SELECT MAX (versions.version_id) from versions), 
'enable')

【问题讨论】:

  • 您能否将(SELECT MAX (versions.version_id) from versions) 存储在单独的 let 或 const 中并尝试使用该变量,看看是否能解决您的问题。
  • @Sharati 它返回一个 id,而不是字符串或版本名称
  • 没关系,试着把结果放在单独的变量里试试。

标签: mysql node.js


【解决方案1】:

大多数开发人员发现使用查询参数更容易,而不是为如何转义文字引号字符而苦恼。如果您使用查询参数,则无需转义任何内容,只需使用 ? 占位符代替标量值,然后将输入添加到您的 params 数组中。

const query1 = `
  INSERT INTO intents (intent, version_id, status_intent) 
  VALUES (?, (SELECT MAX (versions.version_id) from versions), ?)`;

params = [intItem[j], enableStatus];

connection.query(query1, params,
    function (err, results) {
      if (err) {
        console.log(err, "error from new project in insert to intents");
      }
    });

(也可以使用反引号分隔的template literal,因此您可以将SQL 编写为多行字符串,而无需使用+ 将片段连接在一起。)

【讨论】:

    【解决方案2】:

    您的问题是 intItem[j] 实际上有一个 single quote (') 在其中,因此查询将有错误的语法。

    您生成的查询:

      INSERT INTO intents (intent, version_id,status_intent) VALUES ('what'test11', (SELECT MAX (versions.version_id) from versions), 'enable')
    
    • Values 之后的第一个值有一个单引号,因此解析器认为该值在what 之后已经结束。

    要修复它,您需要使用另一个单引号将给定字符串中的single quote (') 转义。结果是:

      INSERT INTO intents (intent, version_id,status_intent) VALUES ('what''test11', (SELECT MAX (versions.version_id) from versions), 'enable')
    
    

    您可以像这样修复代码:

    
    var escapeSqlValue = function(value) {
        if(typeof value === "string") {
            // replace all single quotes with another single quote before it!.
            // Regex with the "g" flag is used, so it will replace all occurences!.
            return value.replace(/'/g, "''")
        }
    
        // no string, so keep it like it is.
        return value
    }
    
    for (var j = 0; j <= intLength - 1; j++) {
        console.log(intItem[j], "intents looop");
        const query1 =
            " INSERT INTO intents (intent, version_id,status_intent) VALUES ('" +
            escapeSqlValue(intItem[j]) +
            "', (SELECT MAX (versions.version_id) from versions), '" +
            escapeSqlValue(enableStatus) +
            "')";
        console.log(query1, "query11");
        
        connection.query(
            query1,
            params,
            function (err, results) {
                if (err) {
                    console.log(
                        err,
                        "error from new project in insert to intents"
                    );
                }
            }
        );
    }
    

    现在生成有效的 sql:

      INSERT INTO intents (intent, version_id,status_intent) VALUES ('what''test11', (SELECT MAX (versions.version_id) from versions), 'enable')
    

    此外,我建议创建一个通用函数来构建您的 sql。所以它更具可读性,您可以更轻松地添加更多转义或其他逻辑。

    例子:

    
    // little enhanced function for regonizing subquerys if you wrap em in 
    // parenthesis
    function escapeSqlValue(value) {    
    
        if (typeof value === "string") {
    
            // For regonizing subquerys, check if it starts with a parenthesis!
            if(value.startsWith("(")) {
                return value
            }
    
            // replace all single quotes with another single quote before it!.
            // Regex with the "g" flag is used, so it will replace all occurences!.
            value =  value.replace(/'/g, "''")
    
            // directly wrap it into commata now!
            return `'${value}'`
        }
    
        // no string, so keep it like it is.
        return value
    }
    
    function sqlInsertQuery(table, rawFields, rawValues) {
       
        // join the fields comma separated.
        const fields = rawFields.join(",")
    
        // escape the actual values and join them with comma
        const values = rawValues.map(v => escapeSqlValue(v)).join(",")
    
        // build up the query:
        // note the `` quotes. They allow to use variables in them directly when
        // they are wrapped within ${/*var goes here*/}  , they allow to build up 
        // strings in a more readable way.
        return `INSERT INTO ${table} (${fields}) VALUES (${values})`
    
    }
    

    你可以这样称呼它

    const fields = ["intent", "version_id", "status_intent"]
    const values = ["what'test11", "(SELECT MAX (versions.version_id) from versions)", "enable"]
    const query = sqlInsertQuery("intents", fields, values)
    
    console.log("query", query)
    

    【讨论】:

    • 感谢您的解释,但我尝试了解决方案但没有成功,因为问题不在于输入意图我在连接到数据库之前记录了查询,在这里是...INSERT INTO intents (intent, version_id,status_intent) VALUES ('what?', (SELECT MAX (versions.version_id) from versions), 'enable'),这是错误回调返回的查询...sql: " INSERT INTO intents (intent, version_id,status_intent) VALUES ('what'test103'', (SELECT MAX (versions.version_id) from versions), 'enable')它们和你看到的不一样
    • @Sameer4Real 请编辑问题以显示确切的错误。已记录。并且参考另一个答案,它接缝更好.. ^^
    • 好的,我编辑帖子,你现在可以查看
    • 请尝试删除测试字符串中的?。也许这有影响?。
    • 谢谢,我参考了另一个答案,它解决了问题。再次感谢您的宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 2020-06-23
    • 2012-10-11
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    • 2013-06-30
    • 2020-11-12
    • 1970-01-01
    相关资源
    最近更新 更多