8

我正在使用 perl 脚本从我的数据库中提取 url,在该脚本中我使用fetchrow_array从数据库中提取 URL,这工作正常,直到我遇到一个很长的 URL georgelog24.blog.iskreni.net/?bid=6744d9dcf85991ed2e4b8a258153a1ab&lid=ff9963b9a798ea335b75b5f7c0c295d1
,然后它开始给我这个错误。

DBD::ODBC::st fetchrow_array failed: st_fetch/SQLFetch (long truncated DBI attribute LongTruncOk not set and/or LongReadLen too small) (SQL-HY000) [state was HY000 now 01004]
[Microsoft][ODBC SQL Server Driver]String data, right truncation (SQL-01004) at C:\test\multihashtest2.pl line 44.

我相信这是在数据库方面,因为我一直用来拉 URL 的代码以前工作过。我使用的数据库是MSSQL server 2005。

数据库中的 URL 列当前使用文本类型,但我尝试将其更改为varchar(max)nvarchar(max)但错误仍然存​​在。

经过一番反复试验,我发现 url 的最大长度然后我可以使用 fetchrow_array 成功查询为 81 个字符。而且由于 URL 有时可以跨越荒谬的长度,我不能对 URL 长度进行限制。

任何人都可以帮助我理解并建议解决这个问题吗?

仅供参考:第 44 行是我下面代码中的第一行

while (($myid,$url) = $statement_handle->fetchrow_array()) { # executes as many threads as there are jobs to do 
    my $thread = threads->create(\&webcrawl); #initiate thread
    my $tid = $thread->tid;
    print "  - Thread $tid started\n";   #obtain thread no. and print
    push (@Threads, $thread);   #push thread into array for "housekeeping" later on
}
4

3 回答 3

13

尝试:

#not anymore errors if content is truncated - you don't necessarily want this
$statement_handle->{'LongTruncOk'} = 1;

#nice, hard coded constant for the length of data to be read from Longs
$statement_handle->{'LongReadLen'} = 20000;
while (($myid,$url) = $statement_handle->fetchrow_array()) { # executes as many threads as there are jobs to do 
    my $thread = threads->create(\&webcrawl); #initiate thread
    my $tid = $thread->tid;
    print "  - Thread $tid started\n";   #obtain thread no. and print
    push (@Threads, $thread);   #push thread into array for "housekeeping" later on
}

另外,我建议您尝试Parallel::ForkManager并行化作业 - 我发现它比线程更直观和易于使用

于 2012-09-07T10:09:10.890 回答
6

请查看 DBI 属性LongTruncOkLongReadlen

您将需要接受截断或设置最大大小,因为 text 和 varchar(max) 列可能很大,因此如果将其留给 DBD,它将别无选择,只能分配大量内存以防列是最大值该列的大小。

于 2012-09-07T10:00:30.373 回答
4

要点:您需要在准备语句之前在数据库句柄 上设置 LongReadLen 和/或 LongTruncOk 属性,如此所述。

在获取数据之前尝试在准备好的语句句柄上设置它不会影响返回数据的截断。

于 2015-08-06T03:01:17.473 回答