[IT] 事件總線 EventBus

EventBus EventBus 用於維護一個事件源與事件處理的映射字典 通過 Singleton,確保 EventBus 的唯一入口 利用反射完成事件源與件事處理的初始化綁定 提供統一的事件注冊(register)、取消注冊(unsubscribe)和觸發(trigger)。 Interfaces IEventData public interface IEventData { DateTime EventTime { get; set; } object EventSource {get; set; } } IEventHandler public interface IEventHandler { } IEventHandler`1 public interface IEventHandler<TEventData> : IEventHandler where TEventData : IEventData { void HandlerEvent(TEventData eventData); } base class EventData public class EventData : IEventData { public DateTime EventTIme { get; set; } object EventSource { get; set; } public EventData() { EventTime = DateTime.Now; } } Domain FishType public enum FishType { None, 鯽魚, 鯉魚, 黑魚, 青魚, 草魚, 鱸魚 } FishingEventData : EventData public class FishingEventData : EventData { public FishType FishType { get; set; } public FishingMan FishingMan { get; set; } } FishingEventHandler : IEventHandler public class FishingEventHandler : IEventHandler<FishingEventData> { public void HandleEvent(FishingEventData eventData) { var type = eventData.FishType; var fishMan = eventData.FishingMan; var Name = fishMan.Name; if (type == FishType.None) { fishMan.Message = string.Format("{0}: 沒有釣到魚, 累計釣了{1}條魚", Name, fishMan.FishCount); } else { fishMan.FishCount++; fishMan.Message = string.Format("{0}: 釣到一條[{2}], 累計釣了{1}條魚", Name, fishMan.FishCount, type); } } } FishingMan public class FishingMan { public string Name { get; set; } public int FishCount { get; set; } public FishingRod FishingRod { get; set; } public string Message { get; set; } public FishingMan(string name) { Name = name; FishCount = 0; } public void Fishing() { FishingRod.ThrowHook(this); } } FishingRod 用反射註冊事件 public class FishingRod { public string Message { get; private set; } public FishingRod() { } public void ThrowHook(FishingMan man) { if (new Random().Next() % 2 == 0) { var type = (FishType)(new Random().Next(0, 5) + 1); Message = ("魚兒上鉤了!"); if (FishingEvent != null) { var eventData = new FishingEventData { FishingMan = man, FishType = type }; EventBus.Default.Trigger<FishingEventData>(eventData); } } else { var type = FishType.None; Message = ("可惜了!"); if (FishingEvent != null) { var eventData = new FishingEventData { FishingMan = man, FishType = type }; EventBus.Default.Trigger<FishingEventData>(eventData); } } } } EventBus 實作 用一個靜態單例來統一管理事件 public class EventBus { public static EventBus Default => new EventBus(); private readonly ConcurrentDictionary<Type, List<Type>> _eventAndHandlerMapping; private EventBus() { _eventAndHandlerMapping = new ConcurrentDictionary<Type, List<Type>>(); MapEventToHandler(); } private void MapEventToHandler() { Assembly assembly = Assembly.GetEntryAssembly(); foreach (var type in assembly.GetTypes()) { if (typeof(IEventHandler).IsAssignableFrom(type)) { Type handlerInterface = type.GetInterface("IEventHandler`1"); if (handlerInterface == null) continue; Type eventDataType = handlerInterface.GetGenericArguments()[0]; if (_eventAndHandlerMapping.ContainsKey(eventDataType)) { List<Type> handlerTypes = _eventAndHandlerMapping[eventDataType]; handlerTypes.Add(type); _eventAndHandlerMapping[eventDataType] = handlerTypes; } else { var handlerTypes = new List<Type> { type }; _eventAndHandlerMapping[eventDataType] = handlerTypes; } } } } public void Register<TEventData>(Type eventHandler) { List<Type> handlerTypes = _eventAndHandlerMapping[typeof(TEventData)]; if (!handlerTypes.Contains(eventHandler)) { handlerTypes.Add(eventHandler); _eventAndHandlerMapping[typeof(TEventData)] = handlerTypes; } } public void Unsubscribe<TEventData>(Type eventHandler) { List<Type> handlerTypes = _eventAndHandlerMapping[typeof(TEventData)]; if (!handlerTypes.Contains(eventHandler)) { handlerTypes.Remove(eventHandler); _eventAndHandlerMapping[typeof(TEventData)] = handlerTypes; } } public void Trigger<TEventData>(TEventData eventData) where TEventData : IEventData { List<Type> handlers = _eventAndHandlerMapping[eventData.GetType()]; if (handlers != null && handlers.Count > 0) { foreach (var handler in handlers) { MethodInfo methodInfo = handler.GetMethod("HandleEvent"); if (methodInfo != null) { object obj = Activator.CreateInstance(handler); methodInfo.Invoke(obj, new object[] { eventData }); } } } } } demo MacOs Cocoa Project public partial class ViewController : NSViewController { public ViewController (IntPtr handle) : base (handle) { } public override void ViewDidLoad () { base.ViewDidLoad (); jeff = new FishingMan("Jeff"); rod = new FishingRod(); jeff.FishingRod = rod; EventBus eventBus = EventBus.Default; eventBus.Register<FishingEventData>(typeof(FishingEventHandler)); } FishingMan jeff; FishingRod rod; public override NSObject RepresentedObject { get { return base.RepresentedObject; } set { base.RepresentedObject = value; } } partial void Button_Click(NSButton sender) { jeff.Fishing(); TextLabel.StringValue = rod.Message; TextLabel2.StringValue = jeff.Message ?? ""; } }

