SQLCommand.ExecuteReader() 不限制只读语句
显然,ExecuteReader 用于只读,而 ExecuteNonQuery 用于事务。但由于某种原因,即使我使用 ExecuteReader,我仍然能够运行写入(插入、更新、删除)命令(在 textbox1 中键入)。我的代码有问题还是我误解了 ExecuteReader 的工作方式?
//MY CODE
string sqlStatement = textbox1.Text;
System.Data.SqlClient.SqlConnectionStringBuilder builder =
new System.Data.SqlClient.SqlConnectionStringBuilder();
builder.DataSource = ActiveServer;
builder.IntegratedSecurity = true;
System.Data.SqlClient.SqlConnection Connection = new
System.Data.SqlClient.SqlConnection(builder.ConnectionString);
Connection.Open();
System.Data.SqlClient.SqlCommand command = new
System.Data.SqlClient.SqlCommand(sqlStatement, Connection);
System.Data.SqlClient.SqlDataReader reader = command.ExecuteReader();
dataGridView1.AutoGenerateColumns = true;
bindingSource1.DataSource = reader;
dataGridView1.DataSource = bindingSource1;
reader.Close();
Connection.Close();
So apparently, ExecuteReader is used for read only and ExecuteNonQuery is used for transactions. But for some reason even when I used ExecuteReader I am still able to run write (Insert, Update, Delete) commands (typed in textbox1). Is there something wrong with my code or am I misunderstanding the way ExecuteReader is supposed to work?
//MY CODE
string sqlStatement = textbox1.Text;
System.Data.SqlClient.SqlConnectionStringBuilder builder =
new System.Data.SqlClient.SqlConnectionStringBuilder();
builder.DataSource = ActiveServer;
builder.IntegratedSecurity = true;
System.Data.SqlClient.SqlConnection Connection = new
System.Data.SqlClient.SqlConnection(builder.ConnectionString);
Connection.Open();
System.Data.SqlClient.SqlCommand command = new
System.Data.SqlClient.SqlCommand(sqlStatement, Connection);
System.Data.SqlClient.SqlDataReader reader = command.ExecuteReader();
dataGridView1.AutoGenerateColumns = true;
bindingSource1.DataSource = reader;
dataGridView1.DataSource = bindingSource1;
reader.Close();
Connection.Close();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
ExecuteReader
只是返回一个读取器,该读取器可以读取从 SQL 过程返回的行 - 它不会阻止您在提供该结果集的过程中运行任意 SQL。执行插入/更新/删除,然后立即返回结果集(因此从看起来像读取的代码来看)可以说有点奇怪(读取:代码气味),应该进行审查以查看是否可以将其拆分为不同的操作。
ExecuteReader
simply returns a reader that can read rows returned from a SQL procedure - it doesn't stop you from running arbitrary SQL on the way to providing that result set.Doing inserts / updates / deletes and then immediately returning a result set (so from code looking like a read) is arguably a little odd (read: code smell), and should be reviewed to see if it can be split into distinct actions.
尽管两者都执行 SQL,但
ExecuteReader
预计会返回记录,而ExecuteNonQuery
受影响的记录数。因此,两者是不同的。但在内部,它们的不同程度取决于供应商的特定实现。您可以单独使用 ExecuteReader 来执行所有数据库操作因为它刚刚工作(到目前为止),但由于它没有记录它并不是真正正确的方法< /em>.通过ExecuteNonQuery
,您可以更清楚地了解您的意图。就性能而言,我认为根本没有区别。我尝试使用
SQLite
、MySqlClient
、SqlClient
、SqlServerCe
和VistaDb
并没有看到明显的差异有利于任何一个。他们都应该以某种方式在内部使用 ExecuteReader。要点:
SqlClient:
和
MySqlClient:
如您所见,
MySqlClient
直接调用ExecuteReader
,而SqlClient
仅在某些条件下调用。 请注意,insert
和update
很少是瓶颈(通常是select
)。正如我所说,在 ExecuteReader 的帮助下您不会获得受影响的行数,因此最好使用 ExecuteNonQuery 来执行查询。
ExecuteReader
更直接的替换是ExecuteScalar
,它返回读取的第一行的第一列中的数据。要点:
SqlClient:
和
MySqlClient :
所以使用
ExecuteReader
进行ExecuteScalar
并没有什么坏处,并且没有任何性能差异。Though both executes the sql,
ExecuteReader
is expected to return records whileExecuteNonQuery
number of records affected. Both are different hence. But internally how different they are would depend on vendor specific implementation. You could useExecuteReader
alone for all your db actions because it just worked (until now) but since its not documented its not really the right approach to go for. You could be more clear about your intent withExecuteNonQuery
.As far as performance is considered I don't think there's a difference at all. I tried with
SQLite
,MySqlClient
,SqlClient
,SqlServerCe
andVistaDb
and saw no noticeable difference to favour either. And they all should useExecuteReader
internally one way or other.The essentials:
SqlClient:
and
MySqlClient:
As you can see
MySqlClient
directly callsExecuteReader
whileSqlClient
does only for certain conditions. Mind youinsert
s andupdate
s are rarely the bottleneck (its often theselect
s).As I said you wouldn't get the number of rows affected with the help of
ExecuteReader
, so useExecuteNonQuery
better to execute queries. A more direct replacement byExecuteReader
would be ofExecuteScalar
which returns the data in first column of first row read.The essentials:
SqlClient:
and
MySqlClient:
So it doesn't hurt to use
ExecuteReader
forExecuteScalar
and no performance difference whatsoever..这些方法的底层实现只是执行给定的 SQL 语句,因此您可以使用这些方法中的任何一个来运行几乎任何语句。只是最终的结果是一个读者试图返回一个期望的结果集,而另一个方法并不期望返回一个结果集。使用 ExecuteReader 运行不生成结果集的语句可能效率稍低。提供者仍然会创建一个数据读取器对象,这会增加一点成本(在大多数情况下可能可以忽略不计,除非提供者最终对服务器进行另一个往返调用)。
The underlying implementation of those methods simply executes the given SQL statement, so you can run pretty much any statement with any of those methods. It's just that the end result is that a reader tries to return an expected result set, while the other method does not expect a result set. It is probably a little less efficient to use ExecuteReader to run a statement that does not produce a result set. The provider will still create a data reader object, which would add a little bit of cost (probably negligible in most cases unless the provider ends up making another round-trip call to the server).