Mysql

MySQL:為什麼我會收到這個警告?

  • August 10, 2017

我正在呼叫下面的儲存過程,並收到此警告,此警告是誤報還是我的查詢不安全?

1 queries executed, 1 success, 0 errors, 1 warnings

Query: call User_Signup('lee3@gmail.com', 'password', 'Lee', 'Brooks', null, null, null, null)

1 row(s) affected, 1 warning(s)

Execution Time : 0.042 sec
Transfer Time  : 0.093 sec
Total Time     : 0.136 sec

Note Code : 1592
Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave.

這是電話:

CALL User_Signup('lee3@gmail.com', 'password', 'Lee', 'Brooks', NULL, NULL, NULL, NULL);

這是儲存過程:

DELIMITER $$

USE `MobiFit_Dev` $$

DROP PROCEDURE IF EXISTS `User_Signup` $$

CREATE DEFINER = `root` @`localhost` PROCEDURE `User_Signup` (
 email VARCHAR (250),
 hashedPassword BINARY(60),
 firstName VARCHAR (100),
 lastName VARCHAR (100),
 gender ENUM ('Male', 'Female'),
 dateOfBirth DATE,
 height DECIMAL (3, 2),
 currentWeight DECIMAL (4, 1)
) 
BEGIN
 INSERT INTO USER (
   Email,
   HashedPassword,
   RoleId,
   FirstName,
   LastName,
   Gender,
   DateOfBirth,
   Height,
   CurrentWeight,
   CreatedAt
 ) 
 VALUES
   (
     email,
     hashedPassword,
     (SELECT 
       id 
     FROM
       Role 
     WHERE `Code` = 'CUSTOMER'),
     firstName,
     lastName,
     gender,
     dateOfBirth,
     height,
     currentWeight,
     UTC_TIMESTAMP()
   ) ;
END $$

DELIMITER ;

這個警告是非常真實和正確的。為什麼??

該警告旨在讓 DBA 和開發人員挑選不合時宜的東西。

什麼是時代錯誤?想想這些類比:

  • 1930年有一部手機
  • 1976 年在筆記型電腦中使用
  • 擁有公元前 5 年的硬幣(可能是假的)

從本質上講,它擁有一個在其時間之前就存在的對象。

看查詢。要評估的 INSERT 的第一部分是

(SELECT id FROM Role 
 WHERE `Code` = 'CUSTOMER')

在高寫入數據庫環境中,如果在一個數據庫連接中將 id 插入到角色表中,並且您在另一個數據庫連接中執行了 INSERT,則可能會出現競爭條件。如何?

  • 如果首先將客戶角色插入到角色表中,您將獲得 id 的數值
  • 如果最後將客戶角色插入到角色表中,則 id 為 NULL

如果您嘗試從二進制日誌中恢復,這種情況由創建條目的順序決定,會產生不一致的結果。這種情況在進行主/從複製時更加明顯,因為從理論上講,由於這個原因,從屬可能是不一致的。

在您的特定情況下,您可以鬆一口氣,因為您,開發人員/DBA,已經在 Role 表中預定義了角色 CUSTOMER。你不用擔心,對嗎???

因此,該警告只是提醒每個人簡化數據輸入。

您可以忽略該特定警告。

但是,為了清楚起見,或者如果您希望錯誤日誌因警告而停止增長,您應該這樣做:

步驟 01

使儲存過程如下:

DELIMITER $$

USE `MobiFit_Dev` $$

DROP PROCEDURE IF EXISTS `User_Signup` $$

CREATE DEFINER = `root` @`localhost` PROCEDURE `User_Signup` (
 email VARCHAR (250),
 hashedPassword BINARY(60),
 User_Role INT,
 firstName VARCHAR (100),
 lastName VARCHAR (100),
 gender ENUM ('Male', 'Female'),
 dateOfBirth DATE,
 height DECIMAL (3, 2),
 currentWeight DECIMAL (4, 1)
) 
BEGIN
 INSERT INTO USER (
   Email,
   HashedPassword,
   RoleId,
   FirstName,
   LastName,
   Gender,
   DateOfBirth,
   Height,
   CurrentWeight,
   CreatedAt
 ) 
 VALUES
   (
     email,
     hashedPassword,
     User_Role,
     firstName,
     lastName,
     gender,
     dateOfBirth,
     height,
     currentWeight,
     UTC_TIMESTAMP()
   ) ;
END $$

步驟 02

呼叫儲存過程時,檢索 role_id 並將其傳遞給儲存過程:

SELECT id INTO @GivenRoleID FROM Role  WHERE `Code` = 'CUSTOMER';
User_Signup('lee3@gmail.com', 'password', @GivenRoleID, 'Lee', 'Brooks',
null, null, null, null);

試一試 !!!

引用自:https://dba.stackexchange.com/questions/56959