SqlDataAdapter没有填充DataTable

时间:2016-09-29 12:38:36

标签: c# sql sql-server stored-procedures data-access-layer

我遇到一个问题,SqlDataAdapter在执行特定的SQL Server存储过程时没有填充DataTable,尽管事实上我有许多类似的函数执行几乎相同的存储过程,所有这些都能正常工作

这是运行存储过程并返回已填充DataTable;

的函数
public DataTable getAssetClassifications(int? pLevel)
{            
    // Create dataTable to hold data
    var dt = new DataTable();

    // Initialize connection
    using (connection = new SqlConnection(connectionString))
    using (SqlCommand command = connection.CreateCommand())
    using (SqlDataAdapter adapter = new SqlDataAdapter(command))
    {
        // Open connection
        connection.Open();

        // Set connection properties
        command.CommandText = "BR_Manage_Primary_Classification_GetItemsAssets";
        command.CommandType = CommandType.StoredProcedure;

        // Add params
        command.Parameters.AddWithValue("@pLevel", pLevel);

        // Create return value parameter
        SqlParameter returnValue = new SqlParameter();
        returnValue.Direction = ParameterDirection.ReturnValue;

        // Add return value to command
        command.Parameters.Add(returnValue);

        // Execute command
        command.ExecuteNonQuery();

        // Fill DataTable
        adapter.Fill(dt);

        // Get result
        var result = returnValue.Value;

        Console.WriteLine("Get asset classifications result: " + result.ToString());

        if (result.Equals(0))
        {
            return dt;
        }
    }

    return null;       
}

使用pLevel = null运行它将返回null,它应返回382行记录集。从调试我可以看到' adapter.fill(dt)'应该返回382,但DataTable' dt'没有填补。

存储过程如下所示:

CREATE PROCEDURE BR_Manage_Primary_Classification_GetItemsAssets
/*  
TODO:   Allow for subsets based on tree branches
*/
    @pLevel AS INT = NULL
AS
BEGIN
/*      
    Description:    Independently returns asset classifications

        exec BR_Manage_Primary_Classification_GetItemsAssets

    Outputs:    None

    NOTE: This BR doesn't write, so it doesn't audit but it does error log the call to the DAL.

*/
    SET xact_abort, nocount on
    DECLARE @StoredProcedureName AS SYSNAME = quotename(object_schema_name(@@procid))+'.'+quotename(object_name(@@procid))
    DECLARE @Parameters AS NVARCHAR(1000) = 'Parameters: '
    DECLARE @LocalError AS INT
    DECLARE @LocalErrorMessage AS NVARCHAR(2048) 
    DECLARE @NewAuditID AS INT = NULL

BEGIN TRY
    BEGIN TRANSACTION
        EXEC DAL_Primary_Classification_GetItemsAssets
    COMMIT TRANSACTION

    -- Return SUCCESS
    RETURN 0
END TRY
BEGIN CATCH
    -- On fail close any open transactions and write to Error Log
    SET @LocalError = @@ERROR
    SET @LocalErrorMessage = ERROR_MESSAGE()

    IF @@trancount > 0 
       ROLLBACK TRANSACTION

    -- Actual error logging
    EXEC DAL_System_LogError null, @StoredProcedureName, @LocalError, @LocalErrorMessage, @Parameters, null, null, null

    -- Return Error
    RETURN 1
END CATCH
END

这称为DAL:

CREATE PROCEDURE [dbo].[DAL_Primary_Classification_GetItemsAssets]
as
begin
    /*
    Description:    Returns all assets

            exec [DAL_Primary_Classification_GetItemsAssets] 

            exec DAL_Primary_Classification_GetItems 3, 4 

    Outputs:    None

*/
set nocount on;

select  c.id as rule_id,
        c.[Description] as rule_description,
        c.Comment as rule_comment,
        l91.id as L91_IDm,
        l91.name as L91_Name,
        l91.[Description] as L91_Description,
        l91.Comment as L91_Comment,
        l92.id as L92_ID,
        l92.name as L92_Name,
        l92.[Description] as L92_Description,
        l92.Comment as L92_Comment

from    Classifications_Assets as c
            left outer join Class_L9_1 as l91 on c.Class_L9_1_ID = l91.ID       and l91.Deleted = 0
            left outer join Class_L9_2 as l92 on c.Class_L9_2_ID = l92.ID     and l92.Deleted = 0
where   c.Deleted = 0
end

对不起文字之墙,非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

我想我在另一个答案上误解了你。

我看到您在ExecuteNonQuery之前调用了adapter.Fill(dt)

您需要在那里拨打ExecuteNonQuery吗?

没有它可以测试吗?

答案 1 :(得分:0)

在这个答案中: https://stackoverflow.com/a/14816172/4519548

这家伙添加的参数有点不同。他将SqlDbType.Int传递给Add方法:

  SqlParameter returnParameter = cmd.Parameters.Add("RetVal", SqlDbType.Int);
  returnParameter.Direction = ParameterDirection.ReturnValue;
  cmd.ExecuteNonQuery();

  int id = (int) returnParameter.Value;

也许这有助于你。

答案 2 :(得分:0)

我认为您不需要command.ExecuteNonQuery();

并且需要在SqlDataAdapter adapter = new SqlDataAdapter(command)

之前打开连接