September 25, 2023 · 3 分鐘 · Rain Hu

[IT] Clean Architecture - 重點整理

乾淨架構(Clean Architecture) 筆記 分層 乾淨架構中從外而內依序為 Framework Layer Interface Adapter Layer Application Layer Domain Layer Models 一般來說會有四個 Models View Model(給前端) App Model(App Layer 隔離 Domain Layer 所用,aka DTO) Domain Model Data Model(for DBMS) Usecase App Layer 中的 Usecase 做四件事: 查 改 存 推 單向依賴原則 依賴的方向必為單向且為 \(\boxed{\text{Interface Adapter}} \rightarrow \boxed{\text{Application Layer}} \rightarrow \boxed{\text{Domain Layer}}\) Repository Application Layer 為了遵守單向依賴,與 ORM 解耦會做一次依賴反轉,翠取 Repository 介面。 套用乾淨架構的效益衡量 Model Mapping 的成本 vs. 獨立出「領域模型」的價值 省下更換技術的成本(migration cost) 「領域層」的部分通常會結合 DDD

September 23, 2023 · 1 分鐘 · Rain Hu

[IT] LINQ: IQueryable Provider

可重複使用的 IQueryable 基類 IQueryable 簡介 在 C# 最新版本中的 IQueryable 已經不再是一個介面,而是分為兩個部分: IQueryable 與 IQueryProvider。在開始實作之前,我們必須先了解一下這兩個介面。 public interface IQuerable : IEnumerable { Type ElementType { get; } Expression Expression { get; } IQueryProvider Provider { get; } } public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable { } IQueryable 有三個唯讀屬性: ElementType 代表了元素的類型 (或等於 IQueryable<T> 中的 T) Expression 代表了查詢對應的表達式。這是 IQueryable 存在的核心要素。在 IQueryable 的內部,實際上是一個表示查詢的表達式,它將查詢表示為 LINQ 查詢運算子/方法調用的樹狀結構。如果進一步看,你會發現,IQueryable 或是 Queryable 都只是在提供一個自動構建表達式樹節點 (expression tree nodes) 的機制。當我們對 IQeuryable 使用 Where 方法時,它只是回傳一個新的 IQueryable,並且在進行調用的樹頂添加一個方法表達式樹節點。 Provider 作為真正的「提供者」,它負責原先所有 IQueryable 的執行方法。 IQueryProvider 簡介 public interface IQueryProvider { IQueryable CreateQuery(Expression expression); IQueryable<TElement> CreateQuery<TElement>(Expression expression); object Execute(Expression expression); TResult Execute<TResult>(Expression expression); } 當我們進一步觀察 IQueryProvider,會發現它事實上只有兩個操作:CreateQuery、Execute,只是各有一個泛型與非泛型的方法。一般我們會使用泛型的方法,因為它可以避免使用反射來建構實例,從而提高性能。 ...

