[英]What is the best way to insert Bulk Xml (XElement) data to Sql server Table using C#?
[英]What is the best way to check if a record exists in a SQL Server table using C#?
什么是最好的方法? 获得1或0回? 或者检查查询中是否有行可用? 我在为ExecuteScalar辩护,但对其他答案感兴趣为什么或为什么不这样做。
//using DataReader.HasRows?
bool result = false;
var cmd = new SqlCommand("select foo, bar from baz where id = 123", _sqlConnection, _sqlTransaction);
cmd.CommandType = System.Data.CommandType.Text;
using (var r = cmd.ExecuteReader())
{
if (r != null && r.HasRows)
{
result = true;
}
}
return result;
//or using Scalar?
bool result = false;
var cmd = new SqlCommand("if exists(select foo, bar from baz where id = 123) select 1 else select 0", _sqlConnection, _sqlTransaction);
cmd.CommandType = System.Data.CommandType.Text;
int i = (int) cmd.ExecuteScalar();
result = i == 1;
return result;
存在比Count更有效,因为count需要扫描所有行以匹配条件并包含在count中,不存在。
所以ExecuteScalar存在更好。
随着更多信息支持这个:
根据http://sqlblog.com/blogs/andrew_kelly/archive/2007/12/15/exists-vs-count-the-battle-never-ends.aspx
两个查询都扫描了表,但是EXISTS至少能够对它在找到第一个匹配行后可以停止的事件进行部分扫描。 其中COUNT( )必须读取整个表中的每一行,以确定它们是否符合条件以及有多少条件。 这是关键人物。 在符合WHERE子句条件的第一行之后停止工作的能力使得EXISTS如此高效。 优化器知道这种行为并且也可以将其考虑在内。 现在请记住,与现实世界中的大多数数据库相比,这些表格相对较小。 因此,对于较大的表,COUNT( )查询的数字将成倍增加。 您可以轻松地在具有数百万行的表上获得数百次或更多次读取,但EXISTS仍然只能对可以使用索引来满足WHERE子句的任何查询进行一些读取。
作为使用AdventureWorks和MSSQL 2012的简单实验
set showplan_all on
-- TotalSubtreeCost: 0.06216168
select count(*) from sales.Customer
-- TotalSubtreeCost: 0.003288537
select 1 where exists (select * from sales.Customer)
也可以看看
http://sqlmag.com/t-sql/exists-vs-count
更新:在ExecuteScalar vs ExecuteReader上。 在System.Data.SqlClient.SqlCommand方法的实现上看一下反汇编程序(如Reflector),显示了一些令人惊讶的东西,它们是等价的:最终调用内部帮助程序内部SqlDataReader RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior, bool returnStream,string方法,TaskCompletionSource完成,int超时,out任务任务,bool asyncWrite = false)
返回一个SqlDataReader,ExecuteReader按原样返回它。 而ExecuteScalar使用另一个帮助器来使用它:
private object CompleteExecuteScalar(SqlDataReader ds, bool returnSqlValue)
{
object obj2 = null;
try
{
if (!ds.Read() || (ds.FieldCount <= 0))
{
return obj2;
}
if (returnSqlValue)
{
return ds.GetSqlValue(0);
}
obj2 = ds.GetValue(0);
}
finally
{
ds.Close();
}
return obj2;
}
作为旁注,与MySQL Connector / NET(MySQL的官方ADO.NET开源驱动程序)相同,方法ExecuteScalar在内部创建DataReader(MySqlDataReader更精确)并使用它。 请参阅源文件/Src/Command.cs(来自https://dev.mysql.com/downloads/connector/net/或https://github.com/mysql/mysql-connector-net )。
简介:关于ExecuteScalar vs ExecuteReader都会产生创建SqlDataReader的开销,我会说差异主要是惯用的。
我会使用像if exists
的查询来使用ExecuteScalar
。 它应该在服务器上尽可能快,并且网络流量最小。
如果你只关心存在,我会使用标量方法,但也将TSQL更新为:
SELECT CASE WHEN EXISTS(SELECT ...) THEN 1 ELSE 0 END
我会使用ExecuteScalar
稍微不同的查询:
string sql = "SELECT CASE WHEN exists(select NULL from baz where id = 123) THEN 1 ELSE 0 END";
var cmd = new SqlCommand(sql, _sqlConnection, _sqlTransaction);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.