用foreach构建SQL

时间:2018-05-16 06:32:02

标签: 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 (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);
}

所以在这里我有List<Int_String> partneri,其中包含5k行。对于每一个,我运行Komercijalno.Partner.PoslednjaKupovina(partner._int),其中包含如下所示的SQL语句:

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);
        }
    }
}

所以SQL语句执行5k次,这太慢了。

那么我怎么能将我的List<Int_String>或者只是一系列的int传递给sql命令,所以我执行一次(在foreach内部或者其他方式)并返回dataAdapter所以我只执行一次SQL。 / p>

返回的DataAdapter应如下所示:

| ppid     | datum    |

所以,假设我有表PARTNER(我用partneri填充列表SELECT PPID, NAZIV FROM PARTNER),其中包含以下数据:

| 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 |

2 个答案:

答案 0 :(得分:1)

您可以使用单个查询替换所有逻辑:

select d.ppid, max(d.datum)
from partner p
inner join dokument d
    on d.ppid = p.ppid
group by d.ppid

您可能需要添加where - 条款以及其他条件来选择您想要的合作伙伴。

答案 1 :(得分:0)

把它作为一个答案,因为问题下面已经有很多评论,所以它只会在那里的噪音中丢失。

  

那我怎么能把我的List或者只是一些int的数组传递给sql命令所以我执行了一次

这里讨论了这个问题:Filter sql based on C# List instead of a filter table

根据查询的典型(频繁)程度以及数据的大小,几乎没有办法。

  • 全球临时表
  • 使用UNION ALL和多个select {constants} from RDB$database
  • 模仿GTT
  • 将列表展平为一个特殊格式的长字符串,并使用反向LIKE匹配。

PS。对于您的特定任务,Mark的答案肯定要好得多:您不必从服务器获取大量数据,只能将其传回另一个查询中。我只想链接一个已经回答的问题,与此问题的一部分有关。