1. 程式人生 > >使用 ThinkPHP 框架,mysql 報錯:1364:Field xx doesn't have a default value,laravel 卻沒有報過

使用 ThinkPHP 框架,mysql 報錯:1364:Field xx doesn't have a default value,laravel 卻沒有報過

1364:Field 'sex' doesn't have a default value [ SQL語句 ]

1364:Field 'sex' doesn't have a default value [ SQL語句 ]

 

錯誤解決方法:

關閉MySQL的strict mode的具體做法:

找到MySQL目錄下的my.ini,將其中的sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 修改為sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION",重新啟動 Mysql服務

 

造成問題的原因:

一. Strict Mode的描述:

根據 mysql5.0以上版本 strict mode (STRICT_TRANS_TABLES) 的限制:

1).不支援對not null欄位插入null值

2).不支援對自增長欄位插入''值,可插入null值

3).不支援 text 欄位有預設值

eg:

1.看下面程式碼:(第一個欄位為自增欄位)

$query="insert into demo values('','$firstname','$lastname','$sex')";

上邊程式碼只在非strict模式有效,如果是strict模式下就會出錯。

 

2.$query="insert into demo values(NULL,'$firstname','$lastname','$sex')";

上邊程式碼只在strict模式有效。把空值''換成了NULL.

 

二. 讓資料庫支援Strict Mode:

1.對資料庫結構進行以下改進來支援strict mode:

1) 給所有not null欄位都設定非null預設值,字串預設值為 '',數值預設值為 0,日期預設值為 '0000-00-00 00:00:00'

2) 去掉text欄位的預設值

3) 規範化改進: 把 title 欄位統一改為 varchar(255),把有預設值的null欄位改為not null欄位

 

2.如果安裝的PHP程式資料庫結構關閉Strict mode

1).一個是安裝mysql5.0(含以上)版本的時候去掉strict mode。

編輯 my.ini,關閉Strict Mode:

sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

 

2). 另一個就是修改查詢語句。例如在

if ($this->dbcharset) {

@mysql_query("SET NAMES ".$this->dbcharset);

}

後面執行

mysql_query("SET @@sql_mode = ''");

 

注意確定你使用的是MySQL5 以上版本

 

mysqli方式類似,就是執行的是

mysqli_query($this->connection_id, "SET @@sql_mode = ''");

 

MySQL 1364 錯誤提示:#1364 - Field "XX" doesn't have a default value

MySQL 1364 錯誤提示:#1364 - Field "details" doesn't have a default value。

大概意思是:details欄位沒有預設的數值;也就是說我們沒有為其分配數值,而表中此欄位也沒有設定預設值。

這是MySQL5出來後搞出來的東東,認真看一下my.ini檔案中有這樣一段:

my.ini中相關程式碼

# Set the SQL mode to strict

# sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

假如您無法看到my.ini,你可以執行以下SQL命令。

SQL程式碼

SELECT @@GLOBAL.sql_mode;

您可能一下子就注意到:STRICT_TRANS_TABLES(儲存引擎啟用嚴格模式,非法資料值被拒絕)。這也就是為什麼我們插入資料時返回1364的原因:details欄位沒有設定預設值。

解決辦法有兩種:

第一種:資料庫設計時,可能沒有資料的欄位設定預設值。

第二種:設定SQL的模式,此有兩種方法:

(1),配置my.ini,去掉:STRICT_TRANS_TABLES 重新啟動mysql服務

my.ini配置程式碼

# Set the SQL mode to strict

# sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

(2),執行SQL命令。注:此命令需要許可權!

SQL程式碼

SET @@GLOBAL.sql_mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

解決方法一:

如果是直接用sql語句進行操作mysql,可加上 set sql_mode=";

即可.dedecms採集就是這麼做的

解決方法二:

開啟my.ini,查詢

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

修改為

sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

然後重啟MYSQL

解決方法三:

MySQL 5 uses a strict mode which needs to be disabled.