September 21, 2023 · 19 分鐘 · Rain Hu

[IT] 關聯模式的五大鍵 Super key、Candidate Key、Primary Key、Alternate Key、Foreign Key

關聯模式的條件 關聯模式可以比實體關係模式(ERM)更精準的描述資料,他有幾個條件必須滿足: 定義域限制: 指資料庫的關聯中的每個屬性質,必須符合該屬性的定義,例如產品名稱必須是字串,薪水必須是整數數字等。 關聯鍵限制: 指資料庫的關聯中必須有關聯鍵的定義,也就是Super key、Candidate Key、Primary Key、Alternate Key、Foreign Key。這些定義我們稍後再來解釋。 實體完整限制: 如果關聯存在主鍵(Primary Key),則不能為空。因為如果為空值,無法得知其相關的屬性值到底是描述哪一個實體。 參考完整限制: 如果關聯存在外鍵(Foreign Key)為非空值,必須有可以參考的主鍵(Primary Key)。因為如果外鍵存在,而無法關連到其他表格的主鍵,這個關聯存在就沒有意義。 語意完整限制: 這個限制不是必須的,但是可以更完備的描述實體世界的資料。例如交易金額高於100元才可以使用信用卡付款等。 關聯模式的五大鍵 Super key 超鍵: 符合唯一性的關聯鍵。 Candidate Key 候選鍵: 符合唯一性以及最小性的關聯鍵。 Primary Key 主鍵: 從候選鍵中,挑選出其中一個關聯鍵,也就是最具識別意義的關聯鍵。 Alternate Key 次要鍵: 沒有被選為主鍵的其他候選鍵。 Foreign Key 外鍵/外部鍵: 關聯中被用來參考到其他表格主鍵的關聯鍵,就是外鍵。 例如學生資料表(student_id, student_no, student_name, student_depid) student_id student_no student_name student_depid A123454321 00001 Rain Hu MSE A123123123 00002 Mike Hu IM A221232134 00003 Eva Hsu ECE A223124125 00004 Dudu Liu ECE A124124512 00005 Gober Wei IT student_id表示學生身分證字號 student_no表示學生學號 student_name表示學生姓名 student_depid表示學生的科系代號 Super key 就可以是 {student_id}、{student_no}、 {student_id, student_no}、{student_id, student_name}、{student_id, student_depid} … 等等,都符合唯一性的條件。 Candidate Key 就可以是 {student_id}、{student_no},都符合唯一性及最小性的條件。 Primary Key 就可以從Candidate Key挑選一個,至於挑選哪一個,就看你的系統特性。如果你的學校是多學制的話,就可能不適合挑選學生身分證字號當主鍵,因為可能某個學生原本是國中部,畢業後再進入高中部,如果系統沒有考慮清楚,這個畢業後再變新生的個體,就可能出錯。 Alternate Key 就是沒被挑中當成Primary Key的其他Candidate Key,例如,如果挑選 {student_id}當成主鍵,Alternate Key 就是{student_no}。 如果存在科系資料表 (depid, dep_name),而且depid當成科系資料表的主鍵,學生資料表的 student_depid就是Foreign Key。 資料來源:https://www.mysql.tw/2015/04/super-keycandidate-keyprimary.html ...

May 11, 2023 · 1 分鐘 · Rain Hu

[IT] Design Patterns

