如何 return 来自存储过程的单个整数?
How to return a single integer from stored-procedure ?
我有一个 sql-server 2011 存储过程,它迭代从 xml 参数接收到的 ID,并根据来自 xml 参数。过程定义是 -
ALTER PROCEDURE [dbo].[RC_SP_ROUTE_REPOSITORY_DML]
@RAWFILES_ID xml
AS
BEGIN
DECLARE @TEMP_TABLE TABLE(ID BIGINT);
INSERT INTO @TEMP_TABLE(ID) SELECT node.value('(.)[1]','BIGINT') FROM @RAWFILES_ID.nodes('/rawfile/id') AS Temp(node);
DECLARE ID_ITERATOR CURSOR FOR SELECT ID FROM @TEMP_TABLE;
CREATE TABLE #TEMP_TABLE_REPO_ID
(
[ID] BIGINT,
[REPOSITORY_ID] BIGINT
);
OPEN ID_ITERATOR
DECLARE @ID BIGINT, @ROUTE_ID BIGINT
FETCH NEXT FROM ID_ITERATOR INTO @ID
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @ROUTE_ID= NEXT VALUE FOR RC_ROUTE_REPOSITORY_SEQ;
INSERT INTO RC_ROUTE_REPOSITORY(ID,TITLE)
(SELECT @ROUTE_ID,FILE_NAME from RC_RAW_FILES WHERE ID=@ID);
INSERT INTO RC_ROUTE_WAY_POINTS(ID,ROUTE_REPOSITORY_ID)
SELECT NEXT VALUE FOR RC_ROUTE_WAYPOINTS_SEQ,@ROUTE_ID
FROM RC_STAGE_WAY_POINTS S_ID
WHERE S_ID.RAWFILES_ID = @ID;
FETCH NEXT FROM ID_ITERATOR INTO @ID;
END
CLOSE ID_ITERATOR
DEALLOCATE ID_ITERATOR
END
参数@RAWFILES_ID 的值是 XML 例如。 -
<rawfile>
<id>
1001
</id>
<id>
1002
</id>
<id>
1003
</id>
</rawfile>
我的 C# 代码是这样的
public int AddToRepository(string rawfileid_list)
{
int routesInserted = 0;
SqlCommand cmd = new SqlCommand("[RC_SP_ROUTE_REPOSITORY_DML]", connString)
{
CommandType = CommandType.StoredProcedure
};
cmd.CommandTimeout = 5000;
cmd.Parameters.Add("@RAWFILES_ID", SqlDbType.Xml);
cmd.Parameters["@RAWFILES_ID"].Value = rawfileid_list;
connString.Open();
DataSet set = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(set);
foreach (DataRow item in set.Tables[0].Rows)
{
var val = item["routes"];
}
connString.Close();
return routesInserted;
}
预期输出为 routesInserted=3
。
我的问题是如何在当前调用过程中 return RC_ROUTE_REPOSITORY
table 中插入的记录数。基本问题如何 return 过程中的整数或字符串?
我实现此目的的方法是在游标中递增一个 count
变量并 select 它以在数据集中获取它并从数据行中获取值,当我调试该代码时该值不存在。您可以在我的 C# 代码中看到它。
任何更好的方法请建议。
回答你的问题并展示如何在没有光标的情况下做到这一点,并假设你的 return 值应该是所有受影响行的总和(你可以将其更改为你喜欢的任何内容) 存储过程为:
alter PROCEDURE [dbo].[RC_SP_ROUTE_REPOSITORY_DML]
@RAWFILES_ID xml
AS
BEGIN
declare @RowCount int;
DECLARE @TEMP_TABLE TABLE(ID varchar(10), REPOSITORY_ID BIGINT);
INSERT INTO @TEMP_TABLE(ID, REPOSITORY_ID) SELECT node.value('(.)[1]','BIGINT'), NEXT VALUE FOR RC_ROUTE_REPOSITORY_SEQ FROM @RAWFILES_ID.nodes('/rawfile/id') AS Temp(node);
INSERT INTO RC_ROUTE_REPOSITORY(ID,TITLE)
SELECT REPOSITORY_ID,[FILE_NAME]
from @TEMP_TABLE t
join RC_RAW_FILES r on r.ID=t.ID;
set @RowCount=@@ROWCOUNT
INSERT INTO RC_ROUTE_WAY_POINTS(ID,ROUTE_REPOSITORY_ID)
SELECT NEXT VALUE FOR RC_ROUTE_WAYPOINTS_SEQ,REPOSITORY_ID
from @TEMP_TABLE t
join RC_STAGE_WAY_POINTS S on s.RAWFILES_ID=t.id
set @RowCount=@RowCount+@@ROWCOUNT
return @RowCount
END
go
C# 代码是这样的(作为控制台应用程序编写,但您可以看到它在做什么)
static void Main(string[] args)
{
int routesInserted = 0;
SqlConnection connString = new SqlConnection("Server=(LocalDb)\MSSQLLocalDB;Database=test;Trusted_Connection=True;");
SqlCommand cmd = new SqlCommand("[RC_SP_ROUTE_REPOSITORY_DML]", connString)
{
CommandType = CommandType.StoredProcedure
};
cmd.CommandTimeout = 5000;
cmd.Parameters.Add("@RAWFILES_ID", SqlDbType.Xml);
SqlParameter retValue = cmd.Parameters.Add("@RowCount", SqlDbType.Int);
retValue.Direction = ParameterDirection.ReturnValue;
cmd.Parameters["@RAWFILES_ID"].Value = "<rawfile><id>1001</id><id>1002</id><id>1003</id></rawfile>";
connString.Open();
cmd.ExecuteNonQuery();
int x = (int)(retValue.Value);
}
我有一个 sql-server 2011 存储过程,它迭代从 xml 参数接收到的 ID,并根据来自 xml 参数。过程定义是 -
ALTER PROCEDURE [dbo].[RC_SP_ROUTE_REPOSITORY_DML]
@RAWFILES_ID xml
AS
BEGIN
DECLARE @TEMP_TABLE TABLE(ID BIGINT);
INSERT INTO @TEMP_TABLE(ID) SELECT node.value('(.)[1]','BIGINT') FROM @RAWFILES_ID.nodes('/rawfile/id') AS Temp(node);
DECLARE ID_ITERATOR CURSOR FOR SELECT ID FROM @TEMP_TABLE;
CREATE TABLE #TEMP_TABLE_REPO_ID
(
[ID] BIGINT,
[REPOSITORY_ID] BIGINT
);
OPEN ID_ITERATOR
DECLARE @ID BIGINT, @ROUTE_ID BIGINT
FETCH NEXT FROM ID_ITERATOR INTO @ID
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @ROUTE_ID= NEXT VALUE FOR RC_ROUTE_REPOSITORY_SEQ;
INSERT INTO RC_ROUTE_REPOSITORY(ID,TITLE)
(SELECT @ROUTE_ID,FILE_NAME from RC_RAW_FILES WHERE ID=@ID);
INSERT INTO RC_ROUTE_WAY_POINTS(ID,ROUTE_REPOSITORY_ID)
SELECT NEXT VALUE FOR RC_ROUTE_WAYPOINTS_SEQ,@ROUTE_ID
FROM RC_STAGE_WAY_POINTS S_ID
WHERE S_ID.RAWFILES_ID = @ID;
FETCH NEXT FROM ID_ITERATOR INTO @ID;
END
CLOSE ID_ITERATOR
DEALLOCATE ID_ITERATOR
END
参数@RAWFILES_ID 的值是 XML 例如。 -
<rawfile>
<id>
1001
</id>
<id>
1002
</id>
<id>
1003
</id>
</rawfile>
我的 C# 代码是这样的
public int AddToRepository(string rawfileid_list)
{
int routesInserted = 0;
SqlCommand cmd = new SqlCommand("[RC_SP_ROUTE_REPOSITORY_DML]", connString)
{
CommandType = CommandType.StoredProcedure
};
cmd.CommandTimeout = 5000;
cmd.Parameters.Add("@RAWFILES_ID", SqlDbType.Xml);
cmd.Parameters["@RAWFILES_ID"].Value = rawfileid_list;
connString.Open();
DataSet set = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(set);
foreach (DataRow item in set.Tables[0].Rows)
{
var val = item["routes"];
}
connString.Close();
return routesInserted;
}
预期输出为 routesInserted=3
。
我的问题是如何在当前调用过程中 return RC_ROUTE_REPOSITORY
table 中插入的记录数。基本问题如何 return 过程中的整数或字符串?
我实现此目的的方法是在游标中递增一个 count
变量并 select 它以在数据集中获取它并从数据行中获取值,当我调试该代码时该值不存在。您可以在我的 C# 代码中看到它。
任何更好的方法请建议。
回答你的问题并展示如何在没有光标的情况下做到这一点,并假设你的 return 值应该是所有受影响行的总和(你可以将其更改为你喜欢的任何内容) 存储过程为:
alter PROCEDURE [dbo].[RC_SP_ROUTE_REPOSITORY_DML]
@RAWFILES_ID xml
AS
BEGIN
declare @RowCount int;
DECLARE @TEMP_TABLE TABLE(ID varchar(10), REPOSITORY_ID BIGINT);
INSERT INTO @TEMP_TABLE(ID, REPOSITORY_ID) SELECT node.value('(.)[1]','BIGINT'), NEXT VALUE FOR RC_ROUTE_REPOSITORY_SEQ FROM @RAWFILES_ID.nodes('/rawfile/id') AS Temp(node);
INSERT INTO RC_ROUTE_REPOSITORY(ID,TITLE)
SELECT REPOSITORY_ID,[FILE_NAME]
from @TEMP_TABLE t
join RC_RAW_FILES r on r.ID=t.ID;
set @RowCount=@@ROWCOUNT
INSERT INTO RC_ROUTE_WAY_POINTS(ID,ROUTE_REPOSITORY_ID)
SELECT NEXT VALUE FOR RC_ROUTE_WAYPOINTS_SEQ,REPOSITORY_ID
from @TEMP_TABLE t
join RC_STAGE_WAY_POINTS S on s.RAWFILES_ID=t.id
set @RowCount=@RowCount+@@ROWCOUNT
return @RowCount
END
go
C# 代码是这样的(作为控制台应用程序编写,但您可以看到它在做什么)
static void Main(string[] args)
{
int routesInserted = 0;
SqlConnection connString = new SqlConnection("Server=(LocalDb)\MSSQLLocalDB;Database=test;Trusted_Connection=True;");
SqlCommand cmd = new SqlCommand("[RC_SP_ROUTE_REPOSITORY_DML]", connString)
{
CommandType = CommandType.StoredProcedure
};
cmd.CommandTimeout = 5000;
cmd.Parameters.Add("@RAWFILES_ID", SqlDbType.Xml);
SqlParameter retValue = cmd.Parameters.Add("@RowCount", SqlDbType.Int);
retValue.Direction = ParameterDirection.ReturnValue;
cmd.Parameters["@RAWFILES_ID"].Value = "<rawfile><id>1001</id><id>1002</id><id>1003</id></rawfile>";
connString.Open();
cmd.ExecuteNonQuery();
int x = (int)(retValue.Value);
}