若只有變數只有一個數值可以簡單使用 `Parameters.AddWithValue` 將變數值帶入,多個變數也只要重複 n 次
但若是在 in 的變量有多個就無法用 `Parameters.AddWithValue("@t","'t1','t2'")`
:::spoiler 範例程式
```csharp
using System.Data.SqlClient;
var connString = "server=10.12.12.13;...";
var SQLString = @"SELECT USERSNAME,USERID FROM USERS
WHERE date=@date
and country=@country
and currency in (@currency)";
var conn = new SqlConnection(connString);
conn.Open();
var cmd = new SqlCommand(SQLString, conn);
cmd.Parameters.AddWithValue("@date", "2023-04-01");
cmd.Parameters.AddWithValue("@country", "taiwan");
var dr = cmd.ExecuteReader();
while (dr.Read())
{
//防止為空白行
if (!dr[0].Equals(DBNull.Value))
{
string USERSNAME = dr["USERSNAME"].ToString();
string USERID = dr["USERID"].ToString();
//do something
}
}
```
:::
### 法一:
也可以用這種方式做到
```sql
-- csharp 組參數的方法
var parameters = string.Join(',', arrstr.Select(s => $"'{s}'"));
_dataAccess.Execute<IEnumerable<PlayerActivityEntity>>($"call {DBName}.{SpName}('{playerId}', \"{gameIdsParameter}\")");
call DBName.SpName('player234',"'MBNB','THB'");
-- 將 sql 語法組裝
set @qry = concat(
"SELECT website, playerid, currency, firstbetat, lastbetat,
IFNULL(pa.agent, (select dp.agent from journal.daily_player dp where dp.playerid=pa.playerid limit 1)) as agent
FROM journal.player_activity pa
Where pa.playerid = '", _playerid, "' and pa.currency in ( ", _currencies, ");
");
prepare cmd from @qry;
execute cmd;
deallocate prepare cmd;
```
或者使用 [FIND_IN_SET](https://hackmd.io/5eZR6iFOTl2dIeueDGYH0g#FIND_IN_SET),參數組成會比較簡單一點
```sql
call DBName.SpName('p462brick1992', 'bonus-dice,dice,plinko');
-- 將 sql 語法組裝
set @qry = concat(
"SELECT website, playerid, gameid, firstbetat, lastbetat,
IFNULL(pa.agent, (select dp.agent from journal.daily_player dp where dp.playerid=pa.playerid limit 1)) as agent
FROM journal.player_activity pa
Where pa.playerid = '", _playerid, "'
and FIND_IN_SET(pa.gameid, '",_gameids,"');
");
```
### 法二:直接用 replace
將變數直接用 replace 替換掉,會有 sql injection 的風險
注意 replace 必須發生在放入 SqlCommand 前
```csharp
var SQLString = @"SELECT USERSNAME,USERID FROM USERS
WHERE date=@date
and country=@country
and currency in (@currency)";
var curries = new string[];
SQLString = SQLString.Replace("@currency", $"'{string.Join("','", curries)}'");
```
### 法三:跑迴圈產生變數
其實跟 replace 很像,只是變成多產生幾個變數再一一帶入,唯一好處是可避免 sql injection
```csharp
var SQLString = @"SELECT USERSNAME,USERID FROM USERS
WHERE date=@date
and country=@country
and currency in (@T)";
var curries = new string[];
new[] { "THB", "IDR" };
var parameters = curries.Select((s, i) => "@currency" + i).ToArray();
SQLString = SQLString.Replace("@T", string.Join(",", parameters));
var conn = new SqlConnection(connString);
conn.Open();
var cmd = new SqlCommand(SQLString, conn);
for (int i = 0; i < parameters.Length; i++)
cmd.Parameters.AddWithValue(parameters[i], curries[i]);
```
[Parameters.AddWithValue & Parameters.Add - 小毛](https://dotblogs.com.tw/dennismao/2012/11/13/82906)