【问题标题】:Forward Slash issue with DBIDBI 的正斜杠问题
【发布时间】:2015-07-17 15:54:22
【问题描述】:

我不熟悉在 perl 脚本中使用 DBI 进行 SQL 查询。我遇到的问题与具有正斜杠的字段中的数据有关。我想使用变量作为 where 子句的输入,但它正在做 DBI 打算用正斜杠做的事情:停止查询。我尝试了许多不同的解决方法,包括绑定、引号等,但都没有奏效,甚至可能吗?这方面的数据是一致的。有 my $sql 变量的那一行是问题所在。

#!/usr/bin/perl

# Modules
use DBI;
use DBD::Oracle;
use strict;
use warnings;

# Connection Info
$platform = "Oracle";
$database = "mydb";
$user = "user";
$pw = "pass";

# Data Source
$ds = "dbi:Oracle:$database";

my $dbh = DBI->connect($ds, $user, $pw);

# my $dbh = DBI->connect();       
my $XCOD = $dbh->quote('cba');
my $a = $dbh->quote('abc');
my $b = $dbh->quote('123');
# tried this as well  my $pid = $dbh->quote('$a/$b');
my $sql = "SELECT P_ID FROM MyTable WHERE P_ID=$a/$b AND XCOD=$XCOD";
my $sth = $dbh->prepare($sql);
$sth->execute(); 

my $outfile = 'superunique.txt';
open OUTFILE, '>', $outfile or die "Unable to open $outfile: $!";

while(my @re = $sth->fetchrow_array) {
print OUTFILE @re,"\n";
}

close OUTFILE;

$sth->finish();
$dbh->disconnect();

【问题讨论】:

  • 你试过my $pid = $dbh->quote("$a/$b");,所以插值真的发生了吗?
  • 我没有;但是,它对我没有帮助。图我需要一个像 P_ID='abc/123' 这样的值,这意味着这样做时正斜杠不会包含在单个刻度中。
  • 你能澄清一下吗?或许可以举个例子说明你是如何使用绑定变量来尝试的?

标签: perl dbi


【解决方案1】:

我不喜欢看到人们在 SQL 查询中使用变量插值。尝试使用占位符:

 [ snip ]
 my $P_ID = "$a/$b"
 my $sql = "SELECT P_ID FROM MyTable WHERE P_ID = ? AND XCOD = ?";
 my $sth = $dbh->prepare($sql);
 $sth->execute($P_ID, $XCOD); 
 [ snip ]

【讨论】:

  • 我已经删除了不必要的引号并更改为我的 $variable = 'value';但是,当我去运行我的脚本时,我现在收到 DBD::Oracle:db prepare failed: ORA-00933: SQL command not properly end indicator in 'SELECT P_ID FROM MyTable WHERE P_ID = : p1 XCOD = :p2'>
  • 错误消息的 where 子句中没有“AND”。检查你的实际代码。
  • 在处理完一个问题后,显而易见的事情似乎消失了。没有返回任何结果,但没有错误了,所以我会看看我是否不能进一步修改以获得我应该期望的结果。
【解决方案2】:

已为您的问题提供了正确的解决方案 (use placeholders),但您可能有兴趣了解为什么您的操作不起作用。

问题是您似乎误解了quote 方法。 The documentation 是这样说的:

引用一个字符串文字以用作 SQL 语句中的文字值, 通过转义包含的任何特殊字符(例如引号) 在字符串内并添加所需类型的外引号 标记。

你在这三行中使用quote

my $XCOD = $dbh->quote('cba');
my $a = $dbh->quote('abc');
my $b = $dbh->quote('123');

打印出 $XCOD$a$b 的值会很有启发意义(顺便说一句,$a$b 是变量的真正糟糕的名称 - 除了它们的非描述性之外,它们也是排序中使用的特殊变量)。

我怀疑你会看到"cba""abd""123"。该方法没有发现要转义的特殊字符,所以它所做的只是在字符串周围添加引号。

然后您将这些值插入到您的 SQL 中。

my $sql = "SELECT P_ID FROM MyTable WHERE P_ID=$a/$b AND XCOD=$XCOD";

同样,您应该仔细查看在执行此语句后$sql 包含的内容。它看起来像这样:

SELECT P_ID FROM MyTable WHERE P_ID="abc"/"123" AND XCOD="cba"

这可能是 WHERE 子句的第一部分有问题。甲骨文将其视为一个部门。谁知道当您将一个字符串除以另一个字符串时,Oracle 会做什么。因此,您最终会寻找 P_ID 是一些奇怪(可能未定义)值的行。

所以这看起来是一个示例,其中最简单的调试技术(代码中的一些 print 语句)可以引导您朝着正确的方向前进。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2011-09-22
    相关资源
    最近更新 更多