設計模式 Design Pattern 什麼是設計模式? 設計模式是指在軟體設計中通常出現的問題的典型解決方案。它們就像是預先製作好的藍圖,您可以根據自己程式碼中出現的重複設計問題來進行自定義。 設計模式不是一個特定的程式碼,而是一個解決特定問題的一般概念。您可以按照模式的細節來實現適合自己程式的解決方案。值得注意的是,設計模式常與演算法混淆,因為這兩個概念都描述了解決某些已知問題的典型解決方案。模式是一個更高層次的解決方案描述。 模式通常包括模式意圖、動機、結構、程式碼示例等幾個方面,以便人們在多種情況下可以複製它們。模式目錄還列出了其他有用的細節,例如模式的適用性、實施步驟和與其他模式的關係。 誰發明了設計模式? 設計模式不是晦澀難懂、高深複雜的概念,相反地,它們是物件導向設計中解決常見問題的典型解決方案。當一個解決方案在不同的項目中反復出現,某人最終會給它命名並詳細描述解決方案。這基本上是模式的發現方式。 模式的概念最初是由Christopher Alexander在《模式語言:城鎮、建築、建設》中描述的。這本書描述了一種用於設計城市環境的“語言”。這種語言的單位是模式。它們可以描述窗戶應該有多高,建築物應該有多少層,社區中綠地的大小應該是多少等等。+ 這個想法被四位作者Erch Gamma、John Vlissides、Ralph Johnson和Richard Helm接受。在1994年,他們出版了《Design Patterns: Elements of + Reusable Object-Oriented Software》一書,將設計模式的概念應用於編程中。該書介紹了23個解決物件導向設計中各種問題的模式,並迅速成為暢銷書。由於書名過長,人們開始稱之為“四人幫的書(Gang of Four, GoF)”。 此後,發現了許多其他物件導向模式。模式方法在其他編程領域也變得非常流行,因此現在還存在許多與物件導向設計無關的模式。 為什麼要學習設計模式? 設計模式是解決軟體設計中常見問題的一套經過驗證的解決方案工具包。即使從未遇到這些問題,了解模式仍然有用,因為它可以使用物件導向設計原則解決各種問題。 設計模式定義了一個共通的語言,使團隊之間可以使用它更有效地進行溝通。 設計模式的分類 設計模式可以根據其複雜性、細節程度和應用於整個系統的規模進行分類。它們有點像道路建設的類比:通過安裝交通信號燈或建造整個多層立交橋和地下通道來使十字路口更安全。 最基本和低層次的模式通常被稱為 “idioms”。它們通常僅適用於單一程式語言。 最通用和高層次的模式是架構模式(architectural patterns)。開發人員可以在幾乎任何語言中實現這些模式。與其他模式不同,它們可用於設計整個應用程序的架構。 此外,所有模式都可以通過其意圖或目的進行分類。本文將涵蓋三個主要模式: 創建型模式(creational):提供了增加彈性和重複使用現有代碼的物件創建機制。 結構型模式(structural):解釋如何將物件和類組合成更大的結構,同時保持這些結構的靈活性和效率。 行為型模式(behavioral):負責處理物件之間的有效溝通和職責分配。 SOLID 原則 在進入本文之前,來認識一下 SOLID 原則:(詳細的內容可以參考YC的部落格) S = Single-responsibility principle (SRP) = 單一職責原則 O = Open–closed principle (OCP) = 開放封閉原則 L = Liskov substitution principle (LSP) = 里氏替換原則 補充:jyt0532 I = Interface segregation principle (ISP) = 介面隔離原則 D = Dependency inversion principle (DIP) = 依賴反向原則 正文 Factory 簡介 ...

May 1, 2023 · 1 分鐘 · Rain Hu
Oh! You closed up the window, so you cannot see raining

[IT] C# Depth Ch.2 C# 2

C# 2 一、泛型 使用泛型(generic type)可以在編寫在編譯時類型安全的通用程式碼,無須事先知道要使用的具體類型。 示例1: array類型: 大小需預先設定,若要添加需要重新分配 public static void Main(string[] args) { PrintNames(GenerateNames()); } public static void PrintNames(string[] names) { foreach (string name in names) { Console.WriteLine(name); } } public static string[] GenerateNames() { string[] names = new string[4]; names[0] = "Mike"; names[1] = "Rain"; names[2] = "Jessica"; names[3] = "Billy"; return names; } 示例2: ArrayList類型: ArrayList.Add是Object的方法,但如果塞入不適合的參數類型,可能會引發InvalidCastException public static void Main(string[] args) { PrintNames(GenerateNames()); } public static void PrintNames(ArrayList names) { foreach (object name in names) { Console.WriteLine(name); } } public static ArrayList GenerateNames() { ArrayList names = new ArrayList(); names.Add("Mike"); names.Add("Rain"); names.Add("Jessica"); names.Add("Billy"); return names; } 示例3: StringCollection專用類型: 解決前述兩個問題,但也限制了返回值。 ...

