如何从存储过程返回单个整数?

时间:2018-08-13 04:56:46

标签: c# sql-server stored-procedures sqlcommand

我有一个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#代码中看到它。

请提出任何更好的方法。

1 个答案:

答案 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);
    }