我想构建一个简单的循环来检查来自SQL服务器的传入数据,将其与文本字段进行比较,如果没有重复项,则执行非查询。
我写了这段代码:
use App\Http\Middleware\CreateInfos;
class ProfileFormsController extends Controller {
public function __construct()
{
$this->middleware('create');
}
我使用断点并看到代码运行while循环很好,但当它到达ExecuteNonQuery命令时,它会返回一条错误消息:
已经有一个与此命令关联的打开的datareader 必须先关闭
我尝试使用try
{
bool exists = false;
conn = new SqlConnection(DBConnectionString);
SqlCommand check_user = new SqlCommand("SELECT usrEmail FROM tblUsers", conn);
SqlCommand add_user = new SqlCommand("INSERT INTO tblUsers (usrEmail, usrPassword, usrRealname, usrIsowner) VALUES (@email, @pass, @name, @owner)", conn);
// (I have removed all the paramaters from this code as they are working and irrelevant)
conn.Open();
SqlDataReader check = check_user.ExecuteReader();
while (check.Read())
{
if (Convert.ToString(check[0]) == UserEmail.Text)
{
MessageBox.Show("The email you entered already exists in the system.");
exists = true;
break;
}
}
if (exists == false)
{
add_user.ExecuteNonQuery();
}
else
{
return;
}
}
catch (Exception ex)
{
MessageBox.Show("There was a problem uploading data to the database. Please review the seller's details and try again. " + ex.Message);
return;
}
finally
{
conn.Close();
}
命令,但是当我这样做时,由于理解原因,它突然遇到重复的电子邮件错误消息。
另外,我尝试了一个修复程序,其中数据实际上是WAS发送到数据库(我在SQL Server Management Studio中看到它),但仍然给出了错误消息......这甚至更奇怪,因为nonquery命令是最后的在这个功能。如果它有效,为什么要去捕获呢?
我在网站上搜索了答案,但最常见的答案是MARS(我不知道那是什么)或数据集,我不想在这种情况下使用。
这里有简单的解决方案吗?我错过了代码中的内容吗?
答案 0 :(得分:1)
简单的出路是:
using(SqlDataReader check = check_user.ExecuteReader())
{
while (check.Read())
{
if (Convert.ToString(check[0]) == UserEmail.Text)
{
MessageBox.Show("The email you entered already exists in the system.");
exists = true;
break;
}
}
}
也就是说,此代码存在一些严重问题。
首先,您并不想阅读所有用户,只是为了检查是否已收到电子邮件地址。 select count(*) from tblUsers where usrEmail = @email
很好......
......或不,因为有可能出现竞争条件。您应该做的是在usrEmail
列上添加一个唯一约束,然后只添加insert into tblUsers
,以捕获违规行为。或者,如果您愿意,可以使用merge
。
接下来,您并不想真正拥有数据访问代码。至少将它分解为单独的类/方法。