谷歌应用程序脚本赢得';t在远程服务器上与MySQL建立Jdbc连接

谷歌应用程序脚本赢得';t在远程服务器上与MySQL建立Jdbc连接,mysql,google-apps-script,jdbc,Mysql,Google Apps Script,Jdbc,我不熟悉使用Google脚本,正在尝试连接到MySQL(5.5.65-MariaDB)数据库,该数据库位于运行CentOS Linux 7.7.1908 Core的外部(非Google)服务器上 我在这里遵循指南: 在我的脚本中,我使用了以下函数: // export_sheet_data.gs function writeOneRecord() { var conn = Jdbc.getConnection('jdbc:mysql://HOST_NAME.com:3306/DB_NAM

我不熟悉使用Google脚本,正在尝试连接到MySQL(5.5.65-MariaDB)数据库,该数据库位于运行CentOS Linux 7.7.1908 Core的外部(非Google)服务器上

我在这里遵循指南:

在我的脚本中,我使用了以下函数:

// export_sheet_data.gs
function writeOneRecord() {
    var conn = Jdbc.getConnection('jdbc:mysql://HOST_NAME.com:3306/DB_NAME', 'DB_USER', 'DB_PASSWORD');

    var stmt = conn.prepareStatement('INSERT INTO entries '
    + '(guestName, content) values (?, ?)');
    stmt.setString('andy', 'First Guest');
    stmt.execute();
}
显然,
HOST\u NAME
DB\u NAME
DB\u USER
DB\u PASSWORD
是字符串(按字面输入,而不是变量),它们对应于适当的值:我的外部服务器的主机名、数据库名、数据库用户名和数据库密码

当我在脚本控制台(Run>runfunction>
writeOneRecord()
)中执行此操作时,它会显示

正在运行函数writeOneRecord()

大约10秒钟

然后,它会出现错误

异常:无法建立数据库连接。检查连接字符串、用户名和密码

如果我单击“详细信息”,它不会详细说明这一点。上面说

异常:无法建立数据库连接。检查连接字符串、用户名和密码。(第54行,文件“导出图纸数据”)

我已经做了以下工作:

  • 已将链接网页上的IP地址添加到我的服务器防火墙。重新加载防火墙以确保它使用此配置
  • 已检查我的服务器上是否存在数据库“
    DB_NAME
  • 检查主机名,
    HOST\u NAME
    是否与我的服务器匹配。还尝试了外部IP地址
  • 已检查MySQL正在使用端口3306
  • 检查用户名/密码(
    DB\u USER
    DB\u password
    )是否正确
我连接到的服务器上的防火墙日志中没有显示与此相关的内容

我已经检查过我是否正确使用了


我还可以如何调试它?Google脚本控制台中似乎没有任何东西可以提供帮助。

我在访问网站上的MySql数据库时遇到了一些困难,发现这种方法对我很有效

var address=getDBData('address');//I keep the actuall data in a spreadsheet  
    var user=getDBData('user');
    var userPwd=getDBData('pass');
    var db=getDBData('db');
    var dbUrl='jdbc:mysql://' + address + '/' + db;
    s+='<table>';
    s+='<tr><th>Database Name: ' + db + '</th></tr>';
    s+='<tr><th>' + qry + '</th></tr></table>';
    try
    {
      var conn=Jdbc.getConnection(dbUrl, user, userPwd);
    }
var address=getDBData('address')//我将实际数据保存在电子表格中
var user=getDBData('user');
var userPwd=getDBData('pass');
var db=getDBData('db');
var dbUrl='jdbc:mysql://'+address+'/'+db;
s+='';
s+='数据库名称:'+db+';
s+=''+qry+'';
尝试
{
var conn=Jdbc.getConnection(dbUrl、user、userPwd);
}

似乎经常使用的地址是主机帐户的ip地址。

您使用的是VPS Linux吗

