从 mysql 更新到 mysqli 后数据库查询中断
Posted
技术标签:
【中文标题】从 mysql 更新到 mysqli 后数据库查询中断【英文标题】:Database query broken since updating from mysql to mysqli 【发布时间】:2015-05-26 22:53:04 【问题描述】:我继承了一个网站,该网站有一系列最初使用 mysql_query 编码的数据库查询。 由于 zen cart 的更新,从 mysql 移动到 mysqli 这些查询必须更新。由于将查询更改为 mysqli,因此该功能已损坏。
原来的查询是:
function insert_FENQUIRY()
$sql = sprintf('INSERT INTO FENQUIRY
(ENREGION, ENNAME, ENCOMP, ENADD1, ENADD2, ENADD3, ENCNTY, ENPCODE, ENCNTRY, ENTEL, ENDATE, ENDATELCON, ENCAT, ENCONSRS, ENADVER, ENTYPE, EN_CUSTOMER_ID)
SELECT
(SELECT region FROM postcode2region WHERE ab.entry_postcode REGEXP CONCAT("^", postcode_prefix, "[:digit:]*") ORDER BY postcode_prefix DESC LIMIT 1) AS ENREGION,
c.ENCONNAME AS ENNAME,
IF(ab.entry_company <> "", ab.entry_company, CONCAT(c.ENCONNAME, " - online")) AS ENCOMP,
ab.entry_street_address AS ENADD1,
ab.entry_suburb AS ENADD2,
ab.entry_city AS ENADD3,
ab.entry_state AS ENCNTY,
ab.entry_postcode AS ENPCODE,
cc.countries_name AS ENCNTRY,
c.ENCONTEL AS ENTEL,
CURDATE() AS ENDATE,
CURDATE() AS ENDATELCON,
"X" AS ENCAT,
1 AS ENCONSRS,
"WWW" AS ENADVER,
"70" AS ENTYPE,
c.ENCON_ID AS EN_CUSTOMER_ID
FROM FENQCON c
LEFT JOIN address_book ab ON ab.address_book_id = c.ENCON_ZEN_DEFAULT_ADDRESS_ID
LEFT JOIN countries cc ON cc.countries_id = ab.entry_country_id
WHERE c.ENCON_ID = %d
LIMIT 1',
$_SESSION['customer_id']);
mysql_query($sql) or error_log("KG insert_FENQUIRY() : ". mysql_error());
return mysql_insert_id();
function insert_FENQCON()
global $firstname, $lastname, $password, $gender, $newsletter, $email_format, $email_address,
$telephone, $fax, $company, $postcode;
$q = mysql_query(sprintf('
INSERT INTO FENQCON
SET
ENCONFNAME = "%s",
ENCONLNAME = "%s",
ENCON_ZEN_PASSWORD = "%s",
ENCON_ZEN_GENDER = "%s",
ENCON_ZEN_NEWSLETTER = "%s",
ENCON_ZEN_EMAIL_FORMAT = "%s",
ENCON_ZEN_AUTHORIZATION = "%s",
ENCONEMAIL = "%s",
ENCONTEL = "%s",
ENCONFAX = "%s",
ENCONDATE = CURDATE(),
ENCONNAME = "%s",
ENCON_OPTIN = 1,
ENCON_ZEN_ISLOGIN = 1
',
mysql_escape_string($firstname),
mysql_escape_string($lastname),
zen_encrypt_password($password),
mysql_escape_string($gender),
(int) $newsletter,
mysql_escape_string($email_format),
(int) CUSTOMERS_APPROVAL_AUTHORIZATION,
mysql_escape_string($email_address),
mysql_escape_string($telephone),
mysql_escape_string($fax),
mysql_escape_string("$firstname $lastname")
)) or die(mysql_error());
return mysql_insert_id();
function update_FENQCON_with_login()
global $firstname, $lastname, $password, $gender, $newsletter, $email_format;
$q = mysql_query(sprintf('
UPDATE FENQCON
SET
ENCONFNAME = "%s",
ENCONLNAME = "%s",
ENCON_ZEN_PASSWORD = "%s",
ENCON_ZEN_GENDER = "%s",
ENCON_ZEN_NEWSLETTER = "%s",
ENCON_ZEN_EMAIL_FORMAT = "%s",
ENCON_ZEN_AUTHORIZATION = "%s",
ENCON_ZEN_ISLOGIN = 1,
ENCONCUSTOMER_ID = %d
WHERE ENCON_ID = %d',
mysql_escape_string($firstname),
mysql_escape_string($lastname),
zen_encrypt_password($password),
mysql_escape_string($gender),
(int) $newsletter,
mysql_escape_string($email_format),
(int) CUSTOMERS_APPROVAL_AUTHORIZATION,
$_SESSION['customer_id'],
$_SESSION['customer_id'] // WHERE
)) or die(mysql_error());
// FENQUIRY FLAG
$flag_insert_into_FENQUIRY = false;
// Check if email exists in FENQCON
$sql = sprintf('
SELECT
c.ENCON_ID,
c.ENCONCODE,
c.ENCONFNAME,
c.ENCONLNAME,
c.ENCONCSUNIQUE,
q.ENPCODE,
q.ENCOMP,
(SOUNDEX(c.ENCONFNAME) = SOUNDEX("%1$s")) * 1
+(SOUNDEX(c.ENCONLNAME) = SOUNDEX("%2$s")) * 1
+ROUND(levenshtein_ratio(REPLACE(q.ENPCODE, " ", ""), REPLACE("%4$s", " ", "")) / 100 * 2)
+ROUND(levenshtein_ratio(q.ENCOMP, "%5$s") / 100 * 2)
AS Score
FROM FENQCON c
LEFT JOIN FENQUIRY q ON q.ENCSUNIQUE = c.ENCONCSUNIQUE
WHERE c.ENCONEMAIL = "%3$s"
ORDER BY Score DESC, c.ENCON_ID ASC
LIMIT 1',
mysql_escape_string($firstname), // %1
mysql_escape_string($lastname), // %2
mysql_escape_string($email_address), // %3
mysql_escape_string($postcode), // %4
mysql_escape_string($company) // %5
);
$q = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($q) == 1) // We have a matching existing FENQCON row
$FENQCON = mysql_fetch_object($q);
mysql_free_result($q);
error_log("KG FENQCON exists: ". print_r($FENQCON, true));
$_SESSION['customer_id'] = $FENQCON->ENCON_ID ;
$FENQUIRY = null;
if ($FENQCON->ENCONCSUNIQUE > 0) // Fetch a linked FENQUIRY row if it exists and is linked!
$q = mysql_query(sprintf('SELECT * FROM FENQUIRY WHERE ENCSUNIQUE = %d', $FENQCON->ENCONCSUNIQUE));
$FENQUIRY = mysql_fetch_object($q);
mysql_free_result($q);
update_FENQCON_with_login();
if ($FENQUIRY)
// Nothing to do
else
$flag_insert_into_FENQUIRY = true;
else // We need to create a new FENQCON and FENQUIRY rows
error_log("KG No matching FENQCON found.");
$_SESSION['customer_id'] = insert_FENQCON();
error_log("KG New FENQCON added with ENCON_ID: ". $_SESSION['customer_id']);
$flag_insert_into_FENQUIRY = true;
此时一切正常。 如下所示更新了查询以使用 mysqli,它现在仅部分起作用。
function insert_FENQUIRY()
$connect = mysqli_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
$sql = sprintf('INSERT INTO FENQUIRY
(ENREGION, ENNAME, ENCOMP, ENADD1, ENADD2, ENADD3, ENCNTY, ENPCODE, ENCNTRY, ENTEL, ENDATE, ENDATELCON, ENCAT, ENCONSRS, ENADVER, ENTYPE, EN_CUSTOMER_ID)
SELECT
(SELECT region FROM postcode2region WHERE ab.entry_postcode REGEXP CONCAT("^", postcode_prefix, "[:digit:]*") ORDER BY postcode_prefix DESC LIMIT 1) AS ENREGION,
c.ENCONNAME AS ENNAME,
IF(ab.entry_company <> "", ab.entry_company, CONCAT(c.ENCONNAME, " - online")) AS ENCOMP,
ab.entry_street_address AS ENADD1,
ab.entry_suburb AS ENADD2,
ab.entry_city AS ENADD3,
ab.entry_state AS ENCNTY,
ab.entry_postcode AS ENPCODE,
cc.countries_name AS ENCNTRY,
c.ENCONTEL AS ENTEL,
CURDATE() AS ENDATE,
CURDATE() AS ENDATELCON,
"X" AS ENCAT,
1 AS ENCONSRS,
"WWW" AS ENADVER,
"70" AS ENTYPE,
c.ENCON_ID AS EN_CUSTOMER_ID
FROM FENQCON c
LEFT JOIN address_book ab ON ab.address_book_id = c.ENCON_ZEN_DEFAULT_ADDRESS_ID
LEFT JOIN countries cc ON cc.countries_id = ab.entry_country_id
WHERE c.ENCON_ID = %d
LIMIT 1',
$_SESSION['customer_id']);
mysqli_query($connect,$sql) or error_log("KG insert_FENQUIRY() : ". mysql_error());
return mysqli_insert_id($connect);
function insert_FENQCON()
global $firstname, $lastname, $password, $gender, $newsletter, $email_format, $email_address,
$telephone, $fax, $company, $postcode;
$connect = mysqli_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
$q = mysqli_query($connect,sprintf('
INSERT INTO FENQCON
SET
ENCONFNAME = "%s",
ENCONLNAME = "%s",
ENCON_ZEN_PASSWORD = "%s",
ENCON_ZEN_GENDER = "%s",
ENCON_ZEN_NEWSLETTER = "%s",
ENCON_ZEN_EMAIL_FORMAT = "%s",
ENCON_ZEN_AUTHORIZATION = "%s",
ENCONEMAIL = "%s",
ENCONTEL = "%s",
ENCONFAX = "%s",
ENCONDATE = CURDATE(),
ENCONNAME = "%s",
ENCON_OPTIN = 1,
ENCON_ZEN_ISLOGIN = 1
',
mysqli_escape_string($connect,$firstname),
mysqli_escape_string($connect,$lastname),
zen_encrypt_password($password),
mysqli_escape_string($connect,$gender),
(int) $newsletter,
mysqli_escape_string($connect,$email_format),
(int) CUSTOMERS_APPROVAL_AUTHORIZATION,
mysqli_escape_string($connect,$email_address),
mysqli_escape_string($connect,$telephone),
mysqli_escape_string($connect,$fax),
mysqli_escape_string($connect,"$firstname $lastname")
)) or die(mysqli_error());
return mysqli_insert_id($connect);
function update_FENQCON_with_login()
global $firstname, $lastname, $password, $gender, $newsletter, $email_format;
$connect = mysqli_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
$q = mysqli_query($connect,sprintf('
UPDATE FENQCON
SET
ENCONFNAME = "%s",
ENCONLNAME = "%s",
ENCON_ZEN_PASSWORD = "%s",
ENCON_ZEN_GENDER = "%s",
ENCON_ZEN_NEWSLETTER = "%s",
ENCON_ZEN_EMAIL_FORMAT = "%s",
ENCON_ZEN_AUTHORIZATION = "%s",
ENCON_ZEN_ISLOGIN = 1,
ENCONCUSTOMER_ID = %d
WHERE ENCON_ID = %d',
mysqli_escape_string($connect,$firstname),
mysqli_escape_string($connect,$lastname),
zen_encrypt_password($password),
mysqli_escape_string($connect,$gender),
(int) $newsletter,
mysqli_escape_string($connect,$email_format),
(int) CUSTOMERS_APPROVAL_AUTHORIZATION,
$_SESSION['customer_id'],
$_SESSION['customer_id'] // WHERE
)) or die(mysqli_error());
// FENQUIRY FLAG
$flag_insert_into_FENQUIRY = false;
// Check if email exists in FENQCON
$connect = mysqli_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
$sql = sprintf('
SELECT
c.ENCON_ID,
c.ENCONCODE,
c.ENCONFNAME,
c.ENCONLNAME,
c.ENCONCSUNIQUE,
q.ENPCODE,
q.ENCOMP,
(SOUNDEX(c.ENCONFNAME) = SOUNDEX("%1$s")) * 1
+(SOUNDEX(c.ENCONLNAME) = SOUNDEX("%2$s")) * 1
+ROUND(levenshtein_ratio(REPLACE(q.ENPCODE, " ", ""), REPLACE("%4$s", " ", "")) / 100 * 2)
+ROUND(levenshtein_ratio(q.ENCOMP, "%5$s") / 100 * 2)
AS Score
FROM FENQCON c
LEFT JOIN FENQUIRY q ON q.ENCSUNIQUE = c.ENCONCSUNIQUE
WHERE c.ENCONEMAIL = "%3$s"
ORDER BY Score DESC, c.ENCON_ID ASC
LIMIT 1',
mysqli_escape_string($connect,$firstname), // %1
mysqli_escape_string($connect,$lastname), // %2
mysqli_escape_string($connect,$email_address), // %3
mysqli_escape_string($connect,$postcode), // %4
mysqli_escape_string($connect,$company) // %5
);
$q = mysqli_query($connect,$sql) or die(mysqli_error());
if (mysqli_num_rows($q) == 1) // We have a matching existing FENQCON row
$FENQCON = mysqli_fetch_object($q);
mysqli_free_result($q);
error_log("KG FENQCON exists: ". print_r($FENQCON, true));
$_SESSION['customer_id'] = $FENQCON->ENCON_ID ;
$FENQUIRY = null;
if ($FENQCON->ENCONCSUNIQUE > 0) // Fetch a linked FENQUIRY row if it exists and is linked!
$q = mysqli_query($connect,sprintf('SELECT * FROM FENQUIRY WHERE ENCSUNIQUE = %d', $FENQCON->ENCONCSUNIQUE));
$FENQUIRY = mysqli_fetch_object($q);
mysqli_free_result($q);
update_FENQCON_with_login();
if ($FENQUIRY)
// Nothing to do
else
$flag_insert_into_FENQUIRY = true;
else // We need to create a new FENQCON and FENQUIRY rows
error_log("KG No matching FENQCON found.");
$_SESSION['customer_id'] = insert_FENQCON();
error_log("KG New FENQCON added with ENCON_ID: ". $_SESSION['customer_id']);
$flag_insert_into_FENQUIRY = true;
错误日志显示
php Warning: mysqli_error() expects exactly 1 parameter, 0 given
这个错误发生在
$q = mysqli_query($connect,$sql) or die(mysqli_error());
以下代码段
$connect = mysqli_connect(DB_SERVER, DB_SERVER_USERNAME, DB_SERVER_PASSWORD, DB_DATABASE);
$sql = sprintf('
SELECT
c.ENCON_ID,
c.ENCONCODE,
c.ENCONFNAME,
c.ENCONLNAME,
c.ENCONCSUNIQUE,
q.ENPCODE,
q.ENCOMP,
(SOUNDEX(c.ENCONFNAME) = SOUNDEX("%1$s")) * 1
+(SOUNDEX(c.ENCONLNAME) = SOUNDEX("%2$s")) * 1
+ROUND(levenshtein_ratio(REPLACE(q.ENPCODE, " ", ""), REPLACE("%4$s", " ", "")) / 100 * 2)
+ROUND(levenshtein_ratio(q.ENCOMP, "%5$s") / 100 * 2)
AS Score
FROM FENQCON c
LEFT JOIN FENQUIRY q ON q.ENCSUNIQUE = c.ENCONCSUNIQUE
WHERE c.ENCONEMAIL = "%3$s"
ORDER BY Score DESC, c.ENCON_ID ASC
LIMIT 1',
mysqli_escape_string($connect,$firstname), // %1
mysqli_escape_string($connect,$lastname), // %2
mysqli_escape_string($connect,$email_address), // %3
mysqli_escape_string($connect,$postcode), // %4
mysqli_escape_string($connect,$company) // %5
);
$q = mysqli_query($connect,$sql) or die(mysqli_error());
数据正在正确写入 FENQCON 表,但没有写入 FENQUIRY 表。我可以看到这是由于上述查询失败导致 $flag_insert_into_FENQUIRY = true;永远不会跑。
任何 mysqli 专家都可以在这里指出正确的方向吗,因为我看不到代码失败的原因。我在这里阅读了无数关于 mysql 到 mysqli 转换的帖子,我认为我做得对。
【问题讨论】:
在任何地方尝试mysqli_error($connect)
。去吧,告诉发生了什么?
您的复制和粘贴是否出错?你说它转换为mysqli的第二部分仍然是mysql
@anantkumarsingh FUNCTION ded.levenshtein_ratio 不存在
你是在别的地方调用这个函数吗?我没有看到任何引用ded.levenshtein_ratio
的行;是完整的代码吗?
注意,我看到你在查询变量中转义了很多变量;这对我来说有点奇怪。您是否可以a)在它们进入查询之前将它们转义,或者更好,因为您正在转换为mysqli,将其作为准备好的语句重做?
【参考方案1】:
试试这个...
$q = mysqli_query($connect,$sql) or die(mysqli_error($connect));
更新:
现在您已经解决了上述问题,看来您需要解决将 Levenshtein 库添加到 MySQL 安装的新问题,以便您可以运行 levenshtein_ratio()
函数。这可能会有所帮助:https://samjlevy.com/mysql-levenshtein-and-damerau-levenshtein-udfs/
【讨论】:
这给了我一些奇怪的错误信息 FUNCTION ded.levenshtein_ratio 不存在 我看到它是一个用于查看结果之间相似性的函数。这对 mysqli 查询不起作用是否可行? @StevePrice 你用的是什么版本的 MySQL? 尽快升级。安全漏洞 您安装的 MySQL 可能没有安装 levenshtein 库来运行该功能。这可能会为您提供一些启示:samjlevy.com/mysql-levenshtein-and-damerau-levenshtein-udfs以上是关于从 mysql 更新到 mysqli 后数据库查询中断的主要内容,如果未能解决你的问题,请参考以下文章
更新 WordPress 以使用 mysqli 而不是 mysql