我有SelectedType包含type_1 ... type_2_3資料型別列的表bit:
P_ID type_1 type_1_1 type_1_2 type_1_3 type_2 type_2_1 type_2_2 type_2_3
1 0 1 1 0 0 1 0 1
2 1 0 1 0 0 1 0 0
3 1 0 1 0 0 1 0 0
4 0 0 0 1 1 1 1 1
...and so on
和 JSON 陣列
[
{"value": "type_1_1"}, {"value": "type_2_1"}, {"value": "type_2_3"}
]
如何使用 for 回圈更新 SQL Server 表,如果 {"value": "type_1_1"} 等于表列名 type_1_1 然后將值設定為 1 或者如果值為 1 然后設定為 0?
這是我目前正在嘗試的:
public bool UpdatePredictSubGoalType(int id, string _selectedTypes)
{
string a = "[]";
string item = _selectedTypes;
if (!item.Contains('[') && !item.Contains(']'))
{
string c = a.Insert(1, _selectedTypes);
item = c;
}
bool res = false;
JArray Ja = JArray.Parse(item);
string sqlstr = "";
try
{
using (conn = new SqlConnection(CommonDA.GetConnectionString()))
{
conn.Open();
trans = conn.BeginTransaction();
try
{
for (int i = 0; i <= Ja.Count - 1; i )
{
string x = Ja[i]["value"].ToString();
SqlCommand cmd = conn.CreateCommand();
sqlstr = @"Update SelectedType set " x " = (0 or 1, i don't know how to do) where id = @id AND " x " = @" x;
cmd.CommandText = sqlstr;
cmd.Transaction = trans;
cmd.Parameters.AddWithValue("@id", id);
cmd.ExecuteNonQuery();
trans.Commit();
conn.Close();
res = true;
}
}
catch (Exception Err)
{
trans.Rollback();
CommonLB.SystemError(Err.Message);
CommonLB.SystemError("Data", "SQL:" sqlstr);
}
}
}
catch (Exception Err)
{
throw new ApplicationException(Err.Message, Err);
}
return res;
}
uj5u.com熱心網友回復:
假設我在評論中提到的內容是正確的(值的存在定義為 1,不存在定義為 0)我認為,在設定 1 之前,您需要將所有內容設定為 0,或者開始收集所有列所以 C# 可以計算出什么應該是 0..
像這樣的東西(安裝 Dapper 以使 ExecuteAsync 在連接上成為“一件事”,或將其擴展為“長路”):
using var conn = new SqlConnection(CommonDA.GetConnectionString()));
var sql = "UPDATE t SET type_1=0, type_1_1=0, type_1_2=0, type_1_3=0, type_2=0, type_2_1=0, type_2_2=0, type_2_3=0 WHERE ID = @id";
for (int i = 0; i <= Ja.Count - 1; i ){
var c = Ja[i]["value"].ToString();
if(!Regex.IsMatch(c, @"^type_\d(_\d)?$")
continue;
sql = sql.Replace($"{c}=0", $"{c}=1");
}
await conn.ExecuteAsync(sql, new { id });
我們首先命名表中的列,并將其設定為type_x_y=0. 然后對于 json 中存在的每個列名,我們將 SQL 的那部分更改type_x_y=1為一些字串替換
正則運算式是為了防止 json 供應商的 SQL 注入攻擊
uj5u.com熱心網友回復:
您可以將整個 JSON 陣列傳遞給 SQL,然后讓 SQL Server 對其進行分解。
- 使用
OPENJSON帶出單獨的行 - 將其轉回單行,每列都有一個 1 或 0
- 使用的組合
ISNULL,并NULLIF保持相同的值- 如果你想覆寫所有列,那么你可以簡單地做
type_1 = j.type_1
- 如果你想覆寫所有列,那么你可以簡單地做
UPDATE st
SET
type_1 = IIF(j.type_1 = 1, 1, st.type_1 ),
type_1_1 = IIF(j.type_1_1 = 1, 1, st.type_1_1),
type_1_2 = IIF(j.type_1_2 = 1, 1, st.type_1_2),
type_1_3 = IIF(j.type_1_3 = 1, 1, st.type_1_3),
type_2 = IIF(j.type_2 = 1, 1, st.type_2 ),
type_2_1 = IIF(j.type_2_1 = 1, 1, st.type_2_1),
type_2_2 = IIF(j.type_2_2 = 1, 1, st.type_2_2),
type_2_3 = IIF(j.type_2_3 = 1, 1, st.type_2_3)
FROM SelectedType st
CROSS APPLY (
SELECT *
FROM OPENJSON(@json)
WITH (value sysname) j
PIVOT (COUNT(value) FOR value IN
(type_1, type_1_1, type_1_2, type_1_3, type_2, type_2_1, type_2_2, type_2_3)
) pvt
) j
WHERE st.P_ID = @id;
那么你的應用代碼就變得很簡單了
public bool UpdatePredictSubGoalType(int id, string _selectedTypes)
{
if (!item.StartsWith('['))
_selectedTypes = '[' _selectedTypes;
if (!item.EndsWith(']'))
_selectedTypes = _selectedTypes ']';
try
{
const string query = @"
THE ABOVE QUERY
";
using (var conn = new SqlConnection(CommonDA.GetConnectionString()))
using (var cmd = new SqlCommand(query, conn))
{
cmd.Parameters.Add("@id", SqlDbType.Int).Value = id;
cmd.Parameters.Add("@json", SqlDbType.NVarChar, -1).Value = _selectedTypes;
conn.Open();
cmd.ExecuteNonQuery();
}
}
catch (Exception Err)
{
throw new ApplicationException(Err.Message, Err);
}
return true;
}
uj5u.com熱心網友回復:
更改您的 sql 字串:
str = $"Update SelectedType set [{x}] = CASE WHEN [{x}] = 0 then 1 else 0 end where id = {@id}";
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/322268.html
