我有一张简单的桌子:
CREATE TABLE [MyTable]
(
[ID] [INT] IDENTITY(1,1) NOT NULL,
[NAME] [NVARCHAR](100) NOT NULL,
[DATA] [NVARCHAR](max) NOT NULL,
CONSTRAINT [PK_MyTable]
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
我有一个存储过程,该存储过程在此表中插入一行并通过PK IDENTITY
返回SCOPE_IDENTITY()
列的值
CREATE PROCEDURE [InsertMyTable]
@NAME NVARCHAR(100),
@DATA NVARCHAR(MAX)
AS
BEGIN
INSERT INTO [MyTable] ([NAME], [DATA])
VALUES (@NAME, @DATA)
RETURN SCOPE_IDENTITY()
END
我已经通过SSMS和其他工具测试了此存储过程,并且其行为符合预期。
每次运行以下脚本时,返回值将增加1:
DELETE FROM [MyTable]
GO
DECLARE @return INT
EXEC @return = [InsertMyTable] @NAME='MyName', @DATA='Data'
SELECT @return
GO
但是,当我使用System.Data.SqlClient
在C#代码中执行类似操作时,存储过程的返回值始终为1。似乎并不能反映出每次删除并重新插入该行后,标识都会增加。
using (var connection = new SqlConnection({connection-string}))
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "delete from [MyTable] where [NAME]='MyName'";
connection.Open();
command.ExecuteNonQuery();
}
using (var connection = new SqlConnection({connection-string}))
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "InsertMyTable";
command.Parameters.Add(new SqlParameter($"@NAME", "MyName"));
command.Parameters.Add(new SqlParameter($"@DATA", "data"));
connection.Open();
var returnValue = command.ExecuteNonQuery();
}
returnValue = 1
returnValue = 1
您的存储过程返回ID作为存储过程返回值,该ID仅应用于成功或失败,而不能用于数据。
[SqlCommand.ExecuteNonQuery()返回已执行批处理的所有行计数消息的总数。
您应该使用输出参数
CREATE PROCEDURE [InsertMyTable]
@NAME NVARCHAR(100)
, @DATA NVARCHAR(MAX)
, @ID INT OUTPUT
AS
BEGIN
INSERT INTO [MyTable]
([NAME]
,[DATA])
VALUES
( @NAME
, @DATA)
set @ID = SCOPE_IDENTITY()
END
或使用结果集,并使用SqlCommand.ExecuteScalar()或SqlCommand.ExecuteReader()获得值。
CREATE PROCEDURE [InsertMyTable]
@NAME NVARCHAR(100)
, @DATA NVARCHAR(MAX)
AS
BEGIN
INSERT INTO [MyTable]
([NAME]
,[DATA])
VALUES
( @NAME
, @DATA)
SELECT SCOPE_IDENTITY() ID
END
您可以通过绑定一个额外的SqlParameter来完成您的工作,但这是一个坏习惯。