所以我正在尝试学习如何使用存储过程,并且在很大程度上我有点理解除了这个合并过程之外如何使用它们。
我想要做的是使用MERGE过程插入如果一行尚不存在并返回ID ELSE IF NOT EXISTS然后只返回ID。
目前这是我目前所拥有的。
CREATE PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),
@LastName nvarchar(50),
@id int = NULL OUTPUT
AS
MERGE Authors AS target
USING (SELECT @FirstName, @LastName) AS source (FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN MATCHED THEN
UPDATE
SET @id = SCOPE_IDENTITY()
WHEN NOT MATCHED THEN INSERT
(FirstName, LastName) VALUES (source.FirstName, source.LastName);
SET @id = SCOPE_IDENTITY()
就将值/信息输入数据库并查找现有数据而言,一切正常,但我没有正确地恢复我的ID值。这是我使用它的方法..
private static int storeAuthors(string firstName, string lastName)
{
String commandText = "dbo.authors_InsertOrUpdate";
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["AmazonCrawler.Properties.Settings.database"].ToString()))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@FirstName", firstName));
command.Parameters.Add(new SqlParameter("@LastName", lastName));
SqlParameter authorId = new SqlParameter("@id", SqlDbType.Int);
authorId.Direction = ParameterDirection.Output;
command.Parameters.Add(authorId);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
return Convert.ToInt32(authorId.Value);
}
}
}
请帮我解决这个问题!
提前致谢。
--------- EDIT ------------
更新了此过程,但当我尝试返回值时,我仍然在代码中收到空值
CREATE PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),
@LastName nvarchar(50),
@id int OUTPUT
AS
MERGE Authors AS target
USING (SELECT @id, @FirstName, @LastName) AS source (id, FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN NOT MATCHED THEN
INSERT (FirstName, LastName) VALUES (source.FirstName, source.LastName);
SET @id = SCOPE_IDENTITY()
编辑参考1
编辑参考2
编辑参考3
ALTER PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),
@LastName nvarchar(50),
@id int OUTPUT
AS
MERGE Authors AS target
USING (SELECT @id, @FirstName, @LastName) AS source (ID, FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN MATCHED THEN
UPDATE SET @id = target.ID
WHEN NOT MATCHED THEN
INSERT (FirstName, LastName) VALUES (source.FirstName, source.LastName);
SET @id = SCOPE_IDENTITY()
SELECT @id
仍然收到参考文献2中列出的相同错误。 =(还没有解决方案。
这是我传入的值,返回零作为id
这是我的数据库
编辑参考4
尝试在将值添加到此时更改我的参数,因为我认为在获取值之前关闭它会导致问题但没有运气
private static int storeAuthors(string firstName, string lastName)
{
String commandText = "dbo.authors_InsertOrUpdate";
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["AmazonCrawler.Properties.Settings.database"].ToString()))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@FirstName", firstName));
command.Parameters.Add(new SqlParameter("@LastName", lastName));
SqlParameter authorId = new SqlParameter("@id", SqlDbType.Int);
authorId.Direction = ParameterDirection.Output;
command.Parameters.Add(authorId);
connection.Open();
command.ExecuteNonQuery();
int value = Convert.ToInt32(authorId.Value);
connection.Close();
return value;
}
}
}
答案 0 :(得分:1)
在UPDATE情况下,您不会生成新的IDENTITY,您只是查询,因此SCOPE_IDENTITY()不会返回正确的值。在UPDATE的情况下,SCOPE_IDENTITY()似乎可能起作用,但它实际上是从范围内的最后一个INSERT返回值(我认为),这可能是存储过程的最后一次执行。
我建议使用OUTPUT子句。我尝试用你的方法制作一些东西,并且使用@ usr的建议,但我唯一能做的工作就是使用OUTPUT子句。见下文:
CREATE PROCEDURE dbo.authors_InsertOrUpdate
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),
@LastName nvarchar(50),
@id int OUTPUT
AS BEGIN
DECLARE @MergeOutput table
(
ACTION VARCHAR(10),
ID INT
);
MERGE Authors AS target
USING (SELECT @id, @FirstName, @LastName) AS source (id, FirstName, LastName)
ON target.FirstName = source.FirstName AND target.LastName = source.LastName
WHEN NOT MATCHED THEN
INSERT (FirstName, LastName) VALUES (source.FirstName, source.LastName)
WHEN MATCHED THEN UPDATE
SET @Id = target.Id
OUTPUT $action, INSERTED.ID INTO @MergeOutput;
SELECT @Id = Id FROM @MergeOutput
END
GO
DECLARE @id2 INT
exec dbo.authors_InsertOrUpdate 'Melvin', 'Smith', @id = @id2 OUTPUT
SELECT @id2
GO
我尝试使用SCOPE_IDENTITY()创建一些工作,并使用SET @Id = target.Id,就像在@usr的答案中一样,但我仍然会返回最后插入的值,即使是更新。
答案 1 :(得分:1)
SELECT * INTO #o FROM sys.objects
DECLARE @id INT
MERGE #o AS target
USING (SELECT OBJECT_ID('tempdb..#o') AS object_id) AS source (object_id)
ON target.object_id = source.object_id
WHEN MATCHED THEN UPDATE SET @id = target.object_id;
SELECT @id
您可以非常自由地使用MERGE
查询的列。这是一个非常有力的声明。