教你如何用SQLite 實現if not exist 類似功能的操作
需要實現:
if not exists(select * from ErrorConfig where Type='RetryWaitSeconds') begin insert into ErrorConfig(Type,Value1) values('RetryWaitSeconds','3') end
只能用:
insert into ErrorConfig(Type,Value1) select 'RetryWaitSeconds','3' where not exists(select * from ErrorConfig where Type='RetryWaitSeconds')
因為 SQLite 中不支援SP
在用sqlite3熟悉SQL的時候遇到了一個百思不得其解的問題,也沒有在google上找到答案。雖然最後用“迂迴”的方式碰巧解決了這個問題,但暫時不清楚原理是什麼,目前精力有限,所以暫時記錄下來,有待繼續研究。
資料庫是這樣的:
CREATE TABLE book ( id integer primary key, title text, unique(title) ); CREATE TABLE checkout_item ( member_id integer, book_id integer, movie_id integer, unique(member_id, book_id, movie_id) on conflict replace, unique(book_id), unique(movie_id) ); CREATE TABLE member ( id integer primary key, name text, unique(name) ); CREATE TABLE movie ( id integer primary key, title text, unique(title) );
該資料庫包含了4個表:book, movie, member, checkout_item。其中,checkout_item用於儲存member對book和movie的借閱記錄,屬於關係表。
SQL語句(SQL1)如下:
SELECT * FROM member WHERE id NOT IN(SELECT member_id FROM checkout_item);
得到了想要的結果。
這看起來與上一個是類似的,於是我理所當然地執行了如下的SQL語句(SQL2):
SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item);
可是——執行結果沒有找到任何記錄! 我看不出SQL2與SQL1這兩條語句有什麼差別,難道是book表的問題?於是把NOT去掉,執行了如下查詢語句:
SELECT * FROM book WHERE id IN(SELECT book_id FROM checkout_item);
正確返回了被借出的book,其數量小於book表裡的總行數,也就是說確實是有book沒有借出的。
接著google(此處省略沒有營養的字),沒找到解決方案。可是,為什麼member可以,book就不可以呢?它們之前有什麼不同?仔細觀察,發現checkout_item裡的book_id和movie_id都加了一個unique,而member_id則沒有。也許是這個原因?不用id了,換title試試:
SELECT * FROM book WHERE title NOT IN( SELECT title FROM book WHERE id IN( SELECT book_id FROM checkout_item));
確實很迂迴,但至少work了。。。
事實是,我自己的解決方案只不過是碰巧work,這個問題產生跟unique沒有關係。邱俊濤的解釋是,“SELECT book_id FROM checkout_item”的結果中含有null值,導致NOT也返回null。當一個member只借了movie而沒有借book時,產生的checkout_item中book_id就是空的。
解決方案是,在選擇checkout_item裡的book_id時,把值為null的book_id去掉:
SELECT * FROM book WHERE id NOT IN(SELECT book_id FROM checkout_item WHERE book_id IS NOT NULL);
我在解決這個問題的時候方向是不對的,應該像除錯程式一樣,去檢查中間結果。比如,執行如下語句,結果會包含空行:
SELECT book_id FROM checkout_item
而執行下列語句,結果不會包含空行:
SELECT member_id FROM checkout_item
這才是SQL1與SQL2兩條語句執行過程中的差別。根據這個差別去google,更容易找到答案。當然了,沒有NULL概念也是我“百思不得其解”的原因。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2851807/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQLite中中實現 if not exist 類似功能SQLite
- PostgreSQL類似OracleMERGE功能的實現SQLOracle
- C# SQLiteHelper類似SqlHelper類實現存取Sqlite資料庫C#SQLite資料庫
- 教你如何用 MongoDB 實現評論榜功能MongoDB
- 實現類似IE的列印網頁功能 (轉)網頁
- 實現類似Pinterest 的圖片預載入功能REST
- 在Asp.Net中實現類似DWR的功能ASP.NET
- 用CSS實現類似導航翻轉功能例子CSS
- 用 hyperf websocket 實現,類似 qq 單機登入功能Web
- 教你如何用vbs實現微信自動傳送訊息功能
- 碼教授教你一些系統功能實現的操作
- mysql類似merge的操作MySql
- .Net中用js實現無重新整理類似ajax功能(例)JS
- lakeFS:實現類似於Git或事件溯源ES的物件儲存功能Git事件物件
- SQLite Helper類,基於.net c#的SQLite資料庫操作類SQLiteC#資料庫
- 簡單實現類似Spring的Aop原理實現Spring
- 教你如何用 Java 實現非同步呼叫Java非同步
- MySQL的字首索引及Oracle的類似實現MySql索引Oracle
- 完美實現類似QQ的自拍頭像、上傳頭像功能!(Demo 原始碼)原始碼
- Excel有類似“分列”的“分行”功能嗎?Excel
- jquery操作類似tab佈局jQuery
- 類似咻一咻,水波紋實現
- go如何實現類似java的動態代理GoJava
- 教你如何用smokeping實現釘釘告警
- javascript如何實現類的功能JavaScript
- 如何用SQL語句實現以下功能.SQL
- 用 golang 去實現類似 swoole 的 websocket 服務 ?GolangWeb
- Blazor如何實現類似於微信的Tab切換?Blazor
- JS實現類似於微博秀的GitHub掛件JSGithub
- 實現類似QQ的即時通訊程式(十一)
- MySQL 06 mysql 如何實現類似 oracle 的 merge intoMySqlOracle
- Flutter 實現類似TabPicker省市區選擇Flutter
- flutter實現類似優惠券樣式Flutter
- 在鴻蒙中實現類似瀑布流效果鴻蒙
- 教你如何用 Lua 操作檔案中的資料
- 類似這樣的連結是如何實現的呢?
- PHP - 實現類似於百度的實時搜尋PHP
- PHP常用操作類實現——資料庫操作類PHP資料庫