c# - SqlDataAdapter.SelectCommand 没有返回正确的结果
问题描述
我只是面临我的代码问题。
我想使用 SqlDataAdapter SelectCommand 属性从数据库中选择一些数据。
我的代码如下所示:
static SqlConnection sqlConnection;
static SqlDataAdapter daDBData = new SqlDataAdapter();
static SqlCommand command = new SqlCommand();
static DataSet dsDBData = new DataSet("DBData");
static DataTable tblDBData;
static DataRow drCurrent;
public static DataTable dbDataGet(string tabname, string where)
{
sqlConnection = dbConnect(); //sqlConnection setup working fine, defined in another method
string helper = "SELECT * FROM " + tabname + where;
command = new SqlCommand(helper, sqlConnection);
daDBData.SelectCommand = command;
daDBData.MissingSchemaAction = MissingSchemaAction.AddWithKey;
daDBData.Fill(dsDBData, tabname);
tblDBData = dsDBData.Tables[tabname];
return tblDBData;
}
我的问题是,在tblDBData
我的数据库表的所有现有行中都将返回。我在这里想念什么?
解决方案
就代码块而言,可以公平地说它需要大量工作。几乎每一行都有一些可以改进的地方,但它所体现的整个概念是相当令人反感的,因为它本质上是一个巨大的安全风险。这是一个稍微改进的版本:
//Don't need any of those static variables. Stop making everything static..
//In a properly structured C# program almost NOTHING should be declared as static
//Method names in C# use PascalCase convention, not camelCase
public DataTable DbDataGet(string tableName, string whereClause)
{
//this could be a massive security risk if there is any way at all that the
//user can influence the contents of the whereClause. DON'T DO IT if they can
SqlDataAdapter da = new SqlDataAdapter(
$"SELECT * FROM {tableName} WHERE {whereClause}",
GetConnectionString() //in this simplistic context, get a string, not a SqlConnection, then you don't handle disposal
);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
是的; 您编写的所有代码归结为只有 4 行。这仍然是一个大问题,你只是在扔一个带有 where 子句的字符串。使用这种方法摆脱这种情况的唯一方法是开始将您的 where 字符串分解为一组谓词类,在列和运算符级别保护 sql 注入,并将值添加到 SqlParameterCollection - 它本质上是滚动您自己的数据访问图书馆,鉴于许多人已经这样做了(包括微软),不值得费心
考虑通过根本不以这种方式访问数据来摆脱这个可怕的兔子洞。把它全部扔进垃圾桶,改用Dapper。从你现在的情况来看,这并不是一个巨大的学习曲线,并且将以更安全、更安全、更易于使用的方式完成所有工作
作为关于 WHERE 子句的注释,您在使用的评论中说:
WHERE DATEDIFF(day, sale_date, GetDate()) >= 365 AND available=1
也不要这样做。在这里,您对表中的数据条目执行函数操作。如果您的表中有一百万个日期,则该函数将需要调用一百万次。它很慢,使用大量资源并削弱了索引的使用。这是完全没有必要的。您正在寻找一年前售出的所有产品?计算一年前的某个日期,并使用SALE_DATE
from th 故事与它相比没有任何改变:
-- in your sql
WHERE sale_date < @someDate and available = 1
//in your c#
mySqlCommand.Parameters.AddWithValue("@someDate", DateTime.UtcNow.AddYears(-1));
看到不同?在这里,c# 计算一次日期,并将其作为常量值参数提供给查询。在包含一百万个日期的表中,只执行一个简单的比较。我们不计算多少天前有一百万个不同的日期,然后只选择那些差异 > 365
推荐阅读
- amazon-web-services - 估计 SQS 处理时间和负载
- angular - Angular 5:如何在子组件中获取父组件路由参数?
- spring - 邮递员 - 查看压缩响应大小的选项..?
- android - API > 22 的 TextInputLayout 线条颜色不会以编程方式更改
- mongodb - 如何制定正确的 mongo 查询以获取正确格式的记录
- javascript - 上传前的javascript预览图像
- python-3.x - 是否有 (void)x;python中的等价物?
- reactjs - 如何将 ReactJS 与 Magento 2 前端集成?
- chef-infra - 使用python比较不同版本的厨师食谱
- r - 在矩阵中使用 R 中的 rbinom 函数