如何 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);
    }