Skip to content

片段自訂、合併與存檔 ​

本頁包含內建值與使用者 override 的合併、版本相容與存檔,以及手改檔案帶進來的違規。 樣板語法與 Tab 導航見片段導航。

內建值與使用者 override ​

內建定義只有一份: src/SqlAssist.Core/Snippets/DefaultSnippets.json,以 Embedded Resource 隨 VSIX 發布。 不要把 49 筆內容寫進 C#,也不要放進 VSIX 安裝步驟複製到使用者目錄。 其他語言的標題、說明與欄位提示疊自 DefaultSnippets.<語言>.json(見在地化)。

使用者 override 一律蓋過內建值,不論語言:存下來的就是使用者當時看到的文字。反過來,存檔時與任何一個語言的 內建值相同都不算自訂(SqlSnippetDefaults.IsUnmodifiedBuiltIn):清單在繁中載入、換成英文後才存檔時,沒改過的 49 筆仍是繁中文字,只和目前語言比會全部寫進使用者檔,之後就跟不上新版的內建值。

使用者檔位於 %APPDATA%\SqlAssist\snippets.json,v2 只存:

  • 修改過的內建項目;
  • { "id": "builtin...", "disabled": true } 的停用紀錄;
  • 使用者新增的完整項目。

檔案不存在代表「完全使用內建值」,不會在第一次啟動時建檔。這讓新版 VSIX 可以直接 更新未自訂的內建片段。管理介面會標示「已自訂」與「已停用」,並提供「還原此預設」; 全部還原後寫出的 override 清單是空的。

json
{
  "version": 2,
  "snippets": [
    {
      "id": "builtin.ctb",
      "category": "ddl",
      "shortcut": "ctb",
      "title": "CREATE TABLE",
      "description": "建立資料表",
      "expansionMode": "tabStops",
      "positions": ["StatementStart", "BlockStart"],
      "code": "CREATE TABLE $schema$.$table$\n(\n    $column$ $dataType$ NOT NULL\n)$end$;",
      "placeholders": [
        { "id": "schema", "default": "dbo", "tooltip": "結構描述" },
        { "id": "table", "default": "TableName", "tooltip": "資料表名稱" },
        { "id": "column", "default": "ColumnName", "tooltip": "欄位名稱" },
        { "id": "dataType", "default": "INT", "tooltip": "資料型別" }
      ]
    },
    { "id": "builtin.dt", "disabled": true }
  ]
}

category 是固定集合:select、dml、ddl、controlFlow、clause、other; 不認得的值落到 other。positions 重用 SqlKeywordPosition;缺席、空陣列或名稱 全都不認得都是 Any(哪裡都能用)。明寫 "None" 的意思與關鍵字相同:只在分析器 判不出位置時出現。

positions 給得太緊的症狀是全靜默的:使用者只覺得「這個片段有時候有、 有時候沒有」。語句級片段一律要同時給 StatementStart 與 BlockStart——分析器在 BEGIN 之後只回報 BlockStart,只給前者的話整批片段在 BEGIN…END 區塊裡會消失。 守門的是 SqlSnippetDefaultsTests.內建片段在它自然的位置找得到;新增片段時 要在那份表格加一行。

minimumSqlServerVersion 不存在:產品下限已固定,為它查詢每條連線的版本只會把資料庫 I/O 帶進按鍵路徑。

版本、相容與存檔 ​

  • 沒有 v1 遷移路徑。 v1 是完整清單、且第一次啟動就建檔,但它只在 0.14.22 這一個 版本外流一天;為它留著凍結快照與整套等價比較不划算。version 缺席或小於 2 一律照 v2 讀:手改檔案經常不寫版本,留一個讀不動的版本號只會讓整份進唯讀,使用者卻沒有可以照做 的修法。代價是真的還留著 v1 檔的人,那三筆沒有 id 的項目會變成自訂片段並遮住同捷徑 的內建定義——刪掉 snippets.json 就回到全內建。
  • version > 2 時可以讀已知欄位,但整份進入唯讀模式,避免舊版把新欄位覆蓋掉。
  • v2 保留頂層 snippets 鍵並只新增欄位;降回舊版時,舊讀取器至少仍看得到完整 override 與自訂項目。
  • 存檔先寫同目錄暫存檔,再用 File.Replace 原子置換;目標不存在時才用 File.Move。
  • 允許 JSON 註解與尾隨逗號。整份語法壞掉時保留原檔、切成唯讀、顯示錯誤,並繼續提供內建片段。

手改檔案帶進來的單筆違規 ​

只看一份樣板就能判斷的兩條規則(捷徑的格式與 T-SQL 關鍵字撞名、包夾錨點 $surround$ 只能出現一次)在 SqlSnippetValidation:管理介面存檔前擋下, SqlSnippetMerger.Merge 載入時重跑同一份。手改檔案繞得過前者,所以兩邊必須是 同一個進入點——分岔的症狀是清單上沒有標記的那一筆,按下儲存時突然被退回。

載入端只回報不修資料:那一筆照樣留在管理清單與一般建議裡(無效錨點不能用於 包夾),SqlSnippetStore 記進診斷, 管理介面在標題標成「不符規則」(與「已停用」「已遮住」同一排)、開啟時報出筆數、 選起來看原因。整份切唯讀是留給「JSON 壞掉」的處置,單筆違規沒有那麼重; 而安靜地丟掉那一筆更糟——使用者會發現片段消失卻沒有任何說明。

撞名不算違規:那是計算結果,由「已遮住」表示,改掉撞名的那一筆就自己解除。

不使用檔案監看器:清單只在第一次使用時載入並維持穩定參考,管理介面成功存檔才換快照。 因此按鍵路徑沒有磁碟 I/O,也不會因每次 Current 產生新物件而重建整批建議。直接用文字 編輯器修改 JSON 後,需要重新啟動 SSMS 才會載入。

這是 SqlAssist 自己的格式,與 SSMS「程式碼片段管理員」的 .snippet 檔不互相註冊; 只有提交時把選到的項目轉成記憶體中的原生 XML。

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