1

I am having a problem where a SqlDataAdapter is not filling a DataTable when executing a particular SQL Server stored procedure, despite the fact I have many similar functions executing almost identical stored procedures that all work correctly.

Here is the function that runs the stored procedure and returns the filled 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;       
}

Running this with pLevel = null will return null where it should be return a 382 row recordset. From debugging I can see that 'adapter.fill(dt)' returns 382, as it should, yet the DataTable 'dt' is not filled.

The stored procedure is shown here:

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

This calls the 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

Sorry for the wall of text, any help would be greatly appreciated!

2
  • Have you checked the value of resultValue in the debugger? Commented Sep 29, 2016 at 12:48
  • The result value returns 0 for success which is fine Commented Sep 29, 2016 at 13:12

2 Answers 2

1

I think I misunderstood you on my other answer.

I see you're calling ExecuteNonQuery before adapter.Fill(dt).

Do you need to call ExecuteNonQuery there?

Can you test without it?

Sign up to request clarification or add additional context in comments.

4 Comments

Yes just had a look and it makes no difference, although I am thinking I might try to use a reader to see if that makes any difference
That's bad... :(
Maybe the problem is calling a SP that calls another SP. Have you tried it using only one SP? I'm not sure if you can retrieve the result from the exec to an outer exec (that's confuse).
People usually recommend temp tables to do that: stackoverflow.com/a/15802670/4519548
1

I think you don't need command.ExecuteNonQuery();

and need to open connection before SqlDataAdapter adapter = new SqlDataAdapter(command)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.