查詢範例

This commit is contained in:
2025-10-19 21:59:22 +08:00
parent 87a2c35300
commit 6a43883d08
12 changed files with 6293 additions and 53 deletions

View File

@@ -0,0 +1,246 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web.Http;
using System.Configuration;
/// <summary>
/// pivot01Controller - 法會報名統計分析 API
/// 設計理念:直接查詢 SQL VIEW保持彈性與簡潔
/// </summary>
[ezAuthorize]
public class pivot01Controller : ApiController
{
// 連線字串
private readonly string _connectionString;
public pivot01Controller()
{
// 優先使用 shopConn 連線字串(純 SQL Server 連線字串)
var shopConnectionString = ConfigurationManager.ConnectionStrings["shopConn"]?.ConnectionString;
if (!string.IsNullOrEmpty(shopConnectionString))
{
// 移除不相容的 Provider 參數
_connectionString = shopConnectionString.Replace("Provider=SQLOLEDB;", "");
}
else
{
// 備用方案:從 Entity Framework 連線字串中提取 SQL Server 連線字串
var efConnectionString = ConfigurationManager.ConnectionStrings["ezEntities"]?.ConnectionString;
if (!string.IsNullOrEmpty(efConnectionString))
{
// 解析 EF 連線字串,提取 provider connection string 部分
var startIndex = efConnectionString.IndexOf("provider connection string=&quot;") + "provider connection string=&quot;".Length;
var endIndex = efConnectionString.LastIndexOf("&quot;");
if (startIndex > 0 && endIndex > startIndex)
{
_connectionString = efConnectionString.Substring(startIndex, endIndex - startIndex);
}
else
{
throw new InvalidOperationException("無法解析 Entity Framework 連線字串");
}
}
else
{
throw new InvalidOperationException("找不到可用的資料庫連線字串");
}
}
}
#region VIEW
/// <summary>
/// 執行 SQL 查詢並回傳 DataTable
/// </summary>
/// <param name="sql">SQL 查詢語句</param>
/// <param name="parameters">參數陣列</param>
/// <returns>查詢結果 DataTable</returns>
private DataTable ExecuteSqlQuery(string sql, SqlParameter[] parameters = null)
{
var dataTable = new DataTable();
try
{
using (var connection = new SqlConnection(_connectionString))
using (var command = new SqlCommand(sql, connection))
{
// 設定逾時時間為 60 秒
command.CommandTimeout = 60;
// 加入參數
if (parameters != null && parameters.Length > 0)
{
command.Parameters.AddRange(parameters);
}
// 開啟連線並執行查詢
connection.Open();
using (var adapter = new SqlDataAdapter(command))
{
adapter.Fill(dataTable);
}
}
}
catch (SqlException ex)
{
throw new Exception($"SQL 查詢錯誤: {ex.Message}", ex);
}
catch (Exception ex)
{
throw new Exception($"執行查詢時發生錯誤: {ex.Message}", ex);
}
return dataTable;
}
/// <summary>
/// DataTable 轉換為動態物件列表(保留中文欄位名)
/// </summary>
/// <param name="dt">DataTable</param>
/// <returns>Dictionary 列表</returns>
private List<Dictionary<string, object>> DataTableToDictionary(DataTable dt)
{
var list = new List<Dictionary<string, object>>();
foreach (DataRow row in dt.Rows)
{
var dict = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
{
// 保留原始欄位名稱(包含中文)
dict[col.ColumnName] = row[col] == DBNull.Value ? null : row[col];
}
list.Add(dict);
}
return list;
}
#endregion
#region API
/// <summary>
/// GET /api/pivot01/activity_stats
/// 查詢法會統計對應「法會統計」VIEW
/// </summary>
/// <param name="year">查詢年份</param>
/// <returns>法會統計資料</returns>
[HttpGet]
[Route("api/pivot01/activity_stats")]
public IHttpActionResult GetActivityStats(int year)
{
try
{
// 驗證年份參數
if (year < 1900 || year > 2100)
{
return BadRequest("年份參數不正確,請輸入 1900 ~ 2100 之間的年份");
}
// 建立 SQL 查詢(包含當年度及無日期的法會)
string sql = @"
SELECT * FROM [法會統計]
WHERE (YEAR(開始日期) = @year OR 開始日期 IS NULL)
ORDER BY
CASE WHEN 開始日期 IS NULL THEN 1 ELSE 0 END,
開始日期 DESC,
結束日期 DESC
";
// 建立參數
var parameters = new[]
{
new SqlParameter("@year", SqlDbType.Int) { Value = year }
};
// 執行查詢
var dataTable = ExecuteSqlQuery(sql, parameters);
var data = DataTableToDictionary(dataTable);
// 回應結果
var result = new
{
success = true,
data = data,
message = "查詢成功",
rowCount = data.Count
};
return Ok(result);
}
catch (Exception ex)
{
var errorResponse = new
{
success = false,
message = $"查詢失敗:{ex.Message}",
error = ex.ToString()
};
return Content(System.Net.HttpStatusCode.BadRequest, errorResponse);
}
}
/// <summary>
/// GET /api/pivot01/registration_details
/// 查詢報名明細對應「報名明細查詢」VIEW
/// </summary>
/// <param name="activityNum">法會編號(必填)</param>
/// <returns>報名明細資料</returns>
[HttpGet]
[Route("api/pivot01/registration_details")]
public IHttpActionResult GetRegistrationDetails(int? activityNum = null)
{
try
{
// 驗證參數
if (!activityNum.HasValue || activityNum.Value <= 0)
{
return BadRequest("請提供有效的法會編號activityNum");
}
// 建立查詢 SQL
string sql = @"
SELECT * FROM [報名明細查詢]
WHERE 法會ID = @activityNum
ORDER BY 報名日期 DESC, 報名編號 DESC
";
// 建立參數
var parameters = new[]
{
new SqlParameter("@activityNum", SqlDbType.Int) { Value = activityNum.Value }
};
// 執行查詢
var dataTable = ExecuteSqlQuery(sql, parameters);
var data = DataTableToDictionary(dataTable);
// 回應結果
var result = new
{
success = true,
data = data,
message = "查詢成功",
rowCount = data.Count
};
return Ok(result);
}
catch (Exception ex)
{
var errorResponse = new
{
success = false,
message = $"查詢失敗:{ex.Message}",
error = ex.ToString()
};
return Content(System.Net.HttpStatusCode.BadRequest, errorResponse);
}
}
#endregion
}

File diff suppressed because it is too large Load Diff