SqlDataAdapter 未填充 DataTable

Posted

技术标签:

【中文标题】SqlDataAdapter 未填充 DataTable【英文标题】:SqlDataAdapter not filling DataTable 【发布时间】:2017-02-07 19:05:25 【问题描述】:

在执行特定 SQL Server 存储过程时,SqlDataAdapter 没有填充 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

对不起,文字墙,任何帮助将不胜感激!

【问题讨论】:

你检查过调试器中resultValue的值吗? 成功返回 0 即可 【参考方案1】:

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

并且需要在SqlDataAdapter adapter = new SqlDataAdapter(command)之前打开连接

【讨论】:

【参考方案2】:

我想我在其他答案上误解了你。

我看到你在adapter.Fill(dt) 之前打电话给ExecuteNonQuery

你需要在那里打电话给ExecuteNonQuery吗?

没有它你能测试吗?

【讨论】:

是的,只是看了一下,没什么区别,尽管我想我可能会尝试使用阅读器来看看是否有任何区别 那很糟糕... :( 也许问题是调用一个调用另一个 SP 的 SP。你试过只用一个SP吗?我不确定您是否可以将结果从 exec 检索到外部 exec(这很混乱)。 人们通常推荐使用临时表来做到这一点:***.com/a/15802670/4519548

以上是关于SqlDataAdapter 未填充 DataTable的主要内容,如果未能解决你的问题,请参考以下文章

检测 SqlDataAdapter 填充方法何时完成

如何在 where 子句上基于 SqlCommand 或 SqlDataAdapter 填充 datagridview? SqlDataAdapter 不适用于哪里?

C# SqlDataAdapter 不填充数据集

SqlDataAdapter使用Fill方法填充DataSet

为啥 SqlDataAdapter 的填充不允许我添加与外观具有相同行值的行?

用 DataTable 填充的 SqlDataAdapter 不起作用