首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

C# 連接 MySQL 實現動態行號:解決 @rownum 變量報錯的關鍵配置

     編輯:MySQL 資料庫相關知識

在 C# 應用中通過 ADO.NET 執行包含 MySQL 用戶變量(如 @rownum := @rownum + 1)的 SQL 時,常遇到「Parameter '@rownum' must be defined」或語法錯誤。根因在於 MySQL Connector/NET 驅動默認不解析用戶變量。本文給出最小配置修復方案並說明原理。

問題現象

SQL 在 Navicat/MySQL Workbench 執行正常:

SELECT 
    @rownum := @rownum + 1 AS rownum,
    a.order_id, a.order_sn, ...
FROM (SELECT @rownum := 0) r, xj_order_info a
WHERE ... ORDER BY rownum ASC;

但在 C# 代碼中執行拋異常:MySqlException: Parameter '@rownum' must be defined 或語法錯誤。

根因分析

  • MySQL Connector/NET 的 SQL 解析器會預掃描 @ 開頭的標識符,視為參數佔位符(類似 ?name 或 @name)。
  • 驅動嘗試將 @rownum 綁定為 MySqlParameter,但代碼未定義該參數,故報錯。
  • 這是驅動層行為,而非 MySQL Server 語法問題。

解決方案:連接字符串啟用 Allow User Variables=True

在連接字符串中添加此選項,指示驅動忽略 @ 變量的參數化解析,直接發送原始 SQL 給 Server:

Server=127.0.0.1;Port=3306;Database=test;Uid=root;Pwd=123456;Allow User Variables=True;

C# 代碼示例:

using MySql.Data.MySqlClient;

string connStr = "Server=127.0.0.1;Database=test;Uid=root;Pwd=123456;Allow User Variables=True;";
string sql = @"
    SELECT 
        @rownum := @rownum + 1 AS rownum,
        a.order_id, a.order_sn
    FROM (SELECT @rownum := 0) r, xj_order_info a
    WHERE a.order_status = 1
    ORDER BY rownum ASC";

using (var conn = new MySqlConnection(connStr))
using (var cmd = new MySqlCommand(sql, conn))
{
    conn.Open();
    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            Console.WriteLine($"{reader[\"rownum\"]}\t{reader[\"order_id\"]}\t{reader[\"order_sn\"]}");
        }
    }
}

替代方案:不依賴用戶變量(推薦)

MySQL 8.0+ 支持窗口函數,寫法標準、無驅動兼容性問題、效能更優:

SELECT 
    ROW_NUMBER() OVER (ORDER BY a.add_time) AS rownum,
    a.order_id, a.order_sn, ...
FROM xj_order_info a
WHERE a.order_status = 1
ORDER BY a.add_time;

MySQL 5.7 或不願升級時,亦可用衍生表模擬:

SELECT t.*, @rownum := @rownum + 1 AS rownum
FROM (
    SELECT order_id, order_sn ... FROM xj_order_info WHERE order_status = 1 ORDER BY add_time
) t, (SELECT @rownum := 0) r;

最佳實踐總結

場景推薦做法
MySQL 8.0+ 環境直接使用 ROW_NUMBER() OVER () 窗口函數
舊版本必須用 @ 變量連接字符串加 Allow User Variables=True
新建項目/重構優先選窗口函數,避免驅動耦合與維護成本

補充:其他常見連接字符串參數

  • CharSet=utf8mb4:解決 Emoji/生僻字亂碼。
  • SslMode=None / Required:按需控制 TLS。
  • DefaultCommandTimeout=60:防止長查詢超時。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved