我有一个名为的存储过程DvdInsert
,如下所示:
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = 'DvdInsert')
DROP PROCEDURE DvdInsert
GO
CREATE PROCEDURE DvdInsert
(@RatingName char(10),
@FName nvarchar(30),
@LName nvarchar(30),
@Title nvarchar(125),
@ReleaseYear int,
@Notes nvarchar(150),
@DvdId int OUTPUT)
AS
BEGIN
INSERT INTO Director (FName, LName)
VALUES (@FName, @LName)
INSERT INTO Dvd (DirectorId, RatingId, Title, ReleaseYear, Notes)
VALUES ((SELECT DirectorId
FROM Director
WHERE FName = @FName AND LName = @LName),
(SELECT RatingId
FROM Rating
WHERE RatingName = @RatingName), @Title, @ReleaseYear, @Notes)
SET @DvdId = CAST(SCOPE_IDENTITY() AS INT);
END
GO
它应该返回 ID 号,但在 Visual Studio 2017 中我有代码:
public int Insert(DvdItem dvdItem)
{
using (var cn = new SqlConnection(Settings.GetConnectionString()))
{
SqlCommand cmd = new SqlCommand("DvdInsert", cn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter("@DvdId", SqlDbType.Int);
param.Direction = ParameterDirection.Output;
cmd.Parameters.Add(param);
string[] names = dvdItem.Director.ToString().Trim().Split(new char[]
{ ' ' }, 2);
if (names.Length == 1)
{
cmd.Parameters.AddWithValue("FName", "");
cmd.Parameters.AddWithValue("LName", names[0]);
}
else
{
cmd.Parameters.AddWithValue("FName", names[0]);
cmd.Parameters.AddWithValue("LName", names[1]);
}
cmd.Parameters.AddWithValue("RatingName", dvdItem.Rating);
cmd.Parameters.AddWithValue("Title", dvdItem.Title);
cmd.Parameters.AddWithValue("ReleaseYear", dvdItem.RealeaseYear);
cmd.Parameters.AddWithValue("Notes", dvdItem.Notes);
cn.Open();
int i = 0;
object a = cmd.ExecuteScalar();
if (a != null)
i = (int)a;
if (cn.State == System.Data.ConnectionState.Open)
cn.Close();
return i;
}
}
我有一个 Nunit 测试来验证功能,但在调试模式下我得到返回值 0 而不是 4
我的测试代码:
[Test]
public void CanAddDvd()
{
DvdItem dvdItem = new DvdItem();
var repo = new DvdRepositoryADO();
dvdItem.Rating = "R";
dvdItem.Director = "Hello";
dvdItem.Title = "World";
dvdItem.RealeaseYear = "2004";
dvdItem.Notes = "TESTING";
repo.Insert(dvdItem);
Assert.AreEqual(4, dvdItem.DvdId);
}
在我添加之前:
int i = 0;
object a = cmd.ExecuteScalar();
if (a != null)
i = (int)a;
if (cn.State == System.Data.ConnectionState.Open)
cn.Close();
我在这里得到一个空引用异常:
object a = cmd.ExecuteScalar();
我在 SQL Server 中的表如下所示:
CREATE TABLE Dvd
(
DvdId INT NOT NULL IDENTITY(1,1),
DirectorId INT NOT NULL,
RatingId INT NOT NULL,
Title NVARCHAR(125) NOT NULL,
ReleaseYear int NOT NULL,
Notes VARCHAR(150) NULL,
CONSTRAINT PK_Dvd_DvdId PRIMARY KEY (DvdId),
CONSTRAINT FK_Dvd_DirectorId
FOREIGN KEY (DirectorId) REFERENCES Director(DirectorId),
CONSTRAINT FK_Dvd_RatingId
FOREIGN KEY (RatingId) REFERENCES Rating(RatingId)
)
我不明白为什么我没有从存储过程中获取返回值。有任何想法吗?我是初学者,所以如果愿意,请分解您的解释。
预先感谢您的帮助。
如果有帮助,我有我在邮递员中收到的错误的屏幕截图,请单击此处
我的邮政编码:
[Route("dvd/")]
[AcceptVerbs("POST")]
public IHttpActionResult Add(DvdItem dvdItem)
{
repo.Insert(dvdItem);
return Created($"dvd/{dvdItem.DvdId}", dvdItem);
}
我在调试时遇到一条错误消息,上面写着“System.Data.SqlClient.SqlException:'子查询返回的值超过 1 个。当子查询遵循 =、!=、<、<=、>、>= 时,这是不允许的或当子查询用作表达式时。语句已终止。'"
这只是在黑暗中拍摄,但我的问题可能与我插入新导演的子查询有关吗?