C# 使用foreach构建SQL
我有以下代码:C# 使用foreach构建SQL,c#,sql,winforms,firebird,C#,Sql,Winforms,Firebird,我有以下代码: private void button1_Click(object sender, EventArgs e) { foreach(Int_String partner in partneri) { double danaBezProdaje = (DateTime.Today - Komercijalno.Partner.PoslednjaKupovina(partner._int)).TotalDays; if (danaBezP
private void button1_Click(object sender, EventArgs e)
{
foreach(Int_String partner in partneri)
{
double danaBezProdaje = (DateTime.Today - Komercijalno.Partner.PoslednjaKupovina(partner._int)).TotalDays;
if (danaBezProdaje > 31 && danaBezProdaje < 1100)
{
NeaktivniPartner np = new NeaktivniPartner();
np.ppid = partner._int;
np.naziv = partner._string;
np.danaBezKupovine = danaBezProdaje;
neaktivniPartneri.Add(np);
}
}
dataGridView1.DataSource = M.List.ConvertToDataTable(neaktivniPartneri);
}
所以SQL语句执行了5k次,这太慢了
所以,我如何将我的列表或只是int数组传递给sql命令,以便在foreach中执行一次,或者如何返回dataAdapter,以便只执行一次sql
返回的DataAdapter应如下所示:
public static DateTime PoslednjaKupovina(int ppid)
{
using (FbConnection con = new FbConnection(M.Baza.connectionKomercijalno2018))
{
con.Open();
using (FbCommand cmd = new FbCommand("SELECT DATUM FROM DOKUMENT WHERE PPID = @PPID ORDER BY DATUM DESC", con))
{
cmd.Parameters.AddWithValue("@PPID", ppid);
FbDataReader dr = cmd.ExecuteReader();
if (dr.Read())
return Convert.ToDateTime(dr[0]);
else
return new DateTime(1, 1, 1);
}
}
}
| ppid | datum |
假设我有一个表PARTNER,从中我用SELECT PPID填充列表partneri,用其中的数据填充来自PARTNER的NAZIV:
| PPID | NAZIV |
| 1 | name001 |
| 2 | name002 |
| 3 | name003 |
| 4 | name004 |
假设我的DOKUMENT表有以下数据:
| ID | PPID | DATE |
| 1 | 2 | 12.03.2018 |
| 2 | 3 | 12.03.2018 |
| 3 | 2 | 05.03.2018 |
| 4 | 2 | 03.04.2018 |
| 5 | 1 | 26.03.2018 |
| 6 | 4 | 21.02.2018 |
| 7 | 4 | 06.05.2018 |
我想要的输出是:
| PPID | DATE |
| 1 | 26.03.2018 |
| 2 | 03.04.2018 |
| 3 | 12.03.2018 |
| 4 | 06.05.2018 |
您可以用一个查询替换所有逻辑,该查询执行以下操作:
select d.ppid, max(d.datum)
from partner p
inner join dokument d
on d.ppid = p.ppid
group by d.ppid
您可能需要添加一个带有附加条件的where子句来选择您想要的合作伙伴。将其作为答案,因为问题下面已经有很多注释,因此它将在噪音中消失 那个么,我如何才能将我的列表或只是int数组传递给sql命令,以便在那个里执行一次呢 这里讨论了这个问题: 根据查询的典型频率和数据的大小,有几种方法 全局临时表 使用RDB$数据库中的UNIONALL和几个select{constants}模拟GTT 将列表展平为一个特殊格式的长字符串,并使用反向匹配。
另外,对于您的特定任务,Mark的答案肯定要好得多:您不必从服务器获取大量数据,只需在另一个查询中将其传回。我只是想链接一个已经回答过的问题,与其中的一部分相关。通过加入ID,并在where子句中使用。我应该如何将其传递给command?这不是一个好方法@Aria。参数字符串可能会在限制处出错,这样会导致性能下降。@HüseyinBurakKaradag,我认为限制超过5k,但我不知道确切的限制,但它可能会被分块插入?@AleksaRistic您在哪里填写“partneri”数据?若您在DB上获得数据,为什么要使用join DOKUMENT表?如果您的答案是否定的,我的解决方案是,使用“批量插入”方法将ids数据插入会话临时表,并将其与文档表联接。这比maxd.datum快得多,我想成为'DateTime.Today-maxd.datum.TotalDays'。我怎样才能做到这一点呢query@AleksaRistic您应该考虑在C代码中保留这一点,但也可以考虑用另一个包包装SELECT,例如选择嵌套选择的PPID、DATEDIFEDY、DATM、CurrutyDATA日期差异。他不能把这个减法直接放到顶层选择吗?也许,我会从客户端发送DateTime.Today作为参数。因此,服务器会将其视为常量,并且由于客户端计算机和服务器计算机上的本地日期时间可能不同,在这种特定情况下,我可能不会使用DateDiff,而是直接使用日期-日期减法,如果需要,将数据列类型转换为类型@AleksaRistic总的来说,在这个答案的评论中,你添加了两点,这两点是问题本身所遗漏的。你需要的是天数而不是日期,重要的是,你的实际筛选不是任意的、随机的ID列表,而是真正的标准是PARTNER.VIP=1。你从问题中漏掉了关键信息——你真正想要的是什么——而你得到的答案与你真正的问题很不协调-///你的观点应该列在问题本身,而不是评论中!!!评论很嘈杂,很难在那里找到。