2013-01-22 24 views
6

Tôi có một câu hỏi như thế này: (trên PostgreSQL 8.4, PHP-FPM 5.3.10 (fpm-fcgi))Làm cách nào để chèn những thứ như "now() -interval '2 minutes'" vào truy vấn PHP PDO?

select * from users where now() - interval '2 minutes' < seenlast ORDER BY seenlast; 

Tôi muốn sử dụng PHP/PDO truy vấn, vì vậy:

$mymin=5; //this is a variable can be changed by $_GET 
$query = $db_conn->prepare("select * from users where now() - interval ':myminute minutes' < seenlast ORDER BY seenlast"); 
$query->bindParm(":myminute",$mymin) 
$query->execute; 

Điều này không hoạt động, tôi không thể tìm được cách để chuyển số phút ($ mymin) theo cách phù hợp. Nếu tôi hardcode các everithing timestuff hoạt động, do đó, các phần khác của mã phải được chính xác.

Tôi cũng đã cố gắng:

$temp=$mymin." minutes"; 
$query = $db_conn->prepare("select * from users where now() - interval :myminute < seenlast ORDER BY seenlast"); 
$query->bindParm(":myminute",$temp) 

I already saw this, didn't help

+0

tôi đã cùng một vấn đề nhưng đã nhận lỗi: 'SQLSTATE [HY105]: Invalid loại tham số: 7'.Điều này là do tôi có nhiều tham số hơn so với các thay thế được phát hiện (dấu hỏi) khi sử dụng các tham số chưa đặt tên. –

Trả lời

11

Khoảng thể được nhân với số. Vì vậy, một cách tiếp cận này là để chuẩn bị tuyên bố nói interval '1 minute' * :myminutes thay vào đó, chuyển tham số "myminutes" dưới dạng một số nguyên đơn giản.

+0

Giải pháp hoàn hảo: D – ykat

-2
... - INTERVAL :myminute MINUTES ... 

mà không có dấu ngoặc kép là phương pháp thích hợp. Nếu có ích, hãy nghĩ về trình giữ chỗ tương đương với việc sử dụng phương pháp xây dựng truy vấn dựa trên biến trường cũ

... - INTERVAL $myminute MINUTES 

ngoại trừ phần giữ chỗ chăm sóc các lỗ hổng tiêm mà các biến không làm. Chỉ vì bạn đang sử dụng trình giữ chỗ không có nghĩa là bạn có thể thay đổi cú pháp SQL, do đó,

... - INTERVAL '2 minutes' 
... - INTERVAL ':myminute minute' 

không phải là SQL hợp lệ.


followup cho mu:

mysql> select now() + interval '2 minute'; 
ERROR 1064 (42000): 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 '' at line 1 
mysql> select now() + interval 2 minute; 
+---------------------------+ 
| now() + interval 2 minute | 
+---------------------------+ 
| 2013-01-22 13:38:24  | 
+---------------------------+ 
1 row in set (0.02 sec) 
+0

cảm ơn cho answare nhưng vẫn không có may mắn: ( – ykat

+0

Tôi nghi ngờ 'INTERVAL: myminute MINUTES' sẽ hoạt động, tôi mong đợi rằng để tạo ra một lỗi cú pháp' INTERVAL '2 minutes'' OTOH là hoàn toàn tốt; 'interval' 3 minutes'' là một hoạt động cast và chỉ là một cách khác để viết ''3 minutes' :: interval' hoặc' cast ('3 minutes' như interval) '. –

+0

@muistooshort: sai. xem chỉnh sửa ở trên. –

5

Tôi không biết nhiều PDO hoặc PHP nhưng tôi nghĩ rằng tôi biết những gì đang xảy ra ở đây.

Khi bạn nói điều này:

interval '3 minutes' 

Bạn đang thực sự thực hiện một hoạt động diễn viên đó là giống như:

'3 minutes'::interval 
cast('3 minutes' as interval) 

Vì vậy, những gì bạn đang làm là đúc một giá trị TEXT đến một INTERVAL . Điều đó có nghĩa là bạn cần tạo ra thứ gì đó trông giống như chuỗi '3 minutes'. Bạn có thể dán các mảnh chuỗi với nhau bằng dây nối:

# Use cast to make the precedence cleaner. 
$query = $db_conn->prepare("select * from users where now() - cast(:myminute || ' minutes' as interval) < seenlast ORDER BY seenlast"); 
$query->bindParm(":myminute", $mymin) 

Hoặc bạn sẽ có thể làm chuỗi tranh cãi trong PHP:

$query = $db_conn->prepare("select * from users where now() - interval :myminute < seenlast ORDER BY seenlast"); 
$query->bindParm(":myminute", $mymin . ' minutes') 
+0

Đó là một ngày dài, ngày mai tôi cũng sẽ kiểm tra điều này. – ykat

0

Tôi đã đấu tranh với Phalcon và Mô hình nội PDO phân tích cú pháp của nó trong nhiều giờ với cùng một vấn đề.

tôi tìm thấy giải pháp này:

public static function getTimedoutRequests($secsThreshold) { 
    return self::find(
     array(
      // PDO is buggy here, can't use INTERVAL 
      "DATE_PART('epoch', create_time) < DATE_PART('epoch', NOW()) - ?0", 
      "bind" => array(
       $secsThreshold 
      ) 
     ) 
    ); 
} 
Các vấn đề liên quan