[精讚] [會員登入]

[PERL] 一個SQL上的錯誤

一個SQL上的觀念錯誤,浪費了我半小時查錯和半小時寫這篇筆記。

分享完整連結 //n.sfs.tw/m10577

分享連結 [PERL] 一個SQL上的錯誤@精讚
(文章歡迎轉載,請尊重版權註明連結來源)
2019-03-06 03:07:12 By 張○○

今天有一個SQL上的錯誤,這是一個語意上的錯誤,也是我觀念上的錯誤。

事後才想到以前也遇過這樣的錯誤,我怎麼又會犯這種錯誤,叮嚀自己不要再犯,趕快記下來。

是這樣的,我希望能在資料庫中看看該條件的記錄存不存在,有存在的話出現幾次,所以我下了這樣的SQL:

SELECT count(sn) cnt, name from `table` where `name`='王小明';

然後我再由perl DBI的方式來判斷有沒有找到記錄,我這樣寫:

if(my $ref = $sth->fetchrow_hashref()){
  $n =$ref2->{'cnt'}+1;
  $name=$ref2->{'name'};
}else{
  $n =1;
  $name = "李大華";
}

我的想法是,如果name="王小明"存在的時候,取出姓名$name和數量$n。

當王小明不存在時,預設 $name="李大華",數量為1

然後插入另一個表中。

insert into table2(`name`,`cnt`) values("$name", "$n");

這個語法完全沒有問題,但是當王小明不存在時,這語法就出錯了,因為我`name` 不給存NULL,所以錯誤是這樣的:

DBD::mysql::st execute failed: Column 'name' cannot be null at ...

 

這裡我百思不得其解?我的邏輯沒問題啊~~

奇怪,如果王小明不存在,我就設定為李大華,為什麼跳這個錯誤?

花了半個小時亂改程式以後,我把最上面那個語法貼到資料庫去查,發現竟然有結果,對啊,我怎麼沒想到?!

cnt | name
----+-----
0   | NULL

所以那個 if 永遠為真,這時寫入 name會為NULL。

就出錯了。

上面只是舉例,本來我是要填空值,他寫入NULL我把資料表給填就能解決,但是不甘願為什麼這個邏輯不對,最後才發現是這個錯誤。

結論

使用 count之類的內建函數時,永遠會有結果,請小心。

 

END
你可能有興趣

[Rocky9] 安裝node.js 18, node.js 20

原本的nodejs16在使用 quasar dev時出現錯誤,得升級成18版以上

[SSL] Could not read certificate from server.cer 的錯誤排除

在轉換ssl憑證時,出現無法讀取的錯誤,可是怎麼看憑證都很正常,該怎麼解決?

[Linux] 如何能知道我是什麼時候安裝系統的?

linux想知道什麼時候裝系統的? 不必憑記憶。

地圖填色的網站

我們想為國家填色不需要小畫家,這個網站能幫助你

[Linux] 列出所有目錄及所占空間的方法

想知道目錄下的所有目錄所占的空間大小?

[Linux] grep 排除特定字串

使用 -v 參數可以讓grep排除特定字串的方法