C# 如何使用特定约束将记录保存到SQL Server?
我正在使用SQL server 2008和C。例如,可以使用一个或多个员工ID注册临时类型票证。但我只希望每个员工注册一个永久类型票证 下表显示第二条记录注册不正确。那么我如何处理这些约束呢C# 如何使用特定约束将记录保存到SQL Server?,c#,sql-server-2008,C#,Sql Server 2008,我正在使用SQL server 2008和C。例如,可以使用一个或多个员工ID注册临时类型票证。但我只希望每个员工注册一个永久类型票证 下表显示第二条记录注册不正确。那么我如何处理这些约束呢 +-------+--------+----------+-----------+ | empid | userid | ticketNo | ticketType| +-------+--------+----------+-----------+ | 1 | admin | 10
+-------+--------+----------+-----------+
| empid | userid | ticketNo | ticketType|
+-------+--------+----------+-----------+
| 1 | admin | 10 | Permanent |
| 1 | admin | 11 | Permanent |
| 2 | admin | 12 | Temporary |
+-------+--------+----------+-----------+
我尝试了以下方法,但没有按需要工作
private void CheckandBlockEmp()
{
SqlConnection conn = new SqlConnection(dbcon.ReturnConnection());
string commText = "select EmpID from ItemTicketSection where ticketType='Permanent'";
SqlCommand cmdCheck = new SqlCommand(commText, conn);
conn.Open();
var check = cmdCheck.ExecuteScalar();
if (check != null)
{
MessageBox.Show("Permanent type ticket is allowed only ones per Employee!");
return;
}
}
例如,有效的TicketNo登记表:
+-------+--------+----------+-----------+
| empid | userid | ticketNo |ticketType |
+-------+--------+----------+-----------+
| 1 | admin | 10 | Permanent |
| 2 | admin | 12 | Temporary |
| 2 | admin | 13 | Permanent |
| 1 | admin | 14 | Temporary |
+-------+--------+----------+-----------+
如果您需要检查是否有一个已注册永久票证的EmpID,那么您可以将方法更改为
private bool CheckandBlockEmp(int empID)
{
string commText = @"IF EXISTS (SELECT 1 FROM ItemTicketSection
WHERE [Type]='Permanent' AND EmpID=@id)
SELECT 1 ELSE SELECT 0";
using(SqlConnection conn = new SqlConnection(dbcon.ReturnConnection()))
using(SqlCommand cmdCheck = new SqlCommand(commText, conn))
{
conn.Open();
cmdCheck.Parameters.Add("@id", SqlDbType.Int).Value = empID;
var check = cmdCheck.ExecuteScalar();
if (check != null)
{
int num = Convert.ToInt32(check);
return (num == 0);
}
else
return true;
}
}
我改变了一点你的逻辑。现在,如果传递给该方法的EmpID没有注册“永久”票证,则该方法返回0,否则返回1。
通过这种方式,调用代码决定是否可以安全地为该特定EmpID注册带有永久票证标志的记录
正如其他答案所说,添加一个独特的索引将确保业务规则的一致性,但是,如果您想在尝试保存记录之前检查并通知用户,则需要这样的代码来验证您的表如果您需要检查是否有已注册永久票证的EmpID,则可以将方法更改为
private bool CheckandBlockEmp(int empID)
{
string commText = @"IF EXISTS (SELECT 1 FROM ItemTicketSection
WHERE [Type]='Permanent' AND EmpID=@id)
SELECT 1 ELSE SELECT 0";
using(SqlConnection conn = new SqlConnection(dbcon.ReturnConnection()))
using(SqlCommand cmdCheck = new SqlCommand(commText, conn))
{
conn.Open();
cmdCheck.Parameters.Add("@id", SqlDbType.Int).Value = empID;
var check = cmdCheck.ExecuteScalar();
if (check != null)
{
int num = Convert.ToInt32(check);
return (num == 0);
}
else
return true;
}
}
我改变了一点你的逻辑。现在,如果传递给该方法的EmpID没有注册“永久”票证,则该方法返回0,否则返回1。
通过这种方式,调用代码决定是否可以安全地为该特定EmpID注册带有永久票证标志的记录
正如其他答案所说,添加唯一索引将确保业务规则的一致性,但如果您想在尝试保存记录之前检查并通知用户,则需要这样的代码来验证表,最好的解决方案将是筛选唯一索引。它将仅拒绝永久类型的重复EMP:
CREATE UNIQUE NONCLUSTERED INDEX [IDX_Indexname] ON ItemTicketSection
(
[empid] ASC
)
WHERE ([Type]=('Permanent'))
最佳解决方案将被筛选为唯一索引。它将仅拒绝永久类型的重复EMP:
CREATE UNIQUE NONCLUSTERED INDEX [IDX_Indexname] ON ItemTicketSection
(
[empid] ASC
)
WHERE ([Type]=('Permanent'))
您的列名不是ticketType类型。您应该将查询更改为select EmpID from ITEMTICKTSECTION,其中类型为“Permanent”。在sql代码中,创建一个标量函数,然后在检查约束中使用它来限制插入操作期间的多个输入。这与C无关。这完全可以在SQL中完成。您的列名是Type而不是ticketType。您应该将查询更改为select EmpID from ITEMTICKTSECTION,其中类型为“Permanent”。在sql代码中,创建一个标量函数,然后在检查约束中使用它来限制插入操作期间的多个输入。这与C无关。它完全可以在SQL中完成。我想说,这种方法可能会有一些性能问题,如果您使用的方法可以在第一次遇到所需值时中断,那就更好了。性能明智是的,针对这种情况有很多解决方案。例如,你可以使用IF EXISTS,我想说这个方法可能会有一些性能问题,如果你使用的方法可以在第一次遇到期望值时中断,那就更好了。性能明智是的,针对这种情况有很多解决方案。您可以使用IF EXISTS(如果存在),例如问题已解决。你能告诉我它在内部做什么吗?我能在触发事件时将我自己的异常添加到上述唯一索引中吗?正如我在回答中所说的,这是empid列上的索引,当type=Permanent时,它将强制empid列上的唯一性。是的,您可以进一步编辑该谓词。例如,如果[Type]=“Permanent”和userid“Admin”-Admin可以添加重复的永久类型,其他人就不能这样做。问题已经解决。你能告诉我它在内部做什么吗?我能在触发事件时将我自己的异常添加到上述唯一索引中吗?正如我在回答中所说的,这是empid列上的索引,当type=Permanent时,它将强制empid列上的唯一性。是的,您可以进一步编辑该谓词。例如,如果[Type]=“Permanent”和userid“Admin”-Admin可以添加重复的永久类型,则其他人不能这样做。