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

SQL Server 遷移 Access 避坑指南:視圖查詢當機、語法差異與資料型別對照

     編輯:關於SqlServer

觸發情境

專案需將 SQL Server 資料庫轉換為 Access (.mdb)。使用「匯入/匯出精靈」轉換後,部分查詢在 Access 中執行直接當機 (Access 停止回應),SQL Server 卻完全正常。

根因分析:Access 子查詢引用外部欄位的「特色」

原始 SQL Server 正常查詢

SELECT 
    Product.產品ID,
    (SELECT SUM(數量) FROM NowLib WHERE NowLib.產品ID = Product.產品ID) AS 現存數量,
    預警上限,
    (SELECT 預警上限 - SUM(數量) FROM NowLib WHERE NowLib.產品ID = Product.產品ID) AS 缺貨數量,
    ...
FROM Product
GROUP BY Product.產品ID, 通用名, ..., 預警上限, 預警下限
ORDER BY 品名, 產地;

問題點

第二個子查詢引用了外層查詢的 預警上限 (主表欄位)。Access 對「子查詢中引用外層非關聯欄位」的處理機制有缺陷,導致查詢最佳化器陷入無限循環或記憶體耗盡而當機。

修正寫法:預先計算再外層引用

SELECT 
    產品ID, 預警上限, 預警下限, 通用名, 輸入碼, 品名, 產地, 規格, 單位, 包裝, 劑型, 
    零售價, 批發價, 近期進價, 批准文號,
    (SELECT SUM(n3.數量) FROM NowLib n3 WHERE n3.產品ID = Pro.產品ID) AS 總數量,
    預警上限 - 總數量 AS 缺貨數量
FROM Product Pro
GROUP BY 產品ID, 通用名, 輸入碼, 品名, 產地, 規格, 單位, 包裝, 劑型, 
         零售價, 批發價, 近期進價, 批准文號, 預警上限, 預警下限
ORDER BY 品名, 產地;

原則:子查詢僅引用關聯鍵值 (如產品ID),所有外層業務欄位移至外層 SELECT 列表運算。

SQL Server → Access 轉換常見差異對照表

項目SQL ServerAccess處理建議
視圖轉換View自動轉為資料表 (非查詢)手動重建為 Access 查詢
空字串預設值''""腳本批次替換
目前日期時間GETDATE()NOW() / DATE()全域搜尋替換
用戶端機器名HOST_NAME()無對應函數應用層傳入
CASE WHEN支援不支援改用 IIF() 或 SWITCH()
TOP nTOP nTOP n (需 ORDER BY)補齊 ORDER BY
IDENTITYIDENTITY(1,1)AUTOINCREMENT重建資料表
日期字面值'2024-01-15'#2024-01-15#腳本替換
字串聯集+&腳本替換
ISNULLISNULL(a,b)NZ(a,b)腳本替換

遷移檢查清單

  1. 清單所有 View → 手動在 Access 建立對應 Query。
  2. 搜尋所有預存程序/觸發器/預設值中的 GETDATE()、HOST_NAME()、CASE WHEN、ISNULL、+ (字串聯集)。
  3. 日期字面值 'YYYY-MM-DD' → #YYYY-MM-DD#。
  4. 身分欄位 IDENTITY → AUTOINCREMENT,注意種子值重設。
  5. 大量資料表建議:Access 中建立連結資料表 (Linked Tables) 指向 SQL Server,僅將查詢/報表/表單遷移,資料留在 SQL Server — 兼得效能與前端便利。

結語

SQL Server 遷移 Access 非單純資料搬移,查詢引擎差異 (特別是子查詢關聯、CASE WHEN、日期函數) 是當機與錯誤的主要來源。建議採「連結資料表 + 前端遷移」架構,或完整重寫查詢邏輯並充分測試。

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