我有一个存储过程调用DvdInsert
看起来像这样:的SQL Server SCOPE_IDENTITY存储过程返回null在C#
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)
)
我不明白为什么我没有从s中获得回报价值tored程序。有任何想法吗?我是初学者,所以如果愿意,请打破你的解释。
非常感谢您的帮助。
I have a screenshot of the error I receive in postman if that helps click here
我邮编:
[Route("dvd/")]
[AcceptVerbs("POST")]
public IHttpActionResult Add(DvdItem dvdItem)
{
repo.Insert(dvdItem);
return Created($"dvd/{dvdItem.DvdId}", dvdItem);
}
我碰到一个错误信息,同时调试,上面写着:“System.Data.SqlClient.SqlException:“子查询返回多个值这是当子查询如下=,!=,<,< =,>,> =,或当子查询用作表达。 该语句已终止。”'
不允许
这只是一个黑暗中的镜头,但我的问题可能与我插入新导演的子查询有关吗?
你为什么试图在单元测试中与数据库交谈? – Shyju
@Shyju,这是错误的吗?我的答案会是因为我的教练向我展示了这种方式并用于测试目的,但通过您的问题,我认为这是错误的方式? – Student
为什么你不能在sp中选择scope_identity()并调用sp来理解它是否返回正确的值。 –