我一直在尝试学习一些基本的SQL,并且一直在处理一个想象中的项目,以便学习绳索。
我的数据库构造如下:
CREATE TABLE [dbo].[People]
(
[Id] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
[SocialSecurityNumber] [nvarchar](13) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[Email] [varchar](50) NOT NULL
)
CREATE TABLE [dbo].[Employees]
(
[Id] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
[EmployeeCode] [varchar](50) NOT NULL,
[PersonId] [int] FOREIGN KEY REFERENCES People (Id) NOT NULL
)
CREATE TABLE [dbo].[Administrators]
(
[Id] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
[AdministratorCode] [varchar](50) NOT NULL,
[EmployeeId] [int] FOREIGN KEY REFERENCES Employees (Id) NOT NULL,
)
我设法执行以下查询:
INSERT INTO Administrators
VALUES ('A001', (SELECT Employees.Id FROM Employees
INNER JOIN People
ON People.Email = @email))
但是当我打电话给这个程序时:
CREATE PROCEDURE [dbo].[InsertNewAdministrator]
(
@email VARCHAR(50),
@administratorCode VARCHAR(50)
)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO Administrators
VALUES (@administratorCode, (SELECT Employees.Id
FROM Employees
INNER JOIN People ON People.Email = @email))
END
使用此代码:
(p变量是类的一个实例"管理员"发送给方法。管理员继承自人)。
using (var conn = new SqlConnection(connectionString))
using (var command = new SqlCommand(procedureName, conn))
{
if (procedureName == "InsertNewAdministrator")
{
var a = p as Administrator;
command.Parameters.Add(new SqlParameter("@administratorCode", a.AdministratorCode));
}
else if (procedureName == "InsertNewEmployee")
{
...
}
else
{
...
}
command.Parameters.Add(new SqlParameter("@email", p.Email));
command.CommandType = CommandType.StoredProcedure;
conn.Open();
command.ExecuteNonQuery();
}
我收到以下错误:
违反UNIQUE KEY约束' UQ__Employee__7AD04F1040881669'。"
(显然是employeeCode
。)
我只是不明白为什么。 SQL总是按预期添加一个新的管理员,但异常使我的业务逻辑崩溃。
现在我的代码只是吞下了一个空的捕捉......但我仍然知道它在那里......潜伏......
任何人都知道为什么?
答案 0 :(得分:2)
Administrators
有三列。当你写:
INSERT INTO Administrators
VALUES ('A001', (SELECT Employees.Id FROM Employees
INNER JOIN People
ON People.Email=@email))
你真的在写Administrators(ID, AdministratorCode, EmployeeId)
。我不知道为什么当你运行它时它会起作用。你错过了一个专栏。
相反,当您使用insert
时,请始终列出列(除此之外偶尔会有列,但绝对不是在这个简单的情况下)。因为第一列是标识,所以您不需要分配它。
其次,您的join
在两个表之间缺少join
条件。通常,on
子句中的两个表之间至少应有一个相等条件。这不是必需的,也有例外,但对于像这样的简单情况,请记住规则。
您还应该学习insert . . . select
语法 - 它比insert . . . values
更强大。我猜你打算:
INSERT INTO Administrators(AdministratorCode, EmployeeId)
SELECT 'A001', e.Id
FROM Employees e INNER JOIN
People p
ON p.id = e.PersonId
WHERE p.Email = @email;
答案 1 :(得分:0)
在编写C#时,我似乎犯了一个逻辑错误。
if (person is Administrator)
{
NewPersonProcedureCall("InsertNewAdministrator", person);
}
if (person is Employee)
{
NewPersonProcedureCall("InsertNewEmployee", person);
}
因此,在创建员工后立即调用我的方法。快速修复。
if (person is Administrator)
{
NewPersonProcedureCall("InsertNewAdministrator", person);
}
else if (person is Employee)
{
NewPersonProcedureCall("InsertNewEmployee", person);
}
因此,员工存在,验证错误是合乎逻辑的。对不起人!