January 20, 2023 · 2 分鐘 · Rain Hu
Oh! You closed up the window, so you cannot see raining

[IT] C# Depth Ch.1 與時俱進的語言

與時俱進的語言 一、System Class 1. 泛型(genric) 可更清楚的描述序列中每個元素的類型。 C#1 示例 public class Bookshelf { public IEnumerable Books { get { ... } } } C#2 示例:泛型 public class Bookshelf { public IEnumerable<Book> Books { get { ... } } } 2. 可空值類型(nullable value type) 可有效的表示未定的變量值,以擺脫魔數(用-1當集合索引,用 MinValue 或 MaxValue 做為初始值)。 示例 string? a = null; Console.WriteLine(a ?? "null"); // null a = "abc"; Console.WriteLine(a ?? "null"); // abc 3. 匿名類型(anonymous type)、隱式局部變數(var) 兩者皆可解決靜態類型語言的缺陷:程式碼冗長。 示例1: 匿名類型(anonymous type) var book = new { Title = "Harry Potter", Author = "J.K. Rowling" } string title = book.Title; string author = book.Author; 若已經調用了建構式的話,就無需顯式的宣該告變數的類型了。 示例2: 隱式類型(implicit typing) ...

January 17, 2023 · 2 分鐘 · Rain Hu

[IT] Shell 筆記

Reference https://blog.csdn.net/w918589859/article/details/108752592 https://www.w3cschool.cn/linux/linux-Shell.html 一、Shell 簡介 什麼是 Shell? Shell 是一個用 C 語言編寫的程式,它是使用者使用 Linux 的橋樑。Shell 既是一種命令語言,又是一種程式設計語言。 Shell 是指一種應用程式,這個應用程式提供了一個界面,使用者通過這個界面訪問作業系統核心(kernel)的服務。 為什麼要學習和使用 Shell? Shell 屬於內建的腳本,程序開發的效率非常高,依賴於功能強大的命令可以迅速的完成開發任務(批次處理)。 Shell 腳本(Shell script) 是一種為 Shell 編寫的腳本程式。業界所說的 Shell 通常都是指 Shell 腳本。 二、 Shell 入門 1. Shell 環境 Shell 編程需要能編寫程式碼的文本編輯器和一個能解釋執行的腳本解釋器。 在 linux 中有很多類型的 Shell,不同的 Shell 具備不同的功能,Shell 還決定了腳本中函數的語法。 Bash 是 Linux 中默認的 Shell。一般情況下,人們不區分 Bourne Shell 和 Bourne Again Shell,所以 #!/bin/sh 也可以被替換成 #!/bin/bash Linux 的 Shell 種類眾多,不同的 Shell 都有自己的特點以及用途,常見的有: Bourne Shell (/usr/bin/sh 或 /bin/sh) Bourne Again Shell (/bin/bash) C Shell (/usr/bin/csh) K Shell (/usr/bin/ksh) Shell for Root(sbin/sh) …… 2. Bash 常用快捷鏈 快捷鏈 功能 Ctrl+A 把游標移動到命令行開頭。 Ctrl+E 把游標移動到命令行結尾。 Ctrl+C 強制終止當前的命令。 Ctrl+L 清除螢幕,等於 clear 指令。 Ctrl+U 清除並剪下當前命令。 Ctrl+K 刪除並剪下游標以後的命令。 Ctrl+Y 貼上。 Ctrl+R 在歷史命令中搜索,按下 Ctrl+R 之後,就會出現搜索界面,只要輸入搜索內容,就會從歷史命令中搜索。 Ctrl+D 退出當前終端機。 Ctrl+Z 暫停,並放入後台。 Ctrl+S 暫停螢幕輸出。 Ctrl+Q 恢復螢幕輸出。 3. 輸入與輸出 I/O linux 的標準輸入與輸出 ...

January 12, 2023 · 3 分鐘 · Rain Hu
Oh! You closed up the window, so you cannot see raining

[IT] 動態鏈結庫(DDL)

