我正在处理一个遗留项目,需要插入一行并返回该行或它的标识。
使用正确的值插入新行,当数据集返回.net时,数据集中不会返回任何内容。
我已尝试选择@@identity
,RETURN
,OUTPUT
,但我尝试的所有数据集都是空的(但不是空的)。
这不是MyUtils.DBHelper.GetDataSet
的错误,因为它在其他地方使用并执行并返回ok。
USE [dbname]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[DuplicateOrder]
(
@sourceid int,
@var1 int,
@var2 decimal(10,2),
)
AS
INSERT INTO OrderHeader (
Users_ID,
Stores_ID,
)
SELECT
@var1,
@var2
FROM Order
WHERE id = @sourceid
GO
我用来执行存储过程的代码是:
Using cmd As New SqlCommand("DuplicateOrder") With {.CommandType = CommandType.StoredProcedure}
cmd.Parameters.AddWithValue("@sourceid", sourceId)
cmd.Parameters.AddWithValue("@var1 ", var1 )
cmd.Parameters.AddWithValue("@var2 ", var2 )
ds = MyUtils.DBHelper.GetDataSet(cmd)
End Using
答案 0 :(得分:1)
这应该可以解决问题:
ALTER Procedure [dbo].[DuplicateOrder]
(
@sourceid int,
@var1 int,
@var2 decimal(10,2)
)
AS
INSERT INTO OrderHeader (
Users_ID,
Stores_ID
)
SELECT
@var1,
@var2
SELECT @@IDENTITY AS ident
GO
我在SQL服务器上测试了它,它返回了一行ident
。
答案 1 :(得分:0)
您是否尝试过执行此SELECT IDENT_CURRENT ('Table') AS Current_Identity;
它应该返回当前会话和范围中最后生成的标识
答案 2 :(得分:0)
@@ identity和return不会工作(如果你打算一次插入多行,SCOPE_IDENT(),IDENT_CURRENT()也不会工作)。
您最好的选择是使用OUTPUT,但我在代码中看不到任何OUTPUT。下面是一个示例(代码部分在C#中,但您可以轻松转换它,比如使用Telerik转换器或自己编写 - 有N种方式传递数据,我在此示例中选择了XML):
生成示例表和过程的SQL代码:
USE [Test];
GO
CREATE TABLE IdentityTest
(
Id INT IDENTITY
NOT NULL
PRIMARY KEY ,
FirstName VARCHAR(20) ,
LastName VARCHAR(20)
);
GO
CREATE PROCEDURE InsertTestData
(
@XML VARCHAR(MAX) ,
@NodeName VARCHAR(1000)
)
AS
BEGIN
DECLARE @myIDTable TABLE ( theID INT );
DECLARE @hDoc INT;
DECLARE @tbl TABLE
(
fName VARCHAR(20) ,
lName VARCHAR(20)
);
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML;
INSERT @tbl
SELECT *
FROM OPENXML(@hDoc, @NodeName, 1) WITH (fName VARCHAR(20), lName VARCHAR(20));
EXEC sp_xml_removedocument @hDoc;
INSERT INTO [IdentityTest] ( [FirstName], [LastName] )
OUTPUT [Inserted].[Id]
INTO @myIDTable
SELECT t.[fName], t.[lName]
FROM @tbl AS t;
SELECT *
FROM @myIDTable AS [mit];
END;
GO
这是使用SP并插入多行并获取其ID的C#代码(可能已返回完整的行数据):
void Main()
{
List<Person> people = new List<Person> {
new Person { FName = "Sam", LName="Jones"},
new Person { FName = "Cetin", LName="Basoz"},
new Person { FName = "John", LName="Doe"},
new Person { FName = "Steven", LName="Smith"},
new Person { FName = "Bob", LName="Carpenter"},
};
for (int i = 0; i < 100; i++)
{
people.Add(new Person
{
FName = string.Format("FName#{0}", i),
LName = string.Format("LName#{0}", i)
});
}
var peopleAsXML = new XElement("People",
from p in people
select new XElement("Person",
new XAttribute("fName", p.FName),
new XAttribute("lName", p.LName)));
string sql = @"InsertTestData";
DataTable result = new DataTable();
using (SqlConnection con = new SqlConnection(@"server=.\SQLExpress2012;Trusted_Connection=yes;Database=Test"))
{
SqlCommand cmd = new SqlCommand(sql, con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@XML", peopleAsXML.ToString());
cmd.Parameters.AddWithValue("@NodeName", "/People/Person");
con.Open();
result.Load(cmd.ExecuteReader());
con.Close();
}
// check top 5 returned
for (int i = 0; i < 5; i++)
{
Console.WriteLine((int)result.Rows[i]["theID"]);
}
}
public class Person
{
public string FName { get; set; }
public string LName { get; set; }
}