我正在尝试编写一个 perl 脚本来从包含 Joomla 网站文章的 mariadb 数据库中删除字符串。我们的人工智能工具正在数据库中插入需要删除的额外垃圾。这是我们需要删除的字符串类型的示例:
<span class="wordai-block rewrite-block enable-highlight" data-id="53">
困难在于data-id值可能是一些未知的数字。
我们还需要删除所有结束
</span>
标签。
这是我到目前为止开发的代码,但是一旦识别出包含上述字符串,我就陷入了搜索文章所需的循环。
use CGI;
use DBI;
use Date::Format qw(time2str);
use Text::Wrap;
use strict;
use Encode;
use vars qw($copy);
sub clean($$);
sub db_connect();
sub db_disconnect($);
sub write_sql($$);
my $dbh = db_connect();
my $findtext = '<span class=\"wordai-block rewrite-block enable-highlight\" data-id=\"';
my $replace = '';
my $sql1 = "select id,alias,`fulltext` from db1_content where `fulltext` like \"%$findtext%\"";
my $sth0 = $dbh->prepare($sql1) or die "Cannot prepare: ". $dbh->errstr;
$sth0->execute() or die "cannot execute: ".$dbh->errstr();
print "sql1: $sql1\n";
my $dupe;
my $count=0;
while (my $ref1 = $sth0->fetchrow_hashref()) {
$count++;
print "$count Found instance: $ref1->{id} $ref1->{alias}\n";
my $newstring = $ref1->{fulltext};
$newstring =~ s/$findtext/$replace/g;
print "$count: Updating: $ref1->{id}\n";
my $sqlr = "update db1_content set `fulltext` = ".$dbh->quote($newstring)." where id=$ref1->{id}";
}
print "\n";
db_disconnect($dbh);
exit 0;
sub write_sql($$) {
my $dbh = shift;
my $sql = shift;
my $sth = $dbh->prepare($sql);
$sth->execute();
$sth->finish();
print "writing: $sql\n";
}
sub db_connect() {
my %DB = (
'host' => 'localhost',
'db' => 'dbtest',
'user' => 'joomla',
'pass' => 'pass',
);
return DBI->connect("DBI:mysql:database=$DB{'db'};host=$DB{'host'}",
$DB{'user'}, $DB{'pass'});
}
sub db_disconnect($) { my $dbh = shift; $dbh->disconnect(); }
我不是 MariaDB 专家,但有几种标准技术可以满足您的需求:
创建
update
语句(正如您已经拥有的那样)后,将其转储到文本文件(如果您预计 update
语句的数量足够小,则将其转储到内存数组中)。在第一个循环从数据库读取数据完成并关闭后 - 启动第二个循环,现在读取准备好的 update
语句并逐个执行它们。作为一种变体,如果您将 update
语句转储到文件中,您将能够查看它并通过您最喜欢的外部 ?sql
工具执行。
打开两个独立的数据库连接 - 从一个连接读取,在同一循环中通过另一个连接更新。无需担心这两个连接是否会在服务器端发生数据冲突 - 这是多用户服务器读取-修改数据的标准方法,即使在这种情况下,两个“用户”实际上是来自一个应用程序的两个连接- 那还是可以的。
不确定 MariaDB 是否可以处理该问题,但许多其他 RDBMS 支持
cursor for update
技术。因此,您可以创建一个 select
,从中读取数据,然后使用 cursor
完全相同的光标,而不是使用 update
查找记录进行更正。它将自动处理对该特定记录的更改。
在数据库内进行所有更改,无需外部脚本。这是更新记录的最常见方法。但它可能需要复杂的 SQL 语句(或编写存储过程)。
选择任何看起来更容易理解和实施的方法。