動態鏈結庫(Dynamic Linked Library, DDL) 將程式中重複引用的程式庫獨立包裝出來以便共同引用 好處是比起靜態庫更節省空間 也可以單獨修改動態庫文件 示例 創建一個自定義程式庫 math.c // math.c int add(int a, int b) { return a + b; } 建建一個 math.h 只包含函式的宣告 // math.h int add(int a, int b); 將 math.c 編譯成一個動態庫 -shared 表明是一個 shared library .so 是 Linux 下的動態庫的副檔名,Windows 下為 .dll $ gcc -shared -fPIC math.c -o libmath.so 在主程式中包含 math.h 頭文件 // main.c #include <stdio.h> #include <math.h> int main() { printf("add(1, 2) returns %d\n", add(1, 2)); return 0; } 利用 -l 編譯主程式 省略 libmath.so 中的 lib 與 .so 為 -lmath gcc main.c -lmath -L. -o main 系統在路徑下找不到文件的解決方案 將動態庫複製到系統路徑下(需要 root 權限) $ sudo ^C cp libmath.so /usr/local/lib/ 使用環境變量,將當前目錄加到 LD_LIBRARY_PATH 環境變量中 $ export LD_LIBRARY_PATH="$(pwd)" // 將當前目錄叫到 LD_LIBRARY_PATH中 $ echo $LD_LIBRARY_PATH // 測試是否調用成功

September 18, 2022 · 1 分鐘 · Rain Hu

[IT] MySQL Functions

