更新的问题:有没有办法强制数据适配器只接受不包含任何更新/删除/创建/删除/插入命令的命令,而不是在发送到数据适配器之前验证 command.text(否则抛出异常)。dot net 在 datareader dataadapter 或任何其他中是否提供了任何此类内置功能?
注意:DataReader 返回结果它也接受更新查询并返回结果。(我可能会遗漏一些错误,但我在执行阅读器之前显示我的更新命令,然后在成功后显示消息,一切正常
更新的问题:有没有办法强制数据适配器只接受不包含任何更新/删除/创建/删除/插入命令的命令,而不是在发送到数据适配器之前验证 command.text(否则抛出异常)。dot net 在 datareader dataadapter 或任何其他中是否提供了任何此类内置功能?
注意:DataReader 返回结果它也接受更新查询并返回结果。(我可能会遗漏一些错误,但我在执行阅读器之前显示我的更新命令,然后在成功后显示消息,一切正常
你能在字符串中搜索一些关键字吗?像 CREATE、UPDATE、INSERT、DROP 或者查询不以 SELECT 开头?还是这太脆弱了?
您可能还想为此创建一个应用程序使用的仅具有读取功能的登录。我不知道该对象是否具有该属性,但您可以让服务器拒绝交易。
如果您只想要一个 DataTable,那么以下方法很短并且降低了复杂性:
public DataTable GetDataForSql(string sql, string connectionString)
{
using(SqlConnection connection = new SqlConnection(connectionString))
{
using(SqlCommand command = new SqlCommand())
{
command.CommandType = CommandType.Text;
command.Connection = connection;
command.CommandText = sql;
connection.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
DataTable data = new DataTable();
data.Load(reader);
return data;
}
}
}
}
用法:
try{
DataTable results = GetDataForSql("SELECT * FROM Table;", ApplicationSettings["ConnectionString"]);
}
catch(Exception e)
{
//Logging
//Alert to user that command failed.
}
这里实际上不需要使用 DataAdapter - 它并不是真正的你想要的。如果使用了更新、删除或插入命令,为什么还要费心去捕捉异常等?它不适合您想做的事情。
重要的是要注意SelectCommand 属性没有做任何特殊的事情 - 当 SelectCommand 被执行时,它仍然会运行传递给它的任何命令 - 它只期望返回一个结果集,如果没有返回结果,那么它返回一个空数据集。
这意味着(无论如何您都应该这样做)您应该明确地仅授予您希望人们能够查询的表的SELECT 权限。
编辑
要回答您的另一个问题,SqlDataReader是ReadOnly
因为它们通过只读的 firehose 样式游标工作。这实际上意味着:
while(reader.Read()) //Reads a row at a time moving forward through the resultset (`cursor`)
{
//Allowed
string name = reader.GetString(reader.GetOrdinal("name"));
//Not Allowed - the read only bit means you can't update the results as you move through them
reader.GetString(reader.GetOrdina("name")) = name;
}
它是只读的,因为它不允许您在浏览记录时更新记录。但是,他们执行以获取结果集的 sql 没有理由无法更新数据。
您需要做的就是确保没有为DataAdapter
. 您的代码可能如下所示:
var dataAdapter = new SqlDataAdapter("SELECT * FROM table", "connection string");
或者
var dataAdapter = new SqlDataAdapter("SELECT * FROM table", sqlConnectionObject);
而且,你有一个只读数据适配器。
如果您有只读要求,请让您的 TextBox 使用连接字符串,该连接字符串使用的帐户仅对 SQL 数据库具有 db_datareader 权限。
否则,是什么阻止了正在使用您的控制权的开发人员仅连接到数据库并自行使用 SqlCommand 造成严重破坏?