MySQL动态传入列名、值数组执行INSERT语句报语法错误如何解决
问题原因
Node.js MySQL驱动的?占位符默认用于值转义,所有通过?传入的参数都会被当作普通值处理,字符串类型会被自动包裹单引号,符合值的SQL语法要求。但列名属于SQL标识符,不能用单引号包裹,因此直接用?传列名数组就会触发语法错误。
你之前调用replace(/'/g,'')无效,是因为mysql.format方法在转义时已经生成了合法的转义后单引号,直接全局替换还可能破坏值里的合法单引号,引发更多问题。
解决方法
MySQL驱动专门提供了??占位符用于SQL标识符转义,会给传入的标识符自动包裹合法的反引号(`),完全兼容动态列名的需求,同时内置了标识符转义逻辑,避免SQL注入风险,是官方推荐的方案。
修改后的代码如下:
// 把第一个占位符从?改成??,专门用于传入列名(标识符) const q = "INSERT INTO customers (??) VALUES (?)" const columns_arr = [ 'stat', 'idcustomers', 'parent_id', 'cust_prio_code', 'custadd_type_code', 'customername', 'EMAIL', 'priority_id' ] const values_arr = [ 2, 300, 900, 10003999, 'someType', 'dave', 'mail@mail.com', 99 ] const inserts = [columns_arr, values_arr] const format_query = mysql.format(q, inserts) mydb.query(format_query)
修改后生成的合法SQL为:
INSERT INTO `customers` (`stat`, `idcustomers`, `parent_id`, `cust_prio_code`, `custadd_type_code`, `customername`, `EMAIL`, `priority_id`) VALUES (2, 300, 900, 10003999, 'someType', 'dave', 'mail@mail.com', 99)
可以直接正常执行,没有语法问题。
内容的提问来源于stack exchange,提问作者MatanyaP
相关产品推荐
相关产品推荐

