You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多表查询展示到多DataGridView的问题及存储过程优化咨询

搜索功能实现问题与优化咨询

需求背景

正在实现一个搜索功能,需从数据库多张表查询数据并展示到对应DataGridView中(每张数据库表对应一个DataGridView)。

现有实现

存储过程

获取Style表数据的存储过程

CREATE PROCEDURE [dbo].[FetchCS_V2] @Keyword nvarchar(30)
AS
 SELECT [RID]
      ,[CustomerBrand]
      ,[CustomerStyle]
      ,[ProductName]
      ,[ProductType]
      ,[ValidityDateFrom]
      ,[ValidityDateTo]
      ,[Colorway]
      ,[Season]
      ,[Factory]
  FROM [dbo].[CostSheet_Mst]
  WHERE RID Like '%' + @Keyword + '%'
  OR CustomerStyle Like '%'+ @Keyword + '%'
  OR ProductName Like '%'+ @Keyword + '%'
  OR ProductType Like '%'+ @Keyword + '%'
  OR ValidityDateFrom Like '%'+ @Keyword + '%'
  OR ValidityDateTo Like '%'+ @Keyword + '%'
  OR Colorway Like '%'+ @Keyword + '%'
  OR Season Like '%'+ @Keyword + '%'
  OR Factory Like '%'+ @Keyword + '%'

GO

获取FOB表数据的存储过程

CREATE PROCEDURE [dbo].[FetchCS_FOB_V2] @Keyword nvarchar(30)
AS
 SELECT [FobRID]
      ,[RID]
      ,[FOBType]
      ,[Amount]
      ,[Currency]
  FROM [dbo].[CostSheet_FOB]
  WHERE RID IN
  (SELECT  
       [RID]
      FROM CostSheet_Mst
      where [RID] LIKE '%' + @Keyword + '%')
    OR [FOBType] LIKE '%' + @Keyword + '%'
    OR [Amount] LIKE '%' + @Keyword + '%'
    OR [Currency] LIKE '%' + @Keyword + '%'


GO

C#搜索函数

