在C#代码中优化SQL函数

时间:2017-03-05 13:53:46

标签: c# sql

我遇到了一个应用程序的问题,该应用程序引导我执行以下方法。

protected override int GetCount(List<int> itemlist)
{
    sql.Execute(@"TRUNCATE Table table0");
    int count = 0;

    foreach (int itemgroup in itemlist)
    {
        count += sql.Execute(@"  INSERT  INTO table0 (ID, Guid)
                                    SELECT  table1.ID , table1.Guid
                                    FROM    dbo.tablefunction(@p0) table1 LEFT JOIN
                                            dbo.table0 ON table1.ID = table0.ID
                                    WHERE   table0.ID IS NULL", itemgroup);
    }
    return count;
}

我在插入循环期间遇到了一个关键的约束问题,这并不是完全意外的。

但我也注意到它可能会执行多种不同大小的插入,因此我正在寻找关于动态组合联合查询然后立即插入所有结果的想法/建议。例如,生成的查询可能是

WITH b AS
(
    SELECT  table1.ID , table1.Guid
    FROM    dbo.tablefunction(item0) table1 LEFT JOIN
            dbo.table0 ON table1.ID = table0.ID
    WHERE   table0.ID IS NULL

    UNION

    SELECT  table1.ID , table1.Guid
    FROM    dbo.tablefunction(item1) table1 LEFT JOIN
            dbo.table0 ON table1.ID = table0.ID
    WHERE   table0.ID IS NULL
)
INSERT  INTO table0 (ID, Guid)
SELECT * FROM b

我只是不确定如何做到这一点。

3 个答案:

答案 0 :(得分:0)

使用string.format()方法:

protected override int GetCount(List<int> itemlist)
        {
            sql.Execute(@"TRUNCATE Table table0");
            int count = 0;

            foreach (int itemgroup in itemlist)
            {
                string sql = string.Format(@"  INSERT  INTO table0 (ID, Guid)
                                    SELECT  table1.ID , table1.Guid
                                    FROM    dbo.tablefunction({0}) table1 LEFT JOIN
                                            dbo.table0 ON table1.ID = table0.ID
                                    WHERE   table0.ID IS NULL", itemgroup);

                count += sql.Execute(sql);
            }
            return count;
        }

答案 1 :(得分:0)

您可以使用Table-Valued Parameters - msdn和存储过程来执行此操作。

首先,您需要创建一个表类型以与过程一起使用:

create type dbo.ItemGroups_udt as table (ItemGroup int not null);
go

然后,创建程序:

create procedure dbo.table0_truncate_and_insert (
  @ItemGroups as dbo.ItemGroups_udt readonly
) as 
begin;
  set nocount, xact_abort on;

  truncate table table0;

  insert into table0 (id, guid)
  select tvf.id, tvf.guid
  from @ItemGroups as i
    cross apply dbo.tablefunction(i.ItemGroup) as tvf;

end;
go

如果您参与约束violoations,则可能需要使用distinct,group by或其他条件

然后,使用DataTable使用SqlParameter作为SqlDbType.Structured汇编并将项目组列表传递给存储过程。

表值参数参考:

答案 2 :(得分:0)

这是我最终想出来的。当我看到这个时,我可能早先喝过咖啡。它可能仍然可以使用一点点工作,但它应该工作。

protected override int GetCount(List<int> itemlist)
{
    sql.Execute(@"TRUNCATE Table table0");
    int count = 0;

    string sql = @"WITH b AS
                    (
                        {0}
                    )
                    INSERT  INTO table0 (ID, Guid)
                    SELECT ID, Guid
                    FROM b";

    List<string> sqlsubs = new List<string>();

    foreach (int itemgroup in itemlist)
    {
        sqlsub.Add( string.Format(@"SELECT  table1.ID , table1.Guid
                                    FROM    dbo.tablefunction({0}) table1 LEFT JOIN
                                            dbo.table0 ON table1.ID = table0.ID
                                    WHERE   table0.ID IS NULL", itemgroup));
    }

    string sqlunion = string.Join(" UNION ", sqlsub);

    return context.Execute(string.Format(sql, sqlunion));
}