从mysql中的触发器调用url

时间:2016-05-13 16:32:30

标签: mysql rest triggers

我知道这是非常不受推荐的,

我知道这是性能,速度等方面的问题, 但这是为了集成,他们只是通过mysql进行更新(我知道这样做也很疯狂,但我无法改变他们做的事情,他们正在大量销售,所以他们不想改变任何东西)。

我只需要发布到一个网址(它可以像http://www.google.com?id=skuid一样简单)

我读过这个博客和堆栈,但他们已经2年多了,想知道是否有其他方法可以使用udf:

http://open-bi.blogspot.pe/2012/11/call-restful-web-services-from-mysql.html

http://www.mooreds.com/wordpress/archives/1497

Calling a php file by using mysql trigger

非常感谢所有事情!!

3 个答案:

答案 0 :(得分:19)

要触发外部操作,您必须使用UDF - 这是mysql向“外部世界”讲述内容的唯一方法。 The only alternative是一个不断轮询DB的外部代理 - 这是一个较差的解决方案。

关于UDF的选择,

  • 为了最大限度地减少数据库上的负载,它应该可以快速完成(注意UDF同步运行)。
  • 因此,除非安装规模足够小,否则只会向外部代理通知事件。这也最小化了DB端的错误处理。
    • 否则,如果你还没有照顾,你可以例如只是产生curl所有它的价值。

想到的方式:

  • 产生一个小程序 - 例如touch代理人观看的一些文件。现有sys_exec使用system()(考虑到所有因素)。
  • IPC(信号是最简单的;与其他人一样,您可以传递更多信息,但需要更多设置)

正如sys_exec's source所示,编写UDF并不是那么难,所以你并不仅限于已有的东西(这可以解释为什么lib_mysqludf_sys如此有限:如果你需要什么更好的是,编写特定于任务的功能非常容易。目前的文档位于26.4.2 Adding a New User-Defined Function - MySQL 5.7 Reference Manual

答案 1 :(得分:1)

您可以通过触发器中的“sys_exec”命令执行外部脚本。诀窍是以非阻塞方式编写该脚本,因此它产生异步执行工作的后台进程,主进程立即完成。

例如:

#!/bin/sh
nohup curl(or wget) http://www.example.com ...other_post_parameters... &

但是,您需要确保不会创建太多同时进程。这可以在触发器中完成(例如,它可以将最后执行时间写入某个表,然后检查是否已经过了一段时间),或者在shell脚本中(它可以创建/删除一些表示正在运行的程序的标志文件) )。

答案 2 :(得分:1)

这是Windows平台上MySQL服务器5.6 64位(!)的解决方案。我在Win10 64bit下测试了它。 我需要一个64位.dll版本的插件,它提供了在shell中运行命令的功能,我在这里找到了一个工作: http://winadmin.blogspot.nl/2011/06/mysql-sysexec-udf-for-64-bit-windows.html

您也可以在Windows上自行编译,请参阅: http://rpbouman.blogspot.nl/2007/09/creating-mysql-udfs-with-microsoft.html

对于MySQL 5.1+,您必须将插件/ dll放在MySQL安装根目录的子目录中,例如C:\wamp\bin\mysql\mysql5.6.17\lib\plugin 否则你会收到错误:

  

无法打开共享库dll - 错误代码193

您还需要由curl.exe调用的sys_eval。你需要在这里下载正确的(确保将(!)文件.exe和.crt复制到PATH环境中的可到达路径),我使用了c:\windows\system32https://winampplugins.co.uk/curl/

然后只有你需要的代码是:

--one time setup. run inside your database
CREATE FUNCTION sys_eval RETURNS STRING SONAME ‘lib_mysqludf_sys.dll’;

--example call to an URL
select CONVERT(sys_eval(CONCAT(‘curl https://randomuser.me/api?results=1‘)) USING UTF8MB4);