我也遇到过同样的问题,但无法解决。这似乎是GAS JDBC实现的一个缺陷,它结合了VPS内部使用的自定义网络驱动程序和/或特定的MYSQL实现

对于一些Linux/Mysql组合,我能够连接到Linux Mysql,而对于一些则不能

我的例子中的错误是“读取通信包时出错”(mysql日志)——很难跟踪mysql错误

如果您检查服务器上的mysql日志,就是这个错误,我认为您最好遵循简化版的@TheAddAndPot建议-编写一个小的nodejs代码为您运行sql并将其安装为linux服务(在自定义端口上侦听http)-这方面有很多示例。花几个小时做这个比较容易,因为我认为这个问题在不久的将来不会得到解决

我还没有测试过,但像这样的东西应该适合你的情况

var http = require('http');
var url = require('url');
var mysql = require('mysql');

var con = mysql.createConnection({
  host: "localhost",
  user: "yourusername",
  password: "yourpassword",
  database: "mydb"
});

con.connect(function(err) {
  if (err) throw err;
  console.log("Connected to mysql!");
});

http.createServer(function (req, res) {
  var q = url.parse(req.url, true).query;
  var result;

  let stmt = `INSERT INTO entries (guestName, content) values (?, ?)`;
  let values = [q.guestName, q.content];
  console.log('Request', q);

  // execute the insert statment
  connection.query(stmt, values, (err, results, fields) => {
    if (err) {
      res.writeHead(400, {'Content-Type': 'application/json'});
      console.error(err.message);
      result = {error:err};
    } else {
      res.writeHead(200, {'Content-Type': 'application/json'});
      console.log('Insert Id:' + results.insertId);
      result = {success:true, id:results.insertId};
    }
  });
  res.end(JSON.stringify(result));
}).listen(7733);
从气体的角度来称呼它

UrlFetchApp.fetch('http://your-server-ip:7733/?guestName=' + encodeURIComponent(guestName) + '&content=' + encodeURIComponent(content));

或者,您可以尝试切换Linux/Mysql版本,但它更复杂,而且我不确定切换组合是否正确,因为在我的例子中,错误发生在Debian 18.04上,您的Mysql版本?你能从其他地方连接到它吗?5.5.65-5。我已经把它添加到了问题中。使用Apps脚本的JDBC服务通常是一个令人沮丧的练习。您最好构建一个自定义的mirco服务,该服务与数据库交互,并让应用程序脚本调用数据库。我建议将应用程序脚本与诸如云发布/订阅和云功能等服务结合使用,以构建您所需的功能。@这里的ADDO和POT用例是从Google工作表中读取数据,然后将其插入不同服务器上的MySQL数据库。我的脚本已经正确地读取了工作表中的数据,将其插入MySQL所需的SQL非常基本。只是连接不起作用。但是因为它没有出现在我的防火墙日志中,所以我甚至不知道连接失败之前的距离(我不知道它是否到达了我的服务器)。您提到的想法是否更适合这种类型的用例?如果是的话,我愿意调查一下。看看您是否有幸使用
getConnection
:user、pwd和dbname作为对象的替代签名。什么是
getDBData()
?这个定义在哪里?您对
Jdbc.getConnection
的调用与我所做的有什么不同?正如我在问题中提到的,我已经尝试使用服务器的IP和主机名。抱歉,get DB data只是从哈希表中读取数据。我在一些网站上的连接也遇到了问题,有些网站我似乎可以连接到一些我无法连接的网站。我们使用的服务器是一个专用的盒子,它不是VPS,如果这是你的意思的话。我已经给出了CentOS和MariaDB的确切版本。有人评论说不支持MariaDB,尽管我还没有找到任何信息来证实这一点。不要认为这只是VPS问题,我认为这是Linux网络驱动程序+Mysql版本组合的结果。好的是,它根本不起作用,你事先就知道了。对于随机故障,情况会更糟。