SQL - 時の雫
從時間欄位出發 → 做運算或分段 → 推導出狀態或統計結果
💼 三種常見的時間分析模式
類型
說明
範例
關鍵函式
① 時間差模式 (Time Gap)
用「時間差」判斷狀態或剩餘時間
HR 系統判斷誰快退休
DATEDIFF, DATEADD, CASE WHEN
② 時間分群模式 (Time Bucketing)
把連續的時間切成段落來統計
每月、每日、每週銷售分析
MONTH, DATEPART, DATEADD
③ 時間對齊模式 (Time Rounding)
把時間「取整」對齊成標準區間
每分鐘、每小時登入量
DATEADD(DATEDIFF(...))
💼 查詢的共通術式
技術重點
說明
DATEADD / DATEDIFF
處理時間偏移與差距(加減天、月、年)
DATEPART / MONTH / YEAR
擷取時間單位(分群依據)
CASE WHEN
將數值轉成語意化狀態
CTE (WITH)
建立暫存結果,讓查詢更乾淨易讀
分群 (GROUP BY)
對時間區間進行統計彙 ...
SQL Injection
💼 FromSqlInterpolated1234var user = "johndoe";var blogs = context.Blogs .FromSqlInterpolated($"EXECUTE dbo.GetMostPopularBlogsForUser {user}") .ToList();
FromSqlInterpolated 接受 FormattableString(即 $”…”)做為參數。EF Core 會把內插的值({user})自動轉成 DbParameter(例如 @p0),並把 SQL template 與參數分開傳給底層 provider(SqlClient)。用在執行 Stored Procedure 或 raw SQL 且要保留可讀性的情境很好用。如果有多個參數,寫法同樣直觀:$”EXEC proc {p1}, {p2}”。
FromSqlInterpolated 並不是把整個字串插入後再送出;EF 會解析 FormattableString.Format 與 Form ...
Asynchronous Programming - 第十四章 :async lambda
LINQ ForEach() 與 async / await
問題的起點 — async lambda 與 Fire-and-Forget 陷阱問題的起點 — async lambda 與 Fire-and-Forget 陷阱解法 1:簡單但不平行解法 2:真正的非同步 + 平行執行LINQ 的 Select 不會「馬上執行」Codesummary新的一年,動力滿格,誓言要變成更好的自己,我們開始報名課程、立下目標、說要健身、要學語言、要創業,那一刻就像丟出一個 Task 嚷嚷著我會做到的承諾。但接下來,沒有積極安排「等待與驗收」,例如固定回顧、截止日、交付物、找人督促,生活的 ForEach 將忙碌的人生繼續往下跑,我們會很快進入下一堆事情。最後你回頭看 results 可能是空的、有的只有一半(做到一半被別的事用掉了)、有時看起來做了很多,但沒有一個真正可用的成果,問題不在是否努力,是因為沒設計「誰來等你完成」!!!
12345urls.ForEach(async url =>{ var response = await client.GetAsync(ur ...
Asynchronous Programming - 第十三章:Task.WhenAll
跑腿什麼時候觸發了任務執行?下載檔案預覽ValidatorsTask.WhenAll 最高?WaitAll 與 WhenAll展現阻塞的差異你叫三個小弟幫你跑腿
Gina 去買雞蛋Bill 去買牛奶Lily 去買麵包
你不會等 Gina 回來才讓 Bill 去,你會同時叫他們出門,然後你說:「等你們全部都回來,我們再一起做早餐!」這就是 Task.WhenAll ,等全部人回來,再開始做接下來的事
它的本質是,把很多 Task 包裝成「一個新的 Task」,這個新 Task 會在所有子 Task 都完成後才完成 (to execute multiple asynchronous tasks concurrently,and wait for all of them to complete)
12345678910111213141516171819async Task Main(){ var tasks = new List<Task>(); foreach (var i in Enumerable.Range(1, 3)) { tasks.Add ...
EF Core - TransactionScope vs BEGIN TRAN/COMMIT
TransactionScope與COMMIT TRAN
transactionScope or BEGIN TRANTransactionScopeBEGIN TRAN / COMMIT TRAN兩者怎麼互動強迫建立不同的連線,確保觸發 MSDTC操作summary「如果用 TransactionScope 包了一段程式,裡面又在 SQL 裡手動開 BEGIN TRAN,那最後誰決定要不要真的 commit?」
只要你在 using 範圍內操作資料庫,EF 或 ADO.NET 會自動參與這個「環境交易 (Ambient Transaction)」。如果沒呼叫 scope.Complete(),在離開 using 時就會自動 rollback
123456789using (var scope = new TransactionScope()){ // 這裡做的所有 DB 操作(只要使用相同的連線)都會自動參與這個交易 DoSql1(); DoSql2(); // 決定是否 commit scope.Complete();}
這 ...
EF Core Attach() 與 Entry().State 進行更新
使用 EF Core Attach() 與 Entry().State 進行更新
小船什麼是 Entry()Entity 的五種狀態 (EntityState)Entry(record).State = EntityState.Modified 是什麼意思如果只想更新部分欄位Attach(record) 是什麼Primary Key 的狀況單純 Attach() 未指定 Id 值先查一筆,再 Attach()Attach() 指定 Id 值的 EntityAttach() 後修改某屬性Entry().State = EntityState.ModifiedSetValues() 只更新有修改的欄位SetValues() 的靈活應用summary在資料的海洋裡,每一筆 Entity 都像一艘小船。有的剛啟航(Added),有的正返港(Modified),有的靜靜停泊(Unchanged),而有的早已脫離航道(Detached)。
EF Core 就像港口的管理員,它用 Entry() 觀察著每艘船的狀態,用 Attach() 告訴它:「這艘船其實還在港裡,只是暫時沒動而已。」在 EF ...
Upsert
EF Core 新增或更新資料 (UPSERT) 的簡便寫法
Upsert傳統寫法的痛點EntrySetValues 在做什麼summary這是一個非常典型的需求:
傳入一筆資料,用 Primary Key(或唯一欄位)去比對資料庫。
若不存在 → 新增
若存在 → 更新欄位
也就是所謂的 Upsert(Update + Insert)
會員/客戶資料整併會員/客戶資料整併(CRM / User Profile)時,第三方登入回傳一組 ExternalId(Google/Facebook/LINE),系統收到最新暱稱、頭像、Email
沒有這個 ExternalId → 新增會員
已存在 → 更新最新資料(頭像、名稱、聯絡資訊)
1234existing.PropA = record.PropA;existing.PropB = record.PropB;existing.PropC = record.PropC;// ...
問題是當 Entity 有三十個欄位時,這樣的程式碼不僅冗長、容易漏改,也很難維護 ...
執行順序
Help Desk 說:「使用者回報登入錯誤,你幫我修一下。」RD 回:「我先看 log,嗯…沒看到錯誤」Help Desk:「我不是叫你看 log,我是要你先試著登錄看看啊!」RD:「那我得先知道帳號」Help Desk:「我剛不是說了嗎?就是那個登入錯誤的使用者啊!」
SQL 的執行順序,理性、結構化,你說「先 SELECT 再篩資料」,它說「不行,我得先把資料來源 JOIN 起來再說」
了解 SQL 的邏輯執行順序, 當你懂它的思考邏輯,你就不會再覺得它「不聽話」, 反而能跟它合作無間,讓查詢更快、更準、更漂亮
💼 邏輯執行順序SQL 查詢的邏輯執行順序,並不是你「寫」的順序,而是資料庫「想」的順序
步驟
關鍵字
意義
1
FROM / JOIN
先決定資料來源(要用哪些表)
2
ON
決定 JOIN 的配對條件
3
WHERE
過濾出你想要的資料
4
GROUP BY
把資料分組(分類)
5
HAVING
過濾掉不符合條件的群組
6
SELECT
挑出你想顯示的欄位
7
UNION 等集合運算
合併多個查詢結果
8 ...
Field
在 SQL 資料表設計時,「欄位型別的選擇」會直接影響到:
儲存空間(Database Size)
查詢效能(Index / Join / Sort)
可擴充性(是否足夠表示未來的資料量)
💼 char / varchar / nchar / nvarchar「var」表示變長,「n」表示支援 Unicode
🔹 定長:char想像你開一間餐廳,每張桌子都是固定 10 個座位 (char(10)),不管今天坐 2 個人還是 10 個人,桌子都占同樣的空間也就是說,你設定 char(10),即使只放 ‘Hi’,它還是佔 10 Bytes,系統會幫你在後面補空白(space),讓長度固定
char 因為長度固定,SQL Server 可以「快速計算位置」,所以在大量查詢時效能較好。所以 char 比較「浪費空間但速度快」;varchar 比較「省空間但速度略慢一點」
🔹 Unicode vs. 非Unicode(n 開頭的型別)Unicode 是一種「萬國通用的文字編碼」,用來同時支援 中、英、日、韓、泰文 等不同語 ...
Index - 發揮作用...了嗎
5個概念拯救龜速的SQL查詢(Query)
索引沒有覆蓋(Covering Index)索引沒有覆蓋查詢(Covering Index)複合索引的順序不對(Leftmost Prefix 原則)索引欄位的「資料分佈」不好(Cardinality)Equality 與 Range 的順序Optimizersummary索引是「查詢條件、資料分佈、索引結構三件事剛好對齊時,Optimizer 才會願意用它」,假設我們今天建立了一個 Index,我們以為它可以幫忙「快速定位資料」,Optimizer 看查詢條件會嘗試判斷能不能用這個 Index 做 Seek、用了之後要不要回主表(Key Lookup)、成本是不是比 Scan 還低,Optimizer 依據 Statistics 估算回傳列數,不是實際跑,而是「猜」,如果猜錯,整個執行計畫就歪掉,只要任何一環不理想、Index 欄位不夠、欄位順序不對、資料分佈太平均、統計過期,則 Optimizer 就會放棄你以為「應該要用」的索引
因此會發生已經建好索引,而且查詢條件也寫得很明確,但實際發生的是出現 Key Lookup、Index ...











