【问题标题】:Laravel Lumen : execute mysql function with insert intoLaravel Lumen:使用插入执行 mysql 函数
【发布时间】:2020-07-30 16:49:51
【问题描述】:

我希望在查询中执行自定义 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;

谢谢

【问题讨论】:

  • 你没有给 user_id 值。问题可能出在哪里?
  • 您将 radius 参数声明为 small int 并传递了一个浮点数...
  • 另外你应该使用准备好的语句来避免sql注入漏洞
  • @Furkanöztürk 确实,这个问题(缺少 1 个参数)已解决,但它不能解决我的问题(谢谢!)
  • @EliasSoares 确实,我解决了这个问题(我的错)。如果我在 laravel 中使用 'DB::insert',我可以将我的 mysql 函数的结果作为列的值插入吗?

标签: mysql laravel lumen


【解决方案1】:

这里有一些错误,正如问题中所评论的那样。

  1. 您的函数期望 radiusSMALLINT,但您正在向它传递一个浮点值。
  2. 您在值中缺少user_id,因此实际代码将您的函数getpolygon() 的输出放到user_id 列中,而在circle 列中没有任何内容,从而导致语法错误。
  3. 您的代码可能容易受到 SQL 注入的攻击。我说可能是因为我不知道您在查询中连接的变量的来源。

因此,要修复 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,
    ]
);

请注意,参数被添加两次,因为您需要绑定到插入和更新语句中。

【讨论】:

  • 非常感谢。在对我的帖子进行两次回复后,前两个步骤都可以。因此,我在 SQL 中的自定义函数将被执行,并且返回的值将填充“圆圈”列,对吧?
  • 是的,就像您的原始查询一样,但现在 sql 注入安全。如果对您有帮助,请接受我的回答正确。
  • 另一个错误是使用 'GEOMFROMTEXT' 而不是 'ST_GEOMFROMTEXT'(到目前为止是正确的方式)
猜你喜欢
  • 2018-06-10
  • 2017-02-15
  • 2017-08-12
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 2018-12-25
  • 2018-05-28
相关资源
最近更新 更多