下面是我在查資料庫的Function
public static DataTable ReadSQLToDT(string pSQL)
{
string constr = "SQL Connection String";
DataTable dtSource = new DataTable();
try
{
using (SqlConnection conn = new SqlConnection(constr))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(pSQL, conn))
{
cmd.CommandTimeout = 3;
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dtSource);
cmd.Cancel();
conn.Close();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return dtSource;
}
資料量太龐大時
在SqlDataAdapter這邊會出問題
第一個問題是如果我想要將龐大的資料量查完
程式會在60秒左右的時候直接掛掉
直接出現下面的訊息
不管我timeout設定多長都一樣
第二個問題是如果資料量一樣很龐大的前提下
我想要它時間一到不管有沒有查完就自己timeout跳出來
但這部分設定timeout一樣完全沒作用
一樣會等到差不多60秒的時候跳出上面那個錯誤訊息
想請問是我timeout還是哪邊設定錯呢?
public static DataTable ReadSQLToDT(string pSQL)
{
string constr = "SQL Connection String";
DataTable dtSource = new DataTable();
try
{
using (SqlConnection conn = new SqlConnection(constr))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(pSQL, conn))
{
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.SelectCommand.CommandTimeout = 3;
adapter.Fill(dtSource);
cmd.Cancel();
conn.Close();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return dtSource;
}
https://stackoverflow.com/questions/30910016/how-to-increase-timeout-of-dataadapter-to-3-min
以 實習工程師 所提供的
adapter.SelectCommand.CommandTimeout = 3;
其兩段差異不大,但太大量的資料還是會 Timeout 的情形,可以在下達 SQL 透過 SSMS 用戶端統計資料來比較這語法的差異。
但還是建議你太大量的資料,還是以 ROW_NUMBER 來進行分頁查詢,TSQL 裡面做分頁查詢非常的簡單可以詢問 ChatGPT 來提供你分頁的 TSQL 語法
以下是一個分批查詢資料的範例,將資料分段填充到 DataTable 中,以避免一次性查詢大量資料的問題:
public static DataTable ReadSQLToDT(string pSQL)
{
string constr = "SQL 連線字串";
DataTable dtSource = new DataTable();
try
{
using (SqlConnection conn = new SqlConnection(constr))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(pSQL, conn))
{
cmd.CommandTimeout = 60;
using (SqlDataReader reader = cmd.ExecuteReader())
{
// 每次查詢的記錄數
int batchSize = 1000;
// 當前已經讀取的記錄數
int currentCount = 0;
// 設置 DataTable 的結構
for (int i = 0; i < reader.FieldCount; i++)
{
dtSource.Columns.Add(reader.GetName(i), reader.GetFieldType(i));
}
// 逐批將資料填充到 DataTable 中
while (reader.Read())
{
DataRow row = dtSource.NewRow();
for (int i = 0; i < reader.FieldCount; i++)
{
row[i] = reader.GetValue(i);
}
dtSource.Rows.Add(row);
currentCount++;
// 每達到批次大小,就提交到 DataTable 中,並清空 DataRow 集合
if (currentCount % batchSize == 0)
{
dtSource.AcceptChanges();
dtSource.Clear();
}
}
// 將剩餘的資料提交到 DataTable 中
if (dtSource.Rows.Count > 0)
{
dtSource.AcceptChanges();
}
}
cmd.Cancel();
conn.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return dtSource;
}
另外,如果需要處理大量資料,也可以考慮使用 ORM 框架(例如 Entity Framework)處理資料,這樣可以避免手動處理記憶體和資料庫的交互。