在Perl中捕获任何DBI错误的最佳方法是什么?例如,如果插入失败,因为插入的值中存在非法字符,我怎么能不让脚本失败,而是捕获错误并适当地处理它.
我不想做"或死",因为我不想停止执行脚本.
我搜索过谷歌,但找不到我认为简单问题的答案.
我有一个Perl代码(下面的示例),每3秒获取一次数据,并将接收到的数据更新到MySQL数据库中,但有时MySQL数据库不可用,脚本就会死掉.如果失败,如何再次建立MySQL连接?
use DBD::Mysql;
sub updateMysqlDB{
my $connect = DBI->connect("dbi:mysql:$database:$host",
$user,
$pw,
{RaiseError => 1}
);
$myquery = "My sql query to insrt data into columns";
$query_handle=$connect->prepare($myquery);
$query_handle->execute();
$connect->disconnect;
}
while (1) {
if data received call updateMysqlDB ();
else wait for data { sleep 3 ;}
}
Run Code Online (Sandbox Code Playgroud) disconnect会使1个活动语句句柄无效(在断开连接之前,destroy语句处理或调用它们)
从MySQL获取数据的以下代码成功执行,但会导致Apache在其错误日志中生成以上消息:
my $driver = "mysql";
my $server = "localhost:3306";
my $database = "test";
my $url = "DBI:$driver:$database:$server";
my $user = "apache";
my $password = "";
#Connect to database
my $db_handle = DBI->connect( $url, $user, $password )
or die $DBI::errstr;
#SQL query to execute
my $sql = "SELECT * FROM tests WHERE id=?";
#Prepare SQL query
my $statement = $db_handle->prepare($sql)
or die "Couldn't prepare query '$sql': $DBI::errstr\n";
#Execute SQL Query
$statement->execute($idFromSomewhere)
or die "Couldn't execute query '$sql': $DBI::errstr\n";
#Get query …Run Code Online (Sandbox Code Playgroud) 有些人可以告诉我,如果有一个函数mysql_real_escape_string()与DBI模块中的Perl的PHP相同吗?
有没有办法重用DBI准备语句中使用的?请考虑以下代码:
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?),C(?)");
$sth->execute($a,$a,$a);
Run Code Online (Sandbox Code Playgroud)
改为使用这样的东西会很好:
#I'm making this up as something I hope exists
$sth=$dbh->prepare("INSERT INTO mytable(a,b,c) SELECT ?,B(?:1),C(?:1)");
$sth->execute($a);
Run Code Online (Sandbox Code Playgroud)
请注意,只有一个$a传递给执行而不是三个.有没有办法在现实生活中做到这一点?
我使用Perl和DBI来管理我的MySQL表,查询等.如何显示查询的运行时间?
如果我在控制台中执行SELECT,结果将如下所示:
+-----+-------------+
| id | name |
+-----+--------------
| 1 | Jack |
| 2 | Joe |
| 3 | Mary |
+-----+-------------+
3 rows in set (0.17 sec)
Run Code Online (Sandbox Code Playgroud)
我需要表明0.17 sec.在DBI中有什么方法可以显示Perl的运行时间,这样的话吗?
my $dbh = $db->prepare("SELECT id, name FROM names ORDER BY id;");
$dbh->execute;
print $dbh->runnin_time; # ???
Run Code Online (Sandbox Code Playgroud) 我在perl脚本中遇到了一些内存泄漏问题,我正在运行很长一段时间,其中perl占用的内存量正在继续增长.因此,我试图使用Devel :: Leak来追踪泄漏.我发现每当我调用DBI的prepare方法时,返回的标量值的数量Devel::Leak就会增加一个.下面是我测试的脚本,我把它放在一起做我正在描述的内容:
#!/usr/bin/perl
use strict;
use Devel::Leak;
use DBI;
START:
my $handle; # apparently this doesn't need to be anything at all
my $leaveCount = 0;
my $enterCount = Devel::Leak::NoteSV($handle);
print "ENTER: $enterCount SVs\n";
{
# CONFIG VARIABLES
my $platform = "mysql";
my $database = "db";
my $host = "localhost";
my $port = "3306";
my $user = "user";
my $pw = "pass";
#DATA SOURCE NAME
my $dsn = "dbi:mysql:$database:$host:3306";
# PERL …Run Code Online (Sandbox Code Playgroud) 我正在努力让手动交易按照DBD :: Pg中的说明工作,或者我只是误解了所述文档.
我的理解是,如果我想手动管理事务,我应该关闭AutoCommit.
$dbh->{AutoCommit} = 0;
$dbh->begin_work;
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时,我会遇到连续的错误
DBD::Pg::db begin_work failed: Already in a transaction
Run Code Online (Sandbox Code Playgroud)
要使其工作,我需要首先打开AutoCommit.
$dbh->{AutoCommit} = 1;
$dbh->begin_work;
Run Code Online (Sandbox Code Playgroud)
但这似乎与任何文档都不一致.
我只是误解了吗?
我正在尝试使用DBI和连接SSL客户端密钥DBD::Pg.
use strict;
use warnings 'all';
use DBI;
my $dsn = "dbi:Pg:db=mydb;sslmode=require;host=localhost;"
."sslcert=C:\\path with\\spaces.crt;"
."sslkey=C:\\path with\\spaces.key";
my $dbh = DBI->connect( $dsn, 'username', '' );
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Can't connect to database: missing "=" after "with\spaces.crt" in connection info string!
Run Code Online (Sandbox Code Playgroud)
我试过在值周围使用单引号或双引号无效,我在文档中找不到任何内容.
单引号如下:
my $dsn = "dbi:Pg:db=mydb;sslmode=require;host=localhost;"
."sslcert='C:\\path with\\spaces.crt';"
."sslkey='C:\\path with\\spaces.key'";
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
failed: FATAL: connection requires a valid client certificate
Run Code Online (Sandbox Code Playgroud)
我知道这个配置有效,因为它适用于Python.
事实证明这是有效的:
my $dsn = "dbi:Pg:db=mydb;sslmode=require;host=localhost;"
."sslcert='C:\\\\path with\\\\spaces.crt';"
."sslkey='C:\\\\path with\\\\spaces.key'";
Run Code Online (Sandbox Code Playgroud)
为什么我需要双逃逸反斜杠?
我正在尝试做一个简单的查询作为准备好的声明,但没有成功.这是代码:
package sqltest;
use DBI;
DBI->trace(2);
my $dbh = DBI->connect('dbi:mysql:database=test;host=***;port=3306','the_username', '****');
my $prep = 'SELECT me.id, me.session_data, me.expires FROM sys_session me WHERE me.id = ?';
$dbh->{RaiseError} = 1;
my $sth = $dbh->prepare($prep);
$sth->bind_param(1, 'session:06b6d2138df949524092eefc066ee5ab3598bf96');
$sth->execute;
DBI::dump_results($sth);
Run Code Online (Sandbox Code Playgroud)
MySQL服务器响应语法错误near '''.
DBI跟踪的输出显示
-> bind_param for DBD::mysql::st (DBI::st=HASH(0x21e35cc)~0x21e34f4 1 'session:06b6d2138df949524092eefc066ee5ab3598bf96') thr#3ccdb4
Called: dbd_bind_ph
<- bind_param= ( 1 ) [1 items] at perl_test_dbi_params.pl line 10
[...]
>parse_params statement SELECT me.id, me.session_data, me.expires FROM sys_session me WHERE me.id = ?
Binding parameters: SELECT me.id, …Run Code Online (Sandbox Code Playgroud)