我有一个sql-server 2011存储过程,该过程对从xml参数接收到的id进行迭代,并基于来自xml参数的那些ID对两个关系表执行插入操作。过程定义为-
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
。
我的问题是如何在当前对过程的调用中返回插入RC_ROUTE_REPOSITORY
表中的记录数。基本问题是如何从过程中返回整数或字符串?
我实现此目标的方法是在光标中增加一个count
变量,然后选择它以将其获取到数据集中,并从数据行中获取值(当我调试该代码时不存在该值)。您可以在我的C#代码中看到它。
请提出任何更好的方法。
答案 0 :(得分:1)
要回答这两个问题并显示如何在没有游标的情况下进行操作,并假定您的返回值应该是所有受影响的行的总和(您可以将其更改为所需的值),则存储的proc是:
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);
}