由于使用DBD::mysql的類似陳述句似乎作業正常,當使用DBD::SQLite作為 DBI 驅動程式時,我在HAVING子句中使用占位符作為整數的錯誤在哪里?
#!/usr/bin/perl
use 5.012;
use warnings;
use DBI;
my $dbh = DBI->connect("dbi:SQLite:dbname=/tmp/test.sqlite","","", {
RaiseError => 1,
sqlite_allow_multiple_statements => 1,
});
$dbh->do( <<'EOT' );
CREATE TABLE cd (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT
);
CREATE TABLE artist (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
cd INTEGER,
FOREIGN KEY (cd) REFERENCES cd (id)
);
INSERT INTO cd (title) VALUES ('foo');
INSERT INTO cd (title) VALUES ('bar');
INSERT INTO artist (name, cd) VALUES ('max fob', 1);
INSERT INTO artist (name, cd) VALUES ('max baz', 1);
EOT
my $sth1 = $dbh->prepare(<<'EOT');
SELECT cd.title
FROM cd
LEFT JOIN artist ON artist.cd = cd.id
WHERE artist.name LIKE ?
GROUP BY cd.title
HAVING count( artist.cd ) = 2
EOT
my $sth2 = $dbh->prepare(<<'EOT');
SELECT cd.title
FROM cd
LEFT JOIN artist ON artist.cd = cd.id
WHERE artist.name LIKE ?
GROUP BY cd.title
HAVING count( artist.cd ) = ?
EOT
$sth1->execute('max%');
# says 'hit'
say 'sth1: hit' if $sth1->fetch;
$sth2->execute('max%', 2);
# stays silent
say 'sth2: hit' if $sth2->fetch;
謝謝你,DDL。
uj5u.com熱心網友回復:
在?準備好的陳述句中,占位符總是被一個字串(如'2')替換,這對于 SQLite沒有親和力。
從SQLite/Affinity Of Expressions中的資料型別派生出一個類似的運算式count(artist.cd),盡管它記錄了它回傳一個整數,但沒有親和力。
此外,從比較之前的 SQLite/型別轉換中的資料型別派生出兩個沒有關聯的運算元在沒有任何隱式資料型別轉換的情況下進行比較。
對于 SQLite,運算式2 = '2'回傳false.
這就是為什么您必須對?占位符應用資料型別轉換以將其轉換為數值的原因,您可以這樣做:
HAVING count( artist.cd ) = ? 0
此外,與您的問題無關,WHERE您的查詢中的子句使LEFT聯接的行為類似于INNER聯接,因為它應用于右表的列并過濾掉任何不匹配的行。
uj5u.com熱心網友回復:
我不知道為什么占位符被視為字串[1],但您可以通過讓 SQLite 將值視為整數來使代碼正常作業。以下兩種解決方案都是實作此目的的方法:
my $sth2 = $dbh->prepare(<<'EOT');
SELECT cd.title
FROM cd
LEFT JOIN artist ON artist.cd = cd.id
WHERE artist.name LIKE ?
GROUP BY cd.title
HAVING count( artist.cd ) = ?
EOT
$sth2->bind_param(1, 'max%');
$sth2->bind_param(2, 2, DBI::SQL_INTEGER);
$sth2->execute();
my $sth2 = $dbh->prepare(<<'EOT');
SELECT cd.title
FROM cd
LEFT JOIN artist ON artist.cd = cd.id
WHERE artist.name LIKE ?
GROUP BY cd.title
HAVING count( artist.cd ) = CAST( ? AS INTEGER )
EOT
$sth2->execute('max%', 2);
- 另一個答案聲稱占位符始終被視為字串。這不僅不是解釋,甚至不是真的。他們的這種未經證實的主張顯然是錯誤的,因為
bind_param可能導致占位符被視為字串以外的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/425542.html
上一篇:為什么這些值有時未定義?
