【问题标题】:Load stored procedure results into data table将存储过程结果加载到数据表中
【发布时间】:2013-07-06 09:57:57
【问题描述】:

我一直在网上寻找答案,但一次又一次地出现空缺。

我正在尝试做的事情: 将存储过程的结果加载到 DataTable 中。

出了什么问题: 我没有返回任何行。

这是我的存储过程 (SQL Server 2012)。它获取您输入的表的下一个自动递增的 ID 并返回它。

ALTER procedure [dbo].[GET_NEXT_AUTO_ID_OF_TABLE]
    @TABLE_NAME nvarchar(128),
    @NEXT_ID int output
as

declare @latest_id int, @row_count int
    begin 
        set @latest_id = (select IDENT_CURRENT(@TABLE_NAME))
    end
    if @latest_id = 1
    begin
    declare @lRowCountSql nvarchar(1000)
    set @lRowCountSql = N'select @row_count = count(*) from ' + @TABLE_NAME
    exec sp_executesql @lRowCountSql, N'@row_count int out', @row_count out

    if @row_count > 0
        set @next_id = @latest_id + 1
    else
        set @next_id = @latest_id
end
else
    set @next_id = @latest_id + 1
return

问题是我的 proc(我不擅长 sql)吗?当我在 SQL Server 中测试 proc 时,我得到了我期望的结果。 但不是来自我的 C# 代码:

        List<SqlParameter> aSqlParams = new List<SqlParameter>();
        aSqlParams.Add(new SqlParameter("@TABLE_NAME", "your table name") { Direction = System.Data.ParameterDirection.Input, SqlDbType = System.Data.SqlDbType.NVarChar });
        aSqlParams.Add(new SqlParameter() { ParameterName = "@NEXT_ID", Direction = System.Data.ParameterDirection.Output, SqlDbType = SqlDbType.Int });
        DataTable lDt = SQLServerUtils.ExecuteStoredProc("GET_NEXT_AUTO_ID_OF_TABLE", aSqlParams);
        int lNextID = lDt.Rows[0].Field<int>("NEXT_ID");

    public static DataTable ExecuteStoredProc(string aProcName, List<SqlParameter> aSqlParams)
    {
        DataTable lResults = new DataTable();

        using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
        {
            SqlCommand cmd = new SqlCommand(aProcName, conn);
            cmd.CommandType = CommandType.StoredProcedure;

            if (aSqlParams != null)
                foreach (SqlParameter lP in aSqlParams)
                    cmd.Parameters.Add(lP);
            conn.Open();
            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            adapter.Fill(lResults);
        }
        return lResults;
    }

【问题讨论】:

  • 这种获取下一个 ID 的精细方法的全部原因是因为如果表为空 IDENT_CURRENT 为 1,但如果有一行 IDENT_CURRENT 也是 1。所以如果我使用 IDENT_CURRENT +1一个空表意味着 next_id 是 2 - 它显然不是。

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


【解决方案1】:

输出参数本身返回,不包含在数据表中。
我认为您需要一个不同的程序来执行此类查询,

public static int ExecuteOutputIntParam(string aProcName, string outputParamName, List<SqlParameter> aSqlParams)
{
    int outValue = -1;
    using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
    {
        conn.Open();
        SqlCommand cmd = new SqlCommand(aProcName, conn);
        cmd.CommandType = CommandType.StoredProcedure;

        if (aSqlParams != null)
            foreach (SqlParameter lP in aSqlParams)
                cmd.Parameters.Add(lP);

        int result = cmd.ExecuteNonQuery();

        if (aSqlParams != null)
        {
            outValue = Convert.ToInt32(aSqlParams[outputParamName].Value);

        } 
    }
    return outValue;
}

编辑 我已经复制/粘贴了您的示例,但我没有注意到您依赖 SqlDataAdapter 来打开/关闭连接。在我的示例中,应显式打开连接

【讨论】:

  • 感谢您的努力,但没有雪茄。 'int 结果 = cmd.ExecuteNonQuery();'给出 -1
  • OK,但是参数值呢?
  • 另外,我不确定您是否可以在 storeprocedure set @latest_id = (select IDENT_CURRENT(@TABLE_NAME)) 中使用此语法,如果不使用动态 sql,则不能使用参数替换表名或字段名,因为您稍后会这样做
  • 我将 outValue = 更改为 'outValue = Convert.ToInt32(cmd.Parameters[outputParamName].Value);'但它是空的
  • 嗯,好的。如果我在 SQL Server Management Studio 中执行 proc,它会按预期运行。但我会将该位更改为动态 sql,看看我得到了什么。但是,我只能明天才能做到。在那之前。
【解决方案2】:

这里的诀窍是我想要的值返回到 out 参数中。 固定的代码是这样的……

SQL 过程:

ALTER procedure [dbo].[GET_NEXT_AUTO_ID_OF_TABLE]
    @TABLE_NAME nvarchar(128),
    @NEXT_ID int output
as

declare @latest_id int, @row_count int
begin 
    set @latest_id = (select IDENT_CURRENT(''+@TABLE_NAME+''))
end
if @latest_id = 1
    begin
        declare @lRowCountSql nvarchar(1000)
        set @lRowCountSql = N'select @row_count = count(*) from ' + @TABLE_NAME
        exec sp_executesql @lRowCountSql, N'@row_count int out', @row_count out

        if @row_count > 0
            set @next_id = @latest_id + 1
        else
            set @next_id = @latest_id
    end
else
    set @next_id = @latest_id + 1
return

C#:

    public static int GetNextIdOfTable(string aTableName)
    {
        int lNextID = 0;

        using (SqlConnection conn = new SqlConnection(DatabaseConnectionString))
        {
            SqlCommand cmd = new SqlCommand("GET_NEXT_AUTO_ID_OF_TABLE", conn);
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter("@TABLE_NAME", aTableName) { Direction = System.Data.ParameterDirection.Input, SqlDbType = System.Data.SqlDbType.NVarChar });
            cmd.Parameters.Add(new SqlParameter() { ParameterName = "@NEXT_ID", Direction = System.Data.ParameterDirection.Output, SqlDbType = SqlDbType.Int });

            conn.Open();
            cmd.ExecuteReader();

            if (cmd.Parameters["@NEXT_ID"] != null && cmd.Parameters["@NEXT_ID"].Value != DBNull.Value)
                return int.Parse(cmd.Parameters["@NEXT_ID"].Value.ToString());
        }
        return lNextID;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多