2014-06-23 38 views
2

我有一個查詢計算是基於此文檔的點的一定半徑內的對象:http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/perl的錯誤傳遞時DBI->執行值IN子句

它的工作原理很漂亮,但是我想只搜索那些特定類型的對象,這會導致問題;

的代碼看起來是這樣的:

my $sql = "SELECT * 
FROM (
SELECT b.*, pr.postcode, pr.prize, pr.title, pr.collection, pr.redeemed, pr.delivery, pr.archived, bt.category, 
     p.radius, 
     p.distance_unit 
       * DEGREES(ACOS(COS(RADIANS(p.latpoint)) 
       * COS(RADIANS(b.lat)) 
       * COS(RADIANS(p.longpoint - b.lng)) 
       + SIN(RADIANS(p.latpoint)) 
       * SIN(RADIANS(b.lat)))) AS distance 
    FROM bubbles AS b, bubble_prizes AS pr, bubble_types AS bt 
    JOIN ( /* these are the query parameters */ 
     SELECT ? AS latpoint, ? AS longpoint, 
       ? AS radius,  ? AS distance_unit 
    ) AS p 
    WHERE b.lat 
    BETWEEN p.latpoint - (p.radius/p.distance_unit) 
     AND p.latpoint + (p.radius/p.distance_unit) 
    AND b.lng 
    BETWEEN p.longpoint - (p.radius/(p.distance_unit * COS(RADIANS(p.latpoint)))) 
     AND p.longpoint + (p.radius/(p.distance_unit * COS(RADIANS(p.latpoint)))) 
    AND pr.bubble = b.id 
    AND b.type IN ? 
    AND b.type = bt.type 
) AS d 
WHERE distance <= radius 
ORDER BY distance";  

然後我做

my $points = $y->dbh->prepare($sql); 
$results = $points->execute($lat, $lng, $rad, $units, '(type1, type2)'); 

位置 '(TYPE1,TYPE2)' 應該傳遞給

b.type IN ? 

(這是近SQL的底部)。

我已經想盡辦法,我能想到的逃離這個字符串,以便它的作品(包括很多方面是清楚的瘋狂,但我越來越絕望)INC

'(type1, type2)' 
'\(\'type1\', \'type2\'\)' 
'(\'type1\', \'type2\')' 
"('type1', 'type2')" 

等(我已經試過這麼多的東西,我甚至不能全部記住它們。)

無論我怎麼努力,我得到的形式

DBD::mysql::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''(type1, type2)' 
    AND b.type = bt.type 
) AS d 
WHERE distance <= radius' 

的SQL錯誤取決於我如何試圖逃脫字符串,t他的錯誤信息稍有不同,但總是與sql的相同部分有關。

我現在在想,轉義不是我的問題,我錯過了一些關於執行的東西。如果我在DB中運行代碼,它可以正常使用IN語句,即b.type IN('type1','type2')正常工作。

有人能夠啓發我嗎?我該如何做到這一點?

感謝

回答

2

您將需要IN (...)語句中使用佔位符。​​的整個點是爲了避免SQL注入,並且你基本上試圖在那裏注入SQL。你可以這樣做一個動態的佔位符列表:

my @types = qw(type1 type2); 
my $placeholders = join ", ", ("?") x @types; 
my $sql = "... 
     b.typeID IN ($placeholders) 
    ..."; 
my $points = $y->dbh->prepare($sql); 
$results = $points->execute($lat, $lng, $rad, $units, @types); 
+0

這樣做了,謝謝 – mark