In Windows, Goto Start–>Programs–>MySQL->MySQL Instance Config Wizard. Follow through the Reconfigure Instance option–>Detailed Configuration–>Continue Next a few screens. At the bottom under Enable TCP/IP option there is 'Enable Strict Mode'. Deslect this option (no tick). Save changes and MySQL will restart

  原來在MySQL 5.0.2之前,MySQL對非法或不當值並不嚴厲,而且為了資料輸 入還會強制將它們變為合法值。在MySQL 5.0.2和更高版本中,保留了以前的預設行為,但你可以為不良值選擇更傳統的處理方法,從而使得伺服器能夠 拒絕並放棄出現不良值的語句。本節介紹了MySQL的預設行為(寬大行為),新的嚴格的SQL模式,以及它們的區別。

  如果你未使用嚴格模式,下述情況是真實的。如果將"不正確"的值插入到列,如將NULL值插入非NULL列,或將過大的數值插入數值列,MySQL會將這些列設定為"最可能的值",而不是生成錯誤資訊。

  · 如果試圖將超範圍的值儲存到數值列,MySQL伺服器將儲存0(最小的可能值)取而代之,或最大的可能值。

  · 對於字串,MySQL或儲存空字串,或將字串儘可能多的部分儲存到列中。

  · 如果打算將不是以數值開頭的字串儲存到數值列,MySQL將儲存0。

   · MySQL允許將特定的不正確日期值儲存到DATE和DATETIME列(如"2000-02-31"或"2000-02-00")。其觀點在於, 驗證日期不是SQL伺服器的任務。如果MySQL能儲存日期值並準確檢索相同的值,MySQL就能按給定的值儲存它。如果日期完全不正確(超出伺服器能保 存的範圍)將在列中儲存特殊的日期值"0000-00-00"取而代之。

  · 如果試圖將NULL值儲存到不接受NULL值的列,對於單行 INSERT語句,將出現錯誤。對於多行INSERT語句或INSERT INTO … SELECT語句,MySQL伺服器會儲存針對列資料型別的隱含 預設值。一般情況下,對於數值型別,它是0,對於字串型別,它是空字串("),對於日期和時間型別是"zero"。

  · 如果INSERT語句未為列指定值,如果列定義包含明確的DEFAULT子句,MySQL將插入預設值。如果在定義中沒有這類DEFAULT子句,MySQL會插入列資料型別的隱含預設值。

   採用前述規則的原因在於,在語句開始執行前,無法檢查這些狀況。如果在更新了數行後遇到這類問題,我們不能僅靠回滾解決,這是因為儲存引擎可能不支援回 滾。中止語句並不是良好的選擇,在該情況下,更新完成了"一半",這或許是最差的情況。對於本例,較好的方法是"僅可能做到最好",然後就像什麼都未發生 那樣繼續。

  在MySQL 5.0.2和更高版本中,可以使用STRICT_TRANS_TABLES或STRICT_ALL_TABLES SQL模式,選擇更嚴格的處理方式。

  STRICT_TRANS_TABLES的工作方式:

  · 對於事務性儲存引擎,在語句中任何地方出現的不良資料值均會導致放棄語句並執行回滾。

   · 對於非事務性儲存引擎,如果錯誤出現在要插入或更新的第1行,將放棄語句。(在這種情況下,可以認為語句未改變表,就像事務表一樣)。首行後出現的 錯誤不會導致放棄語句。取而代之的是,將調整不良資料值,並給出告警,而不是錯誤。換句話講,使用STRICT_TRANS_TABLES後,錯誤值會導 致MySQL執行回滾操作,如果可以,所有更新到此為止。

  要想執行更嚴格的檢查,請啟用STRICT_ALL_TABLES。除了非事務性存 儲引擎,它與STRICT_TRANS_TABLES等同,即使當不良資料出現在首行後的其他行,所產生的錯誤也會導致放棄語句。這意味著,如果錯誤出現 在非事務性表多行插入或更新過程的中途,僅更新部分結果。前面的行將完成插入或更新,但錯誤出現點後面的行則不然。對於非事務性表,為了避免這種情況的發 生,可使用單行語句,或者在能接受轉換警告而不是錯誤的情況下使用STRICT_TRANS_TABLES。要想在第1場合防止問題的出現,不要使用 MySQL來檢查列的內容。最安全的方式(通常也較快)是,讓應用程式負責,僅將有效值傳遞給資料庫。

  有了嚴格的模式選項後,可使用INSERT IGNORE或UPDATE IGNORE而不是不帶IGNORE的INSERT或UPDATE,將錯誤當作告警對待。