我在不認為不匹配的查詢中收到 HY093(引數計數不匹配)SQLSTATE。
下面我有一個完整的 PHP 腳本來重現錯誤。(當然,需要更改資料庫憑據。)在該腳本中,SELECT 陳述句中存在九個問號,搜索陣列中有 9 個值,所有這些值都是為此測驗硬編碼的。然而, SELECT 回傳 false (不會根據需要拋出例外)并且SQLSTATE值為HY093,我的研究告訴我,這表明引數數量不正確。
我的第二個失望是這不會引發錯誤,但主要是我不知道如何查詢該表。
有什么建議可能導致這種情況嗎?或者需要什么其他資訊來確定問題?
Linux velmicro 5.13.0-40-generic #45~20.04.1-Ubuntu SMP Mon Apr 4 09:38:31 UTC 2022 x86_64
PHP 版本 7.4.3
mysql版本是8.0.24
UBUNTU VERSION="20.04.3 LTS (Focal Fossa)"
#! /usr/bin/php
<?php
$pdoOptions = [ PDO::ATTR_EMULATE_PREPARES => false // no emulation mode for "real" prepared stmts
, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // Errors cause exception
, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC // Default fetch mode
, PDO::MYSQL_ATTR_FOUND_ROWS => true
, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
] ;
$pdo = new PDO('mysql:host=hostname.org.com;dbname=mainDb', 'username', 'password', $pdoOptions) ;
$pdo->exec("DROP TABLE IF EXISTS emotes") ;
$pdo->exec(<<<EOS
CREATE TABLE emotes (
id int NOT NULL AUTO_INCREMENT
, emoteChar varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
, epoch int NOT NULL
, name varchar(64) NOT NULL
, image1 varchar(128) DEFAULT NULL
, image2 varchar(128) DEFAULT NULL
, shortcut1 varchar(64) DEFAULT NULL
, shortcut2 varchar(64) DEFAULT NULL
, shortcut3 varchar(64) DEFAULT NULL
, shortcut4 varchar(64) DEFAULT NULL
, shortcut5 varchar(64) DEFAULT NULL
, PRIMARY KEY (id)
, KEY charEffective (emoteChar,epoch)
)
EOS ) ;
$sql = <<<EOS
SELECT id
FROM emotes em
WHERE emoteChar = ?
AND name = ?
AND IFNULL(image1, '') = IFNULL(?, '')
AND IFNULL(image2, '') = IFNULL(?, '')
AND IFNULL(shortcut1, '') = IFNULL(?, '')
AND IFNULL(shortcut2, '') = IFNULL(?, '')
AND IFNULL(shortcut3, '') = IFNULL(?, '')
AND IFNULL(shortcut4, '') = IFNULL(?, '')
AND IFNULL(shortcut5, '') = IFNULL(?, '')
AND NOT EXISTS (SELECT 1
FROM emotes sub
WHERE sub.emoteChar = em.emoteChar
AND sub.epoch > em.epoch
)
EOS ;
$findEmoteStmt = $pdo->prepare($sql) ;
$findValues = [ 'emoteChar' => 'x'
, 'name' => 'name'
, 'image1' => 'image1'
, 'image2' => 'image2'
, 'shortcut1' => 'shortcut1'
, 'shortcut2' => 'shortcut2'
, 'shortcut3' => 'shortcut3'
, 'shortcut4' => 'shortcut4'
, 'shortcut5' => 'shortcut5'
] ;
$searchOk = $findEmoteStmt->execute( $findValues ) ;
if (! $searchOK) {
printf("Could not search emoticon. %d elements in the values.\nSQL='%s'\n values=(%s)\n error=(%s)\n"
, count($findValues)
, $findEmoteStmt->queryString
, implode(',', $findValues)
, implode(',', $findEmoteStmt->errorInfo())
) ;
}
執行:
> php test.php
Could not search emoticon. 9 elements in the values.
SQL='SELECT id
FROM emotes em
WHERE emoteChar = ?
AND name = ?
AND IFNULL(image1, '') = IFNULL(?, '')
AND IFNULL(image2, '') = IFNULL(?, '')
AND IFNULL(shortcut1, '') = IFNULL(?, '')
AND IFNULL(shortcut2, '') = IFNULL(?, '')
AND IFNULL(shortcut3, '') = IFNULL(?, '')
AND IFNULL(shortcut4, '') = IFNULL(?, '')
AND IFNULL(shortcut5, '') = IFNULL(?, '')
AND NOT EXISTS (SELECT 1
FROM emotes sub
WHERE sub.emoteChar = em.emoteChar
AND sub.epoch > em.epoch
)'
values=(x,name,image1,image2,shortcut1,shortcut2,shortcut3,shortcut4,shortcut5)
error=(HY093,,)
uj5u.com熱心網友回復:
f您有位置引數占位符 ( ?),但您的值位于關聯陣列中,PDO 將用于命名引數占位符。你不能混合這些不同的風格。
有兩種方法可以解決此問題。使用一個修復或另一個(不是兩個:-)。
一種解決方法是將簡單陣列傳遞給execute(),而不是關聯陣列:
$searchOk = $findEmoteStmt->execute( array_values($findValues) ) ;
$findValues另一個解決方法是使用與陣列鍵對應的命名引數占位符,如下所示:
...
WHERE emoteChar = :emoteChar
AND name = :name
...
對于其他引數也是如此。
關鍵是,如果您使用位置引數,則傳遞一個簡單的值陣列。如果使用命名引數,則傳遞鍵/值對的關聯陣列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/474806.html
上一篇:如何根據以下記錄洗掉記錄