private void searchFromDB() 
{
    try
    {
        string mainconn1 = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
        SqlConnection sqlconn = new SqlConnection(mainconn1);
        SqlCommand sqlcomm1 = new SqlCommand("exec [dbo].[FetchCS_V2] '"+searchTextBox.Text+"'", sqlconn); //主表存储过程
        SqlCommand sqlcomm2 = new SqlCommand("exec [dbo].[FetchCS_FOB_V2] '" + searchTextBox.Text + "'", sqlconn); //FOB表存储过程
        //sqlcomm1.CommandType = CommandType.StoredProcedure;
        SqlDataAdapter da1 = new SqlDataAdapter();
        SqlDataAdapter da2 = new SqlDataAdapter();
        da1.SelectCommand = sqlcomm1;
        da2.SelectCommand = sqlcomm2;

        DataTable dt1 = new DataTable();
        DataTable dt2 = new DataTable();
        da1.Fill(dt1);
        da2.Fill(dt2);
        dataGridViewStyleSearch.DataSource = dt1;
        dataGridViewFOBSearch.DataSource = dt2;
        sqlconn.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show(string.Format("There's an error: {0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

当前问题

  • 搜索关键词为RID时,两个DataGridView都能返回对应数据;
  • 搜索仅FOB表含有的字段(如FOBType、Amount、Currency)时,只有FOB表对应的DataGridView返回数据,Style表的DataGridView无结果。

优化疑问

是否使用单个存储过程查询所有表字段会更优?如果可行,如何将结果存入单个DataTable后拆分到对应DataGridView?


问题原因分析

当前Style表的存储过程FetchCS_V2仅在自身表字段中匹配关键词,当搜索FOB表独有的字段时,Style表无对应匹配逻辑,自然返回空结果。而FOB表的存储过程同时匹配了RID关联的主表数据和自身字段,因此能正常返回结果。

解决方案1:修改现有存储过程

修改FetchCS_V2,增加关联FOB表字段的匹配逻辑,确保搜索FOB字段时能返回关联的主表数据:

CREATE PROCEDURE [dbo].[FetchCS_V2] @Keyword nvarchar(30)
AS
 SELECT DISTINCT m.[RID]
      ,m.[CustomerBrand]
      ,m.[CustomerStyle]
      ,m.[ProductName]
      ,m.[ProductType]
      ,m.[ValidityDateFrom]
      ,m.[ValidityDateTo]
      ,m.[Colorway]
      ,m.[Season]
      ,m.[Factory]
  FROM [dbo].[CostSheet_Mst] m
  LEFT JOIN [dbo].[CostSheet_FOB] f ON m.RID = f.RID
  WHERE m.RID Like '%' + @Keyword + '%'
  OR m.CustomerStyle Like '%'+ @Keyword + '%'
  OR m.ProductName Like '%'+ @Keyword + '%'
  OR m.ProductType Like '%'+ @Keyword + '%'
  OR m.ValidityDateFrom Like '%'+ @Keyword + '%'
  OR m.ValidityDateTo Like '%'+ @Keyword + '%'
  OR m.Colorway Like '%'+ @Keyword + '%'
  OR m.Season Like '%'+ @Keyword + '%'
  OR m.Factory Like '%'+ @Keyword + '%'
  -- 新增FOB表字段匹配逻辑
  OR f.FOBType Like '%' + @Keyword + '%'
  OR f.Amount Like '%' + @Keyword + '%'
  OR f.Currency Like '%' + @Keyword + '%'

GO

解决方案2:使用单个存储过程返回多结果集

单个存储过程可直接返回多个结果集,无需拆分DataTable,ADO.NET会自动处理结果集顺序,效率更高:

单个存储过程实现

CREATE PROCEDURE [dbo].[FetchAllCostSheetData] @Keyword nvarchar(30)
AS
 -- 返回主表数据(包含FOB字段关联匹配)
 SELECT DISTINCT m.[RID]
      ,m.[CustomerBrand]
      ,m.[CustomerStyle]
      ,m.[ProductName]
      ,m.[ProductType]
      ,m.[ValidityDateFrom]
      ,m.[ValidityDateTo]
      ,m.[Colorway]
      ,m.[Season]
      ,m.[Factory]
  FROM [dbo].[CostSheet_Mst] m
  LEFT JOIN [dbo].[CostSheet_FOB] f ON m.RID = f.RID
  WHERE m.RID Like '%' + @Keyword + '%'
  OR m.CustomerStyle Like '%'+ @Keyword + '%'
  OR m.ProductName Like '%'+ @Keyword + '%'
  OR m.ProductType Like '%'+ @Keyword + '%'
  OR m.ValidityDateFrom Like '%'+ @Keyword + '%'
  OR m.ValidityDateTo Like '%'+ @Keyword + '%'
  OR m.Colorway Like '%'+ @Keyword + '%'
  OR m.Season Like '%'+ @Keyword + '%'
  OR m.Factory Like '%'+ @Keyword + '%'
  OR f.FOBType Like '%' + @Keyword + '%'
  OR f.Amount Like '%' + @Keyword + '%'
  OR f.Currency Like '%' + @Keyword + '%'

 -- 返回FOB表数据
 SELECT [FobRID]
      ,[RID]
      ,[FOBType]
      ,[Amount]
      ,[Currency]
  FROM [dbo].[CostSheet_FOB]
  WHERE RID IN
  (SELECT DISTINCT m.RID
   FROM [dbo].[CostSheet_Mst] m
   LEFT JOIN [dbo].[CostSheet_FOB] f ON m.RID = f.RID
   WHERE m.RID Like '%' + @Keyword + '%'
   OR m.CustomerStyle Like '%'+ @Keyword + '%'
   OR m.ProductName Like '%'+ @Keyword + '%'
   OR m.ProductType Like '%'+ @Keyword + '%'
   OR m.ValidityDateFrom Like '%'+ @Keyword + '%'
   OR m.ValidityDateTo Like '%'+ @Keyword + '%'
   OR m.Colorway Like '%'+ @Keyword + '%'
   OR m.Season Like '%'+ @Keyword + '%'
   OR m.Factory Like '%'+ @Keyword + '%'
   OR f.FOBType Like '%' + @Keyword + '%'
   OR f.Amount Like '%' + @Keyword + '%'
   OR f.Currency Like '%' + @Keyword + '%')
  OR [FOBType] LIKE '%' + @Keyword + '%'
  OR [Amount] LIKE '%' + @Keyword + '%'
  OR [Currency] LIKE '%' + @Keyword + '%'

GO

C#调用代码

private void searchFromDB() 
{
    try
    {
        string mainconn1 = ConfigurationManager.ConnectionStrings["MyConnection"].ConnectionString;
        using(SqlConnection sqlconn = new SqlConnection(mainconn1))
        {
            SqlCommand sqlcomm = new SqlCommand("[dbo].[FetchAllCostSheetData]", sqlconn);
            sqlcomm.CommandType = CommandType.StoredProcedure;
            sqlcomm.Parameters.AddWithValue("@Keyword", searchTextBox.Text);
            
            SqlDataAdapter da = new SqlDataAdapter(sqlcomm);
            DataSet ds = new DataSet();
            da.Fill(ds); // 自动填充两个结果集到DataSet,顺序与存储过程返回一致
            
            if(ds.Tables.Count >=1)
                dataGridViewStyleSearch.DataSource = ds.Tables[0];
            if(ds.Tables.Count >=2)
                dataGridViewFOBSearch.DataSource = ds.Tables[1];
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(string.Format("错误信息: {0}", ex.Message), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

注:使用using语句自动释放连接资源,参数化查询避免SQL注入风险(原字符串拼接写法存在漏洞)。

方案对比

  • 单个存储过程返回多结果集:减少数据库连接次数,逻辑集中易维护,性能更优;
  • 拆分DataTable:无必要,ADO.NET原生支持多结果集处理,拆分反而增加代码复杂度与性能损耗。

内容的提问来源于stack exchange,提问作者Riku_dola

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 18:15:41