【问题标题】:Passing datatable to SQL Server stored procedure not working将数据表传递给 SQL Server 存储过程不起作用
【发布时间】:2018-04-06 04:20:54
【问题描述】:

我有一个 ASP.NET 应用程序,它将数据表传递给 Web 服务,然后从 Web 服务传递给 SQL Server 存储过程。当我将 Web 应用程序和 Web 服务发布到服务器并运行时,它失败了。当我从指向服务器上的 Web 服务的本地主机运行应用程序时,它工作正常。当我从 localhost 运行 Web 应用程序和 Web 服务时,它工作正常。

我做了一些故障排除,发现下面一行是问题,但我不确定如何解决:

cmdCommit.Parameters.AddWithValue(@SourceTable, dtSource);

当我评论上面的行时,一切正常。当我用字符串数据类型替换上面行中对DataTable (dtSource) 的引用时,它可以工作。

这是整个 web 方法,我在 try/catch 块中使用此代码:

DataTable dtSource = ObjectToData(sourceTable);
dtSource.TableName = TableTypeObject;

using (SqlConnection cnn = new SqlConnection(_cnnSqlCapss))
{
    SqlCommand cmdCommitChange = new SqlCommand("usp_Stored_Procedure", cnn);
    cmdCommitChange.CommandType = CommandType.StoredProcedure;

    cmdCommitChange.Parameters.AddWithValue("@Parm1",  Value1);
    cmdCommitChange.Parameters.AddWithValue("@Parm2", Value2);
    cmdCommitChange.Parameters.AddWithValue("@Parm3", dtSource);

    var returnParameter = cmdCommitChange .Parameters.Add("@ReturnVal", SqlDbType.Int);

    returnParameter.Direction = ParameterDirection.ReturnValue;

    cnn.Open();
    cmdCommitChange .ExecuteNonQuery();

    var result = returnParameter.Value;
    return (int)result;
}

令人困惑的部分是,当我从 localhost 运行 Web 应用程序并引用服务器上的 Web 服务时,它可以工作。我不明白为什么当我从服务器运行 Web 应用程序时它会失败。

当我评论引用 DataTable 的行时,一切正常。

我尝试了以下方法,但仍然没有成功:

SqlParameter tvpParam cmdCommit.Parameters.AddWithValue "@SourceTable", dtSource);  
 tvpParam.SqlDbType = SqlDbType.Structured; 
 tvpParam.TypeName = "dbo.SourceTableType";

另外,web 方法没有抛出异常。

【问题讨论】:

  • @SourceTable 的 DB 字段类型是什么?没有 SqlDbType 来传递数据表。这意味着,您不能将数据表添加到 SQL @parameter。
  • SqlDbType.Structured

标签: asp.net sql-server datatable


【解决方案1】:

假设你已经在做这些:

  1. 在数据库中的用户定义表类型中定义表类型(通常称为 TVP,请参阅下面的参考部分);
  2. 添加参数以将DataTable 传递给存储过程(例如@SourceTable)。

然后,您可以使用SqlDbType.StructuredDataTable 内容作为存储过程参数传递,如下所示:

cmdCommitChange.Parameters.Add("@SourceTable", SqlDbType.Structured).Value = dtSource;

替代AddWithValue:

cmdCommitChange.Parameters.AddWithValue("@SourceTable", dtSource).SqlDbType = SqlDbType.Structured;

SqlConnection 块中的用法示例:

using (SqlConnection cnn = new SqlConnection(_cnnSqlCapss))
{
    SqlCommand cmdCommitChange = new SqlCommand("usp_Stored_Procedure", cnn);
    cmdCommitChange.CommandType = CommandType.StoredProcedure;

    cmdCommitChange.Parameters.AddWithValue("@Parm1", Value1);
    cmdCommitChange.Parameters.AddWithValue("@Parm2", Value2);
    cmdCommitChange.Parameters.AddWithValue("@Parm3", Value3);

    // add this line
    cmdCommitChange.Parameters.Add("@SourceTable", SqlDbType.Structured).Value = dtSource;

    cmdCommitChange.Parameters.Add("@ReturnVal", SqlDbType.Int).Direction = ParameterDirection.ReturnValue;

    cnn.Open();
    cmdCommitChange.ExecuteNonQuery();

    var result = (int)returnParameter.Value;
    return result;
}

参考:

Table-Valued Parameters (MS Docs)

【讨论】:

  • 我正在做你提到的一切。
【解决方案2】:

我发现了问题。我传递的文本值对于我的数据表上的列来说太大了。

Web 服务确实引发了异常,但我的应用程序例程中有一些代码阻止我看到它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-29
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多