不久前,我在寻找 way to insert values into a text field through isql
并最终找到了一些适合我的加载命令。
当我尝试从 Perl 执行它时它不起作用。我收到语法错误。我尝试了两种不同的方法,但到目前为止都不起作用。
我在每个循环周期结束时打印出 SQL 语句变量,所以我知道语法是正确的,但只是没有正确理解。
这是我正在测试的最新代码片段:
foreach(@files)
{
$STMT = <<EOF;
load from $_ insert into some_table
EOF
$sth = $db1->prepare($STMT);
$sth->execute;
}
@files
是一个数组,其元素是管道分隔文本文件的完整路径/位置(例如/home/xx/xx/xx/something.txt)表中的列数与文本文件中的字段数匹配,类型检查很好(我已经手动加载了测试文件,没有失败)
我回来的错误是:
DBD::Informix::db prepare failed: SQL: -201: A syntax error has occurred.
知道可能是什么原因造成的吗?
编辑 RET 和 Petr 的答案
$STMT = "'LOAD FROM $_ INSERT INTO table'";
system("echo $STMT | isql $db")
我不得不把它改成这个,因为 die 命令会强制非自然死亡,并且语句必须用单引号括起来。
最佳答案
Petr 完全正确,LOAD 语句是 ISQL 或 DB-Access 扩展,因此您无法通过 DBI 执行它。如果您查看手册,您会发现它对于 SPL、ESQL/C 等也是无效的语法。
不清楚是否必须使用 perl 来执行脚本,或者 perl 只是生成 SQL 的一种方便方式。
如果是前者,而你想要一个纯 perl 方法,你必须准备一个 INSERT 语句(它的外观只涉及一个表?),然后使用 split
浏览文件。将其分解为列并执行准备好的插入。
否则,您可以使用 perl 生成 SQL 并通过 DB-Access 执行它,或者直接使用 system
或者通过将两者包装在 shell 脚本或 DOS 批处理文件中。
系统调用版本
foreach (@files) {
my $stmt = "LOAD FROM $_ INSERT INTO table;\n";
system("echo $stmt | dbaccess $database")
|| die "Statement $stmt failed: $!\n";
}
在批处理脚本版本中,您可以将所有 SQL 写入单个脚本,即:
perl -e 'while(@ARGV){shift; print "LOAD FROM '$_' INSERT INTO table;\n"}' file1 [ file2 ... ] > loadfiles.sql
isql database loadfiles.sql
注意,关于文件名引号的注释仅在文件名包含空格或元字符时才相关,这是常见的问题。
此外,isql 和 dbaccess 之间行为上的一个关键区别是,当以这种方式执行时,dbaccess 不会在出错时停止,但 isql 会。要使 dbaccess 在出错时停止处理,请在环境中设置 DBACCNOIGN=1。
希望这会有所帮助。
关于perl - 为什么这个 ISQL 命令不能通过 Perl 的 DBI 运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1511330/