我正在查询中执行自定义MySQL函数,以更新(或插入)数据库中的值。
我的实际代码(带有自定义查询):
DB::statement('INSERT INTO locations(longitude, latitude, altitude, speed, point, user_id, circle)
VALUES (' . $long . ', ' . $lat . ', ' . $alt . ', ' . $speed . ', ' . $point . ', GETPOLYGON(' . $lat . ', ' . $long . ' , 0.300, 12))
ON DUPLICATE KEY UPDATE longitude=' . $long . ',latitude=' . $lat . ',altitude=' . $alt . ',speed=' . $speed . ',point=' . $point . ',circle=GETPOLYGON(' . $lat . ', ' . $long . ' , 0.300, 12)');
我真的不知道这样执行是否是我的最佳选择。
我的自定义功能是'getpolygon'。但这似乎不起作用
[2020-04-17 08:23:01] local.ERROR: PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 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 '43.325178, GETPOLYGON(43.325178, 1.121354 , 0.300, 12))
我在SQL中的功能:
CREATE FUNCTION getpolygon(lat DOUBLE, lon DOUBLE, radius SMALLINT, corner TINYINT) RETURNS geometry DETERMINISTIC BEGIN DECLARE i TINYINT DEFAULT 1; DECLARE a, b, c DOUBLE; DECLARE res TEXT; IF corner < 3 || radius > 500 THEN RETURN NULL; END IF; SET res = CONCAT(lat + radius / 111.12, ' ', lon, ','); WHILE i < corner do SET c = RADIANS(360 / corner * i); SET a = lat + COS(c) * radius / 111.12; SET b = lon + SIN(c) * radius / (COS(RADIANS(lat + COS(c) * radius / 111.12 / 111.12)) * 111.12); SET res = CONCAT(res, a, ' ', b, ','); SET i = i + 1; END WHILE; RETURN GEOMFROMTEXT(CONCAT('POLYGON((', res, lat + radius / 111.12, ' ', lon, '))')); END;
谢谢
这里有一些错误,如问题所注释。
radius
为SMALLINT
,但是您正在向其传递浮点值。user_id
的值,因此实际代码将函数getpolygon()
的输出放入user_id
列,而没有任何内容放入circle
列,从而导致语法错误。因此,要修复SQL注入,您可以将准备好的语句与DB::statement($query, $bindings)
一起使用(请参见API Docs:]
DB::statement(
'INSERT INTO locations(longitude, latitude, altitude, speed, point, user_id, circle)
VALUES (?, ?, ?, ?, ?, ?, GETPOLYGON(?,?, 0.300, 12))
ON DUPLICATE KEY UPDATE longitude=?,latitude=?,altitude=?,speed=?,point=?,user_id=?,circle=GETPOLYGON(?,?, 0.300, 12)',
[
$long, $lat, $alt, $speed, $point, $user_id, $lat, $long,
$long, $lat, $alt, $speed, $point, $user_id, $lat, $long,
]
);
请注意,参数需要添加两次,因为您需要绑定到插入和更新语句中。