Skip to content

函式的參數提示 ​

本頁包含純量函式自己的簽章提示,以及任何函式的提示被收掉之後怎麼請回來;括號怎麼補見 函式呼叫。

游標停在使用者自訂純量函式的括號裡時,浮出一行簽章,目前輪到的引數標成粗體:

text
SELECT dbo.dtoc(|)
        dbo.dtoc(@ddate smalldatetime) RETURNS varchar(10)

開關是「輸入函式引數時保持參數提示」,預設開著,見設定,兩件事共用它。

為什麼只做純量函式 ​

2026-09 實機量測(SSMS 22.9):SSMS 自己的「陳述式完成 → 參數資訊」對內建函式有, 對 FROM 後面的資料表值函式也有,只有純量函式一律沒有——連 Ctrl+Shift+Space 明示叫用都沒反應。所以這一份只補那一格:其餘位置再浮一份是兩個視窗搶同一個位置, 而 SSMS 那一份知道的還比較多(內建函式的傳回型別會即時繫結)。

判斷依據是 SqlObjectKind.ScalarFunction,不是「位置在 SELECT 還是 FROM」—— 資料表值函式放在哪裡都由 SSMS 負責,純量函式放在哪裡都由這裡負責。

用平台的簽章提示,不自己開視窗 ​

擺放、跟著捲動、Esc 收掉、與建議清單併存都是平台的事 (ISignatureHelpBroker,實作在 Ssms22/Signatures)。自己畫一份等於把那些重寫一次, 還會在別人的視窗旁邊多出一套外觀——那正是 UI 準則擋著的事。

SSMS 那一份雖然是舊版語言服務的 MethodTip,畫面上是編輯器轉接層 (ShimSignatureHelpController)開在同一個 broker 上的 session,外觀因此與這一份相同。 所以「自己這一份開著沒有」要看 session 裡的簽章型別,不能只問 IsSignatureHelpActive。

平台唯一不懂的是「現在是第幾個引數」:它只知道 session 開在哪裡,不懂 T-SQL 的逗號 與巢狀括號。那一段自己算,在 Core/Completion/SqlCallSignature。游標走進引數裡的 另一個呼叫(dbo.dtoc(GETDATE(|)))時這一份收掉,讓內層那一份浮出來;分組括號與 子查詢不算呼叫,照樣留著。

內容從哪裡來 ​

AugmentSignatureHelpSession 是同步的,而參數要問中繼資料。所以順序反過來: 先在背景把內容備齊,再叫平台開 session,平台回頭來取時只是把備好的那一份拿走。 在那個方法裡等查詢的話,那一次等待發生在 UI 執行緒上。

讀不到中繼資料就這一輪不顯示,下一個逗號就有了——與建議清單同一條。 沒有限定字的呼叫(COUNT(、ISNULL()直接略過,不查中繼資料:純量函式一定寫結構描述, 而物件定位找不到候選時會補載整條敘述的資料來源明細,打一個左括號就可能真的查資料庫。 這條規則只在 SqlSignatureHelp.Covers,續接器也問它。

通知只在這一份真的浮出來時 Post 一則「已顯示函式參數提示」;判斷位置、續接器請回 SSMS 那一份都不發,理由見通知提示。 沒有輸入參數的函式(dbo.fn_Today())也不顯示:這一份的用途是指出「現在輪到第幾個 引數」,一個引數都沒有時它沒有話可說,而它擋住的那一行程式碼是真的。

選擇性參數標成「可寫 DEFAULT」而不是「選擇性」:函式只收位置引數,省略的寫法是 DEFAULT 這個關鍵字,位置照留。哪些有預設值由 SqlModuleParameterDefaults 從定義 讀出來,與 EXEC 骨架同一份。

什麼時候浮出來、什麼時候收掉 ​

時機做什麼
從建議清單提交一個純量函式括號補上、游標落進去,同時請出提示
自己打左括號一律重問——dbo.f(dbo.g( 裡面那個是另一個函式
自己打逗號提示還沒開著才問;開著的那一份自己會把粗體移到下一個
游標離開括號、括號被刪掉自己收掉

粗體怎麼移:左括號記成 ITrackingPoint,每次游標移動或編輯只掃左括號到游標那一段 數同一層的逗號。整份指令碼重新分析一次的話,幾千行的檔案打字就會頓——這也是 SqlCallSignature 分成兩支的理由,Resolve 要從游標往回找左括號,TrackArgument 的起點已經知道了。

引數比參數多時(多打了一個逗號)停在最後一個參數上,不收掉提示:那正是使用者最需要 看到「這個函式只收兩個」的一刻。

提示被收掉之後請回來 ​

SSMS 的參數資訊只在按鍵打出 ( 與 , 時浮出來;刪字、滑鼠點擊(連在同一個字上點 第二下都算)、點出去再點回來、復原,它就收掉而且不回來。會收掉它的操作列不完,所以規則 以「游標在呼叫的括號裡、畫面上沒有提示」為準,不列舉操作。 Ssms22/Signatures/SqlParameterHintKeeper 聽游標與緩衝區事件,停手 200 ms 才判斷, 規則在 Core/Completion/SqlParameterHintRevival:

停手時做什麼
同一個呼叫、畫面上沒有提示請;開著時不請,再請會收掉重畫、粗體閃一下
走進另一個呼叫請,開著的那一份講的是上一個函式;打字走進來的不請,打 (、提交函式那一條自己請過
請過卻沒浮出來停手,刪字才再試:INSERT INTO t (、查不到的名稱請了也不會有東西
單一個 )當成游標移動:打完內層右括號回到外層,與方向鍵走回去相同
這個呼叫裡按過 Esc離開那組括號之前不請

「浮出來了沒有」不靠猜時間:每一份提示(包括 SSMS 那一份)成形時都會經過 SqlSignatureHelpSource,由它通知續接器。提交函式時兩份提示由續接器的 Summon 一起請,並記下這一輪已經請過。

請的方式不變:補送 Edit.ParameterInfo,Covers 成立時再請自己這一份。 編輯器沒有焦點時不送,因為命令會落在有焦點的那個視窗。 CONVERT(、LEFT( 這類名稱是關鍵字的內建函式也要認,所以這裡的 Resolve 帶 includeKeywordFunctions;查中繼資料的那一條不帶,那些名稱查不到物件。

實機確認過:INSERT INTO t ( 這類括號裡送出去沒有作用;Esc 到得了現代命令處理常式。 提示開著時游標移動或打字,粗體先消失再出現是 SSMS 自己重畫,診斷紀錄在那些時候沒有 「請回參數提示」。

以 Apache-2.0 授權條款發布 · 專為 SSMS 22 設計