【问题标题】:sql server invalid precision on exists check querysql server对存在检查查询的无效精度
【发布时间】:2010-08-11 17:03:17
【问题描述】:

使用 sql server 2008 在以下 perl 脚本中出现无效精度值错误:

use DBI;
$idx = '12345';
$query = 'if exists (select * from tbl where idx = ?) select top 10 * from tbl';
my $h = $dbh->prepare($query) or die "Couldn't prepare query: " . $dbh->errstr;
$h->execute($idx) or die "Couldn't execute statement: " . $h->errstr;

但是请注意,如果我尝试这样做

use DBI;
$query = 'if exists (select * from tbl where idx = \'12345\') select top 10 * from tbl';
my $h = $dbh->prepare($query) or die "Couldn't prepare query: " . $dbh->errstr;
$h->execute() or die "Couldn't execute statement: " . $h->errstr;

然后就可以了。我真的很困惑怎么办?在查询中可能会导致无效的精度错误。

感谢任何人提供的任何帮助。

【问题讨论】:

  • tbl中idx的数据类型是什么?
  • idx 是一个 varchar。错误的确切文本是 [Microsoft][ODBC SQL Server Driver][Invalid precision value (SQL-HY104) at filename.pl ...
  • 完全猜测,但如果你尝试if exists (select * from tbl where idx = '?') select top 10 * from tbl
  • 我试过了,它最终通过了?字符直接写入sql而不替换它。
  • 另一个完整的猜测......你能明确地强制数据类型:if exists (select * from tbl where idx = cast(? as varchar(30))) select top 10 * from tbl 调整 varchar(30) 以匹配 idx 的定义。

标签: sql-server perl sql-server-2008 dbi


【解决方案1】:

基于this article,请尝试以下操作:

您需要从 DBI 导入 SQL 类型常量 并指定 SQL_LONGVARCHAR 作为要添加到备注字段的数据类型。

要做到这一点:

$dbh->bind_param(1, $idx, SQL_LONGVARCHAR);

【讨论】:

  • 请注意,如果您的 idx 列长度超过 255 个字符,我 100% 肯定它会有所帮助。如果不是,它可能会起作用,但我不太确定,因为 255 字符限制通常是首先导致此类错误的原因。
  • 原来它是一个 varchar(9),但如果我使用 SQL_VARCHAR 那么这确实有效。知道为什么它会起作用吗?感谢您的帮助。
  • @Chuck - 我目前唯一的聪明想法是有一个类似“int”的值......如果该值是一个非数字字符串,那么原始代码是否会出错?跨度>
  • 所有索引都有字母和数字。无论哪种方式,它仍然会呕吐。它与 exists 子查询有关,因为如果我只是 insert 或 select ,这很好,如果我在 exists 中放置一个字面术语并将其与 insert 或 select 结合起来,这很好。仅在尝试在存在子查询中使用占位符时才会中断
  • 嘿...不知道,但我很高兴我总是原则上避免绑定参数。太头疼了:)
【解决方案2】:

与特定类型的绑定会覆盖 DBD::ODBC 的决定。 DBD::ODBC 将根据从 SQLDescribeParam 返回的内容绑定参数。有时 SQL Server 的 SQLDescribeParam 会失败,尤其是在您使用函数或子选择的情况下。 SQL Server ODBC 驱动程序获取您的 SQL 并重新排列它以尝试以“从 tbl 中选择 idx”之类的结果结束,然后它查看列以回答 SQLDescribeParam 调用。我敢打赌,在这种情况下,SQL Server ODBC 驱动程序无法重新排列您的 SQL,并且 SQLDescribeParam 失败或返回了错误信息。如果您在 DBD::ODBC 中启用跟踪,我们可能会看到这种情况发生。

【讨论】:

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