【发布时间】:2016-09-20 11:00:24
【问题描述】:
我有一个包含 ID 的列表,我想使用 Dapper 将其插入到临时表中,以避免“IN”子句中参数的 SQL 限制。
所以目前我的代码如下所示:
public IList<int> LoadAnimalTypeIdsFromAnimalIds(IList<int> animalIds)
{
using (var db = new SqlConnection(this.connectionString))
{
return db.Query<int>(
@"SELECT a.animalID
FROM
dbo.animalTypes [at]
INNER JOIN animals [a] on a.animalTypeId = at.animalTypeId
INNER JOIN edibleAnimals e on e.animalID = a.animalID
WHERE
at.animalId in @animalIds", new { animalIds }).ToList();
}
}
我需要解决的问题是,当animalIds列表中的id超过2100个时,我得到一个SQL错误“传入的请求参数太多。服务器最多支持2100个参数”。
所以现在我想创建一个临时表,其中填充了传递给方法的 animalIds。然后我可以在临时表上加入动物表,避免出现巨大的“IN”子句。
我尝试了各种语法组合,但没有成功。 这就是我现在的位置:
public IList<int> LoadAnimalTypeIdsFromAnimalIds(IList<int> animalIds)
{
using (var db = new SqlConnection(this.connectionString))
{
db.Execute(@"SELECT INTO #tempAnmialIds @animalIds");
return db.Query<int>(
@"SELECT a.animalID
FROM
dbo.animalTypes [at]
INNER JOIN animals [a] on a.animalTypeId = at.animalTypeId
INNER JOIN edibleAnimals e on e.animalID = a.animalID
INNER JOIN #tempAnmialIds tmp on tmp.animalID = a.animalID).ToList();
}
}
我无法让 SELECT INTO 与 ID 列表一起使用。我是不是走错了路,也许有更好的方法来避免“IN”子句限制。
我确实有一个备份解决方案,我可以将传入的 animalID 列表拆分为 1000 个块,但我读到大的“IN”子句会受到性能影响,加入临时表会更有效率,而且也意味着我不需要额外的“拆分”代码来将 id 分成 1000 个块。
【问题讨论】:
-
INSERT INTO语句在哪里? -
2100 个值是一个非常大的数字。足够大,应该将它们存储在具有适当索引的 自己的 表中。这些价值观从何而来?它们是查询的结果吗?那么为什么不包含在 SELECT 语句中呢?还是它们来自外部来源,例如 CSV 文件?那么最好的选择是将文件导入临时表,然后加入该表
-
它们来自 CSV
-
然后将它们导入一个表并加入它,例如使用
bcp、BULK INSERT或SSIS。您还可以使用SqlBulkCopy 类将行从客户端批量发送到服务器。
标签: c# sql-server dapper