首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

OSQL 執行腳本報錯「缺少結束註釋標記 */」:註釋中包含 GO 批次分隔符導致的解析 Bug 解析

     編輯:關於SqlServer

使用 osql.exe 執行 SQL 腳本檔時,遭遇錯誤 「Missing end comment mark */」,但同樣腳本在 SSMS 查詢視窗執行完全正常。經排查發現,osql 解析器將註釋區塊內的 GO 視為批次結束,導致註釋解析狀態機錯亂,屬於 osql 早期版本的已知缺陷。

問題重現

-- 測試腳本 TestScript.sql
/*
    這是多行註釋
    GO  <-- 這行 GO 導致 osql 解析錯誤
    繼續註釋內容
*/
SELECT 1;
GO

執行指令與錯誤輸出

osql.exe -S .\SQLDEV -U sa -P MyRoot -b -n -r 1 -i ".\TestScript.sql" -o "c:\output.txt"

輸出錯誤:
osql Missing end comment mark "*/"

根因分析

工具解析器行為結果
SSMS / sqlcmd完整 T-SQL 解析器,識別 /* ... */ 區塊內的 GO 為註釋內容,不作為批次分隔✅ 正常
osql (舊版)簡易行導向解析,遇到行首 GO 即視為批次結束,忽略註釋狀態❌ 錯誤:以為註釋在 GO 前結束,後續找不到 */

解決方案

方案 1:移除註釋內的 GO (最快修正)

/*
    這是多行註釋
    -- GO  已移除或改為註釋
    繼續註釋內容
*/
SELECT 1;
GO

方案 2:改用單行註釋包裹 GO

/*
    這是多行註釋
    -- GO  <-- 單行註釋,osql 不會誤判
    繼續註釋內容
*/
SELECT 1;
GO

方案 3:升級工具鏈 - 棄用 osql,改用 sqlcmd

sqlcmd -S .\SQLDEV -U sa -P MyRoot -b -i ".\TestScript.sql" -o "c:\output.txt"
  • sqlcmd 為 osql 繼任者 (SQL 2005+),完整支援 T-SQL 解析、Unicode、變數替換、錯誤處理
  • osql 自 SQL Server 2012 起標記淘汰,2016 移除

方案 4:腳本預處理 (CI/CD 管線)

在部署前以 PowerShell/Python 移除註釋內的 GO:

# PowerShell 範例
$content = Get-Content -Raw -Path ".\Deploy.sql"
# 簡易移除 /* ... */ 內的 GO (需更健全的解析器)
$content = [regex]::Replace($content, '(?s)/\*.*?\*/', { 
    return $_.Value.Replace("GO", "-- GO") 
})
Set-Content -Path ".\Deploy_Clean.sql" -Value $content

最佳實務建議

  1. 全面替換 osql 為 sqlcmd:所有部署腳本、維護作業、CI/CD 管線
  2. 腳本規範:多行註釋 /* ... */ 內嚴禁出現 GO、;、未閉合引號等可能干擾解析器的標記
  3. 批次分隔符:GO 必須獨佔一行、行首無縮進、大寫,避免出現在字串常數、註釋、動態 SQL 中
  4. 編碼:腳本檔統一儲存為 UTF-8 with BOM 或 Unicode (UTF-16 LE),sqlcmd -f 65001 指定編碼

相關已知 osql 缺陷

  • 註釋內 GO 導致「Missing end comment mark」
  • 字串常數內 GO 被誤判為批次分隔
  • Unicode 檔案無 BOM 導致亂碼
  • 長度超過 8000 字元的行截斷
  • 無 :on error、:setvar 等進階腳本控制指令

結論:osql 屬舊世代工具,解析器缺陷無修補可能。遇到此類問題,直接遷移至 sqlcmd 是唯一正確、永久的解決方案,同時獲得 Unicode、變數化、錯誤控制等現代化功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved