我必须使用node.js中的mysql或mysql2执行INSERT INTO查询
传递到查询中的值使用geoMap
列上的空间几何函数ST_GeomFromGeoJSON()
,该函数的类型为GEOMETRY
。
以下是简化代码:
const insertQuery = `INSERT INTO maps (name, geoMap) VALUES ?`;
const insertData = [];
geoMapList.forEach((geoMap) => {
insertData.push([
geoMap.name,
`ST_GeomFromGeoJSON(${JSON.stringify(geoMap.map)}, 2)`
]);
});
this.connection.query(insertQuery, [insertData]);
上面的代码不起作用,并抛出错误Cannot get geometry object from data you send to the GEOMETRY field
我相信这是因为ST_GeomFromGeoJSON()
不是被MySQL解析为函数,而是被解析为字符串。
如何解决这一问题?
您不能将MySQL函数调用放在参数数组中,这些数据都被视为文本。
调用SQL中的函数,并将JSON字符串作为其参数。
不过,我不认为可以使用node-mysql
的大容量插入,所以需要分别插入每一行。
const insertQuery = `INSERT INTO maps(name, geoMap) VALUES (?, ST_GeomFromGeoJSON(?))`
geoMapList.forEach((geomap) =>
this.connection.query(insertQuery, [geomap.name, JSON.stringify(geomap.map)])
);
为了避免调用query()
数千次,可以在查询中放入多个values
列表。
const values = Array(geoMapList.length).fill('(?, ST_GeomFromGeoJSON(?))).join(',');
const insertQuery = `INSERT INTO maps(name, geoMap) VALUES ${values}`;
const params = geoMapList.flatMap(({name, map}) => [name, JSON.stringify(map)]);
this.connection.query(insertquery, params);
由于这将创建一个非常长的INSERT
查询,请确保增加MySQLmax_allowed_packet
设置。您还可以将geoMapList
拆分为更小的批,而不是在一个查询中完成所有操作。