【问题标题】:How to synchronize my Perl script with MySQL query如何将我的 Perl 脚本与 MySQL 查询同步
【发布时间】:2014-03-10 09:40:10
【问题描述】:

我在任何意义上都是编码新手,所以请多多包涵。

我创建了一个与我的 PHP 应用程序通信的 Perl 脚本,但在将它们与 MySQL 查询同步的最后一个障碍上遇到了困难。我希望 Perl 脚本读取我数据库中的表 Syncorderrelation,并且只自动响应一次,通过在我的“传出表”上发布“自动响应”来发送一条短信)到任何符合以下条件的新条目:

  1. updatetype 为 1 的条目,这意味着新条目是订阅产品的新个人。

  2. Perl 脚本读取 DEST_MSISDN 的新条目,这是同一个 Syncorderrelation 表上的一个字段(只是一个电话号码)并通过自动响应回复该号码(只是一条欢迎消息)。这是通过仅在“传出表”上发布“自动响应”来完成的,我的 PHP 应用程序会接管并自行发送响应。

所以我的问题是:如何创建一个查询,以便 Perl 脚本从当前时间开始仅自动回复 Syncorderrelation 表中的新条目。目前,还有数百个我不想触发响应的其他条目。

但是只回复新的DEST_MSISDN(电话号码)并且只回复这个电话号码并且只回复一次,因此不会一次又一次地向同一个号码重新发送相同的欢迎消息。

注意:脚本可以知道它是一个新条目的唯一方法是通过ID 字段。这是一个独特的字段,每次新条目进入Syncorderrelation 表时都会自动生成(现在该表的数量将从当前的“440”增加到“441”)。

我创建的脚本将Syncoderrelation 表中的所有必需字段正确发布到Outgoing 表中,但我无法从Syncorderrelation 表中读取新的Dest_Msisdn(电话号码)并将电话号码发布到Outgoing 表。没有它,PHP 应用程序将不知道将欢迎消息发送到哪里。

use strict;

use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use XML::Simple;
use Digest::MD5 qw(md5_hex);
use Time::Piece;
use DBI;
use Time::HiRes qw(usleep nanosleep);

my $dest_msisdn             = '';
my $link_id                 = '';
my $ID                      = '';
my $subscription_auto_reply = '';
my $user                    = '';
my $send_time               = '';
my $now                     = '';
my $correlator              = '2345';
my $sender_name             = '30045';
my $source                  = '30045';
my $text_message            = 'Dear Customer Welcome to our service';
my $ua                      = new LWP::UserAgent(keep_alive => 1);

#get all the configs

#get sms to be  sent
#set the connection

my $dbh = DBI->connect('DBI:mysql:Database404', 'Kapo', 'XXXXXXXXX') || die "Could not connect to database: $DBI::errstr";
my $j = 0;

while ($j < 1) {
  print "AutoResponse....\n";

  my $sql = "SELECT * FROM syncorderrelation WHERE updatetype = '1'";
  my $results = $dbh->selectall_hashref($sql, 'id');

  foreach my $id (keys %$results) {
    print "AutoResponder!!!.....\n";

    #get all the required columns
    #get all the required columns
    my $textMessage  = $results->{$id}->{text_message};    #$results->{$id}->{dest_msisdn};
    my $correlator   = $results->{$id}->{id};
    my $senderName   = $results->{$id}->{sender_name};
    my $linkID       = $results->{$id}->{link_id};
    my $textID       = $results->{$id}->{id};
    my $client       = $results->{$id}->{client};
    my $productId    = $results->{$id}->{product_id};
    my $dest_msisdn  = $results->{$id}->{dest_msisdn};
    my $text_message = $results->{$id}->{text_message};
    my $autoReply    = $results->{$id}->{autoreply};

#####send service

    my $user = 5;

    my $send_time = time;
    my $now       = time;

    #catch error

    my $sql1 = "INSERT INTO outgoing_sms(dest_msisdn, text_message, sender_name, link_id, correlator, send_time, client,  user_id, timestamp) VALUES ('$dest_msisdn', 'Dear Customer Welcome to our service', '$sender_name', '$link_id', '1161', '$now', '1',  '$user', '$now')";
    $dbh->do($sql1);

    #print $sql1;
###send
    print $sql1;

    #remove from outgoing table
    my $sql2 = "UPDATE incoming_sms SET sent_flag = 1 WHERE id='$correlator'";
    $dbh->do($sql2);

    print $sql2;

  }

  usleep(1000000);
}

