C#&;SQL Server:如何添加验证以阻止插入重复的用户名

C#&;SQL Server:如何添加验证以阻止插入重复的用户名,c#,sql,sql-server,C#,Sql,Sql Server,我在windows窗体应用程序中有一个窗体,供管理员用户使用,以便他们可以添加、编辑和删除用户。我遇到的问题是,管理员可以插入一个新用户,该用户与另一个用户具有相同的用户名,这会导致两个用户在登录系统时都具有重复的用户名 我只需要一些基本的验证,这样在用户名重复时就不会插入用户名,但我不确定如何将其添加到dataadapter SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=

我在windows窗体应用程序中有一个窗体,供管理员用户使用,以便他们可以添加、编辑和删除用户。我遇到的问题是,管理员可以插入一个新用户,该用户与另一个用户具有相同的用户名,这会导致两个用户在登录系统时都具有重复的用户名

我只需要一些基本的验证,这样在用户名重复时就不会插入用户名,但我不确定如何将其添加到dataadapter

SqlConnection con = new SqlConnection(@"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|Data.mdf;Integrated Security=True");
con.Open();

SqlDataAdapter sda = new SqlDataAdapter("INSERT INTO Login (FirstName, Role, Username, Password, Surname) VALUES ('" + txtfirstname2.Text + "','" + rolecombo.Text + "','" + txtusername2.Text + "','" + txtpassword2.Text + "','" + txtsurname.Text + "')", con);

sda.SelectCommand.ExecuteNonQuery();
con.Close();

MessageBox.Show("SAVED SUCCESSFULLY !!!!!");

在INSERT查询中添加
WHERE NOT EXISTS
子句以检查用户名是否存在,然后使用
ExecuteNonQuery
(受影响的行数)的返回值确定用户是否已插入。0=>未插入,因为存在重复项。

创建插入触发器或唯一键索引:

大概是这样的:

CREATE TRIGGER MyTrigger ON dbo.MyTable
AFTER INSERT
AS

if exists ( select * from table t 
    inner join inserted i on i.name=t.name and i.date=t.date)
begin
    rollback
    RAISERROR ('Duplicate Data', 16, 1);
end
go

这只是插入,您可能也想考虑更新。

更新

一种更简单的方法是只在表上创建一个唯一的约束,这也将在更新时强制执行该约束,并消除对触发器的需要。只要做:

ALTER TABLE [dbo].[TableName]    
ADD CONSTRAINT [UQ_ID_Name_Date] UNIQUE NONCLUSTERED
(
    [Name], [Date]
)

然后你就可以做生意了。

在数据库中添加一个唯一的约束。还要考虑使用参数化查询……连接到SQL Server的xkcd,这样您就可以向数据库本身添加约束,而不必尝试在代码中执行。在DB中执行此操作意味着无论数据如何访问(即使不是通过应用程序访问),约束仍然适用。好悲伤——在这里和其他地方发表了数百篇关于SQL连接危险的帖子之后,这里又有一张海报在做这件事。在坏习惯根深蒂固之前,在这里快速搜索参数化查询。查找
尝试捕获
——非常容易捕获异常并相应地报告。不过,请注意清理您的代码——使用
语句查看
。不要忽略我们前面的评论——参数化查询很容易实现,而且非常值得投入5分钟的时间。从一开始就努力正确学习,这样以后就不必改掉坏习惯了。:-)如果你从一开始就不吸烟,那么做一个不吸烟的人要容易得多;学习编写正确的代码也是如此。如果您不学习如何编写糟糕的代码并以此为借口编写新代码,那么编写好代码就会容易得多。我尝试了唯一约束方法而不是触发器方法,但当输入重复的用户名时,我会收到关于唯一约束的错误。。虽然这很好,因为这意味着约束正在工作,但我如何添加一个显示而不是错误的messagebox,以便用户可以在应用程序中继续您最可能需要并应该执行try/catch/finally块,并且还有几个堆栈溢出示例: