2013-08-03 40 views
21

Tôi nhận được thông báo lỗi "SQLSTATE [HY093]: số tham số không hợp lệ" khi tôi cố gắng để chạy các chức năng dưới đây:PHP PDOException: "SQLSTATE [HY093]: số tham số không hợp lệ"

function add_persist($db, $user_id) { 
    $hash = md5("per11".$user_id."sist11".time()); 
    $future = time()+(60*60*24*14); 
    $sql = "INSERT INTO persist (user_id, hash, expire) VALUES (:user_id, :hash, :expire) ON DUPLICATE KEY UPDATE hash=:hash"; 
    $stm = $db->prepare($sql); 
    $stm->execute(array(":user_id" => $user_id, ":hash" => $hash, ":expire" => $future)); 
    return $hash; 
} 

tôi cảm thấy như nó đơn giản mà tôi không bắt được. Bất kỳ ý tưởng?

+9

'Bạn không thể sử dụng dấu tham số được đặt tên có cùng tên hai lần trong câu lệnh đã chuẩn bị.' [http://php.net/manual/en/pdo.prepare.php](http://php.net/ manual/en/pdo.prepare.php) – bitWorking

+0

Tôi hiểu rằng bài đăng đó cũng có câu trả lời cũng trả lời câu hỏi của tôi, nhưng câu hỏi của tôi chắc chắn không phải là bản sao có thể. – vijrox

+0

Trong câu hỏi khác, 'fetchAll()' trả về không có gì vì truy vấn không thành công giống như của bạn. Các tác giả khác chỉ không nhận thấy nó. Đây là cơ bản cùng một vấn đề, do đó, nó là giá trị liên kết hai. – RandomSeed

Trả lời

33

Hãy thử:

$sql = "INSERT INTO persist (user_id, hash, expire) VALUES (:user_id, :hash, :expire) ON DUPLICATE KEY UPDATE hash=:hash2"; 

$stm->execute(array(":user_id" => $user_id, ":hash" => $hash, ":expire" => $future, ":hash2" => $hash)); 

Trích từ tài liệu (http://php.net/manual/en/pdo.prepare.php):

Bạn phải bao gồm một marker tham số duy nhất cho mỗi giá trị mà bạn muốn vượt qua trong vào câu lệnh khi bạn gọi PDOStatement :: execute(). Bạn không thể sử dụng một dấu tham số được đặt tên có cùng tên hai lần trong một câu lệnh đã chuẩn bị. Bạn không thể liên kết nhiều giá trị với một tham số được đặt tên duy nhất, ví dụ, mệnh đề IN() của một câu lệnh SQL.

+0

nó đã làm việc! Tôi sẽ chấp nhận câu trả lời của bạn ngay khi stack cho phép tôi. Tại sao phương pháp gốc không hoạt động? – vijrox

+0

@VijayRamamurthy, vui lòng đọc qua: http://php.net/manual/en/pdo.prepare.php – vee

+0

Sự khác biệt giữa câu trả lời của bạn và câu hỏi của OP là gì? – Shafizadeh

15

Đây là một hạn chế khi sử dụng PDO. PDO chỉ đơn giản là thừa nhận số lượng tham số trong truy vấn và thực thi và đưa ra một lỗi trên bất kỳ sự không phù hợp nào. Nếu bạn cần phải sử dụng tham số lặp lại trong các truy vấn của bạn, bạn phải đi về nó sử dụng một workaround

$sql = "insert into persist(user_id, hash, expire) values 
    (:user_id, :hash, :value) on duplicate key update 
    hash = :hash2"; 
$stm->execute(array(':user_id' => $user_id, ':hash' => $hash, ':hash2' => $hash, 
    ':expire' => $expire)); 

Bạn có thể tham khảo này cho một workaround phức tạp hơn - https://stackoverflow.com/a/7604080/1957346

+1

Tuyệt vời! Tôi đã dành hai ngày gỡ lỗi mã mà làm việc trên tất cả mọi thứ khác, ngoại trừ một truy vấn cụ thể. Câu trả lời là (như được đề cập bởi "vijrox" ở trên trong một bình luận) rằng bạn không thể tái sử dụng cùng một tham số có tên trong PDO. Tôi đã có 'UPDATE người dùng SET username =: username, caption =: chú thích WHERE username =: username', sẽ không hoạt động vì': username' xuất hiện hai lần. Bản sửa lỗi đã được đổi tên thành thứ hai, kết thúc với điều này: 'UPDATE người dùng SET username =: username, caption =: chú thích WHERE username =: user' (lần cuối': user' là khác nhau). –

-2
$stmt = $con->prepare("INSERT INTO items(Name, Description, Price, Country_Made, Status, Add_Date) VALUES(:zname, :zdesc, :zprice, :zcountry, zstatus, now())"); 

$stmt-> execute(array(
    "zname" => $name, 
    "zdesc" => $desc, 
    "zprice" => $price, 
    "zcountry" => $country, 
    "zstatus" => $status 
)); 
+2

Hãy luôn thêm một số giải thích cho mã của bạn ... – andreas

+0

Mặc dù mã này có thể giúp giải quyết vấn đề, nó không giải thích _why_ và/hoặc _how_ nó trả lời câu hỏi.Việc cung cấp ngữ cảnh bổ sung này sẽ cải thiện đáng kể giá trị giáo dục lâu dài của nó. Vui lòng [sửa] câu trả lời của bạn để thêm giải thích, bao gồm những giới hạn và giả định được áp dụng. –

2

Tôi biết đây là một câu hỏi cũ, tuy nhiên tôi nghĩ rằng nó đáng chú ý là một giải pháp thích hợp hơn là tránh các cách giải quyết khó khăn trong PHP bằng cách tận dụng SQL một cách thích hợp:

INSERT INTO `persist` (`user_id`, `hash`, `expire`) 
VALUES (:user_id, :hash, :expire) 
ON DUPLICATE KEY UPDATE `hash`=VALUES(`hash`) 

Bằng cách này, bạn chỉ cần gửi giá trị một lần.

Các vấn đề liên quan