【问题讨论】:

  • 发布实际数据样本和想要的输出会很有帮助。
  • 如果有帮助,请添加相关数据库的快照。

标签: php mysql sql database perl


【解决方案1】:

我对你的代码有很多意见

  • 总是 use warnings 以及 use strict

  • 不要在程序顶部声明所有变量。应将它们声明为尽可能接近其第一个使用点

  • 您有一个use 用于许多 不必要的模块,以及许多 未使用或两次被删除的变量。在寻求帮助之前整理代码是一种礼貌。使用整洁的程序也更容易,但这是你自己的事。

  • 同样,不要编写 cmets,除非您必须实现复杂到难以理解的代码。并且说如何某些代码是如何工作的,而不是它的作用:在调用 DBI-&gt;connect 之前评论 set the connection 是荒谬的

  • 在大多数情况下,您应该使用 DBI 的 prepareexecute 而不是 do。参数应该使用占位符来传递,而不是通过将它们插入到 SQL 字符串中

  • 最好询问数据库它认为是什么时间,而不是使用本地系统时间。这样可以正确比较数据库中不同表上的时间戳

  • 您应该将多个表的相关更改放在一个事务中,以便在发生错误的情况下,一个更改不能没有另一个更改

据我所知,您正在寻找 syncorderrelation 中所有 updatetype 为 1 的条目以及 incoming_sms 中相应行设置了 sent_flag 到 1. 为此,您需要在两张桌子上使用 JOIN

代码应如下所示。 (见 - 一个模块,变量声明少得多!)但显然我无法在没有访问测试数据的情况下检查它。

use strict;
use warnings;

use DBI;

my $dbh = DBI->connect('DBI:mysql:Database404', 'Kapo', 'XXXXXXXXX')
    or die "Could not connect to database: $DBI::errstr";

my $get_new_ids = $dbh->prepare(<<__ENDSQL__);
SELECT syncorderrelation.* FROM syncorderrelation INNER JOIN incoming_sms
ON incoming_sms.id = syncorderrelation.id
WHERE syncorderrelation.updatetype = 1 AND incoming_sms.sent_flag != 1
__ENDSQL__

my $insert_outgoing = $dbh->prepare(<<__ENDSQL__);
INSERT INTO outgoing_sms (
    dest_msisdn,
    text_message,
    sender_name,
    link_id,
    correlator,
    send_time,
    client,
    user_id,
    timestamp)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
__ENDSQL__

my $update_incoming = $dbh->prepare('UPDATE incoming_sms SET sent_flag = 1 WHERE id = ?');

while () {

  while (my $data = $get_new_ids->fetchrow_hashref) {

    my ($now) = $dbh->selectrow_array('SELECT CURRENT_TIMESTAMP');

    $dbh->do('START TRANSACTION');

    $insert_outgoing->execute(
      $data->{dest_msisdn},                       # dest_msisdn,
      'Dear Customer Welcome to our service',     # text_message,
      $data->{sender_name},                       # sender_name,
      $data->{link_id},                           # link_id,
      1161,                                       # correlator,
      $now,                                       # send_time,
      1,                                          # client,
      5,                                          # user_id,
      $now,                                       # timestamp
    );

    $update_incoming->execute($data->{id});

    $dbh->do('COMMIT');
  }

  sleep 2;
}

【讨论】:

  • 感谢您的回复和建议。
  • 感谢您的回复和建议。我实际上只是在 syncorderrelation 中寻找 updatetype 为 1 的新条目,并且还想提取伴随 syncorderrelation 表中的新条目的 MSISDN 值,并将其插入到传出表中的“dest_Msisdn”中。从以上两张快照可以看出,一张快照有 Msisdn 值,另一张没有。缺少 Msisdn 值的实际上是“传出”表。
  • 我目前遇到以下错误,当我尝试实施建议的解决方案时,您认为可能是什么问题?谢谢! [DBD::mysql::st fetchrow_hashref 失败:在 new.pl 第 33 行未执行 fetch()]
猜你喜欢
  • 2014-02-17
  • 2016-03-22
  • 1970-01-01
  • 2023-03-28
  • 2017-06-06
  • 2020-11-03
  • 2014-03-24
  • 1970-01-01
  • 2014-05-27
相关资源
最近更新 更多