String Functions ASCII Return the ASCII value for the specific character CHAR_LENGTH or CHARACTER_LENGTH Return the length of string (in characters) CONCAT Adds two or more expressions together CONCAT_WS Adds two or more expressions together with a separator FIELD Returns the index position of a value in a list of values FIND_IN_SET Returns the position of a string within a list of strings FORMAT Return sFormats a number to a format like “#,###,###.##”, rounded to a specified number of decimal places INSERT Inserts a string within a string at the specified position and for a certain number of characters INSTR Returns the position of the first occurrence of a string in another string LCASE Converts a string to lower-case LEFT Extracts a number of characters from a string (starting from left) LENGTH Returns the length of a string (in bytes) LOCATE Returns the position of the first occurrence of a substring in a string LOWER Converts a string to lower-case LPAD Left-pads a string with another string, to a certain length LTRIM Removes leading spaces from a string MID Extracts a substring from a string (starting at any position) POSITION Returns the position of the first occurrence of a substring in a string REPEAT Repeats a string as many times as specified REPLACE Replaces all occurrences of a substring within a string, with a new substring REVERSE Reverses a string and returns the result RIGHT Extracts a number of characters from a string (starting from right) RPAD Right-pads a string with another string, to a certain length RTRIM Removes trailing spaces from a string SPACE Returns a string of the specified number of space characters STRCMP Compares two strings SUBSTR Extracts a substring from a string (starting at any position) SUBSTRING Extracts a substring from a string (starting at any position) SUBSTRING_INDEX Returns a substring of a string before a specified number of delimiter occurs TRIM Removes leading and trailing spaces from a string UCASE Converts a string to upper-case UPPER Converts a string to upper-case Numeric Functions ABS Returns the absolute value of a number ACOS Returns the arc cosine of a number ASIN Returns the arc sine of a number ATAN Returns the arc tangent of one or two numbers ATAN2 Returns the arc tangent of two numbers AVG Returns the average value of an expression CEIL Returns the smallest integer value that is >= to a number CEILING Returns the smallest integer value that is >= to a number COS Returns the cosine of a number COT Returns the cotangent of a number COUNT Returns the number of records returned by a select query DEGREES Converts a value in radians to degrees DIV Used for integer division EXP Returns e raised to the power of a specified number FLOOR Returns the largest integer value that is <= to a number GREATEST Returns the greatest value of the list of arguments LEAST Returns the smallest value of the list of arguments LN Returns the natural logarithm of a number LOG Returns the natural logarithm of a number, or the logarithm of a number to a specified base LOG10 Returns the natural logarithm of a number to base 10 LOG2 Returns the natural logarithm of a number to base 2 MAX Returns the maximum value in a set of values MIN Returns the minimum value in a set of values MOD Returns the remainder of a number divided by another number PI Returns the value of PI POW Returns the value of a number raised to the power of another number POWER Returns the value of a number raised to the power of another number RADIANS Converts a degree value into radians RAND Returns a random number ROUND Rounds a number to a specified number of decimal places SIGN Returns the sign of a number SIN Returns the sine of a number SQRT Returns the square root of a number SUM Calculates the sum of a set of values TAN Returns the tangent of a number TRUNCATE Truncates a number to the specified number of decimal places Date Functions ADDDATE Adds a time/date interval to a date and then returns the date ADDTIME Adds a time interval to a time/datetime and then returns the time/datetime CURDATE Returns the current date CURRENT_DATE Returns the current date CURRENT_TIME Returns the current time CURRENT_TIMESTAMP Returns the current date and time CURTIME Returns the current time DATE Extracts the date part from a datetime expression DATEDIFF Returns the number of days between two date values DATE_ADD Adds a time/date interval to a date and then returns the date DATE_FORMAT Formats a date DATE_SUB Subtracts a time/date interval from a date and then returns the date DAY Returns the day of the month for a given date DAYNAME Returns the weekday name for a given date DAYOFMONTH Returns the day of the month for a given date DAYOFWEEK Returns the weekday index for a given date DAYOFYEAR Returns the day of the year for a given date EXTRACT Extracts a part from a given date FROM_DAYS Returns a date from a numeric datevalue HOUR Returns the hour part for a given date LAST_DAY Extracts the last day of the month for a given date LOCALTIME Returns the current date and time LOCALTIMESTAMP Returns the current date and time MAKEDATE Creates and returns a date based on a year and a number of days value MAKETIME Creates and returns a time based on an hour, minute, and second value MICROSECOND Returns the microsecond part of a time/datetime MINUTE Returns the minute part of a time/datetime MONTH Returns the month part for a given date MONTHNAME Returns the name of the month for a given date NOW Returns the current date and time PERIOD_ADD Adds a specified number of months to a period PERIOD_DIFF Returns the difference between two periods QUARTER Returns the quarter of the year for a given date value SECOND Returns the seconds part of a time/datetime SEC_TO_TIME Returns a time value based on the specified seconds STR_TO_DATE Returns a date based on a string and a format SUBDATE Subtracts a time/date interval from a date and then returns the date SUBTIME Subtracts a time interval from a datetime and then returns the time/datetime SYSDATE Returns the current date and time TIME Extracts the time part from a given time/datetime TIME_FORMAT Formats a time by a specified format TIME_TO_SEC Converts a time value into seconds TIMEDIFF Returns the difference between two time/datetime expressions TIMESTAMP Returns a datetime value based on a date or datetime value TO_DAYS Returns the number of days between a date and date “0000-00-00” WEEK Returns the week number for a given date WEEKDAY Returns the weekday number for a given date WEEKOFYEAR Returns the week number for a given date YEAR Returns the year part for a given date YEARWEEK Returns the year and week number for a given date Advanced Functions BIN Returns a binary representation of a number BINARY Converts a value to a binary string CASE Goes through conditions and return a value when the first condition is met CAST Converts a value (of any type) into a specified datatype COALESCE Returns the first non-null value in a list CONNECTION_ID Returns the unique connection ID for the current connection CONV Converts a number from one numeric base system to another CONVERT Converts a value into the specified datatype or character set CURRENT_USER Returns the user name and host name for the MySQL account that the server used to authenticate the current client DATABASE Returns the name of the current database IF Returns a value if a condition is TRUE, or another value if a condition is FALSE IFNULL Return a specified value if the expression is NULL, otherwise return the expression ISNULL Returns 1 or 0 depending on whether an expression is NULL LAST_INSERT_ID Returns the AUTO_INCREMENT id of the last row that has been inserted or updated in a table NULLIF Compares two expressions and returns NULL if they are equal. Otherwise, the first expression is returned SESSION_USER Returns the current MySQL user name and host name SYSTEM_USER Returns the current MySQL user name and host name USER Returns the current MySQL user name and host name VERSION Returns the current version of the MySQL database

September 1, 2022 · 7 分鐘 · Rain Hu