perl-在数据库中发送多个请求

4sup72z8  于 2021-06-16  发布在  Mysql
关注(0)|答案(2)|浏览(382)

我在perl中有这个脚本,这个程序解析一个日志文件并将结果发送到数据库中,我的问题是我的脚本只插入一个请求,我需要插入多个请求:


# Connect to the database.

my $dbh = DBI->connect("DBI:mysql:database=database;host=IP",
"hostname", 'password',
{'RaiseError' => 1});

while (my ($user, $ref) = each %counts) {
  while (my ($program, $count) = each %$ref) {
    #print "$count OSUSER with session $user and with program $program\n";
    print "time = $time, count = $count, user = $user, program = $program, last_line = $last_line\n";

    $request ="'$time', '$count', '$user', '$program', $last_line";

    my $sth = $dbh->prepare("REPLACE `test` (time, nb, os_name, program, last_line) VALUES($request);")
    or die "prepare statement failed: $dbh->errstr()";

    $sth->execute() or die "execution failed: $dbh->errstr()";
    print $sth->rows . " rows found.\n";
    $sth->finish;
  }
}

我的日志:

ID USER                    TERMINAL        SERVICE                    
---------- ------------------------- --------------- -------------------------  
         1 toto                    titi     roro          
         2 toto                    titi     roro          
         4 gigi                    gege        fefe

我的数据库:

+----+---------------------+-----------+-------------+----------------+-----------+
| ID | time                | nb        | os_name     | program        | last_line |
+----+---------------------+-----------+-------------+----------------+-----------+
| 15  | 2019-01-04 14:00:00|        33 | titi        | roro           | 109       |

我想要:

+----+---------------------+-----------+-------------+----------------+-----------+
| ID | time                | nb        | os_name     | program        | last_line |
+----+---------------------+-----------+-------------+----------------+-----------+
| 15  | 2019-01-04 14:00:00|        33 | titi        | roro           | 109       |
| 16  | 2019-01-04 14:00:00|        9  | gege        | fefe           | 109       |

(由戴夫补充-从评论中复制。以下是表定义。)

CREATE TABLE test (
  ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
  time datetime NOT NULL,
  nb int NOT NULL,
  os_name nvarchar(100) NOT NULL,
  program nvarchar(100) NOT NULL,
  last_line nvarchar(100)NOT NULL,
  PRIMARY KEY (ID),
  UNIQUE KEY (time)
) ENGINE=InnoDB;
uidvcgyl

uidvcgyl1#

从手册中 REPLACE : REPLACE 工作原理与 INSERT ,但如果表中的旧行与 PRIMARY KEY 或者 UNIQUE 索引时,在插入新行之前删除旧行。
(强调:我)
给你。你有同样的时间 2019-01-04 14:00:00 两次。什么时候 REPLACE 删除第二个第一个会被删除
尝试删除上的唯一索引 time .

cx6n0qe3

cx6n0qe32#

表定义(来自注解)包括:

UNIQUE KEY (time)

因此,表中的任何值只能包含一行 time .
还有,你用 REPLACE 在sql中。因此,当您第二次运行语句时,数据库会看到存在一个具有相同唯一键的现有行,因此它会更新该行,而不是插入一个新行。
在我看来,你的代码工作完全符合预期。如果要添加更多行,则需要更改中的值 $time .
更新:
从你对另一个答案的评论中。
我使用insert进行了测试,但不起作用:dbd::mysql::st execute failed:键“time”的重复条目“2019-01-04 17:45:00”
对!这正是应该发生的。宣布你 time 列组件 UNIQUE 您告诉数据库每个时间值在表中只能出现一次。因此,如果您尝试在同一时间插入另一行(这就是您正在执行的操作),则会出现错误。
所以你从 INSERTREPLACE 没有错误,只插入了一行,因为这就是 REPLACE 做。
您在表中给出的示例在时间列中有两个相同的值。如果你有足够的时间 UNIQUE 该列的定义。这正是 UNIQUE 关键是要防止。
你需要退后一步,想想你到底想要什么。如果希望表中的时间值重复,则需要删除 UNIQUE 表上的键定义(然后更改 REPLACEINSERT ).

相关问题