【问题标题】:SQLDataAdapter changing value type returned from SQLSQLDataAdapter 更改从 SQL 返回的值类型
【发布时间】:2016-11-08 13:37:38
【问题描述】:

在我的 C# 项目中,我正在对 SQL 2014 数据库执行查询以检索 Employee 数据,包括以 Decimal 形式存储在数据库中的 PeriodEnd(即,存储 2016 年 11 月 17 日)如 20161117)。我查询的数据库不是我们的产品,所以我无法将类型更改为 DateTime 字段。

这是正在执行的 SQL 脚本:

SELECT DISTINCT
    e.EMPLOYEE as EmpNo,
    ch.PEREND As PeriodEnd,
    ch.PRPOSTSTAT
FROM UPEMPL e
    INNER JOIN UPCHKH ch 
        ON e.EMPLOYEE = ch.EMPLOYEE
WHERE 
    ch.PEREND = @PERIODEND

这里是SqlDataAdapter 电话:

ExecuteSqlCommandScript(String sqlScript, List<SqlParams> sqlParams)
{
    . . . (setup SqlConnection info)

    using (SqlConnection _conn = new SqlConnection(connectionString))
    {
        using (SqlCommand _cmd = new SqlCommand())
        {
            _cmd.CommandText = sqlScript;
            _cmd.Connection = _conn;
            _cmd.Connection.Open();

            // add SqlParameters to SQL command
            if (sqlParams != null)
            {
                _cmd.Parameters.AddRange(sqlParams.ToArray());
            }

            using (SqlDataAdapter _sqlDataAdapter = new SqlDataAdapter(_cmd))
            {
               try
               {
                    // Save Table info to Results object
                    DataSet _dataSet = new DataSet();
                    _sqlDataAdapter.Fill(_dataSet); 

                    SqlResult _result = new SqlResult();
                    _result.DataSet = _dataSet;
                    _result.TableCount = _dataSet.Tables.Count;

                    this.Results.Add(_result);
                }
            }
        }
    }
}

使用 SQL Server Profiler 我可以看到传递给 SQL 的查询是:

exec sp_executesql N'
SELECT DISTINCT
    e.EMPLOYEE as EmpNo,
    ch.PEREND As PeriodEnd,
    ch.PRPOSTSTAT
FROM UPEMPL e
    INNER JOIN UPCHKH ch 
        ON e.EMPLOYEE = ch.EMPLOYEE
WHERE 
    ch.PEREND = @PERIODEND 
',N'@PERIODEND nvarchar(8)',@PERIODEND=N'20161101'

如果我直接在 SQL 中运行,结果如下:

但是,DataTable_sqlDataAdapter 创建的结果是:

有没有办法强制SqlDataAdapter 使用结果中的数据类型?或者是否有可能 SQL 确实返回了 DateTime 对象而不是 DecimalPeriodEnd 列在 SQL 中定义为 decimal(9,0))?如果是这样,是否有这样做的原因和/或防止它的方法?

【问题讨论】:

  • StartDate 和这个有什么关系?
  • 调试的时候,编译器说的是什么类型?您可能只需在每条记录的该列上执行 .ToString("yyyyMMdd")
  • 你能粘贴创建_cmd对象的代码吗?特别是命令文本的创建和参数化?
  • 为了理智,SELECT TOP(1) SQL_VARIANT_PROPERTY(CONVERT(SQL_VARIANT, PEREND), 'BaseType') FROM UPCHKH 产生了什么?
  • @Crowcoder,不知道我为什么写StartDate,已将其更正为PeriodEnd

标签: c# sql-server sqldatadapter


【解决方案1】:

尝试在创建数据集时显式添加列类型,方法是将十进制类型的数据列添加到数据表中。 我的猜测是,由于您没有明确指定列类型,.net 是从值派生的。

【讨论】:

  • 没有。数据适配器从 SQL Server 返回的类型派生类型。总是有这样的类型。它可能是VARCHARDECIMALDATETIME,但它永远不会让.NET 猜测。你所说的确实适用于参数——如果没有指定类型,.NET 必须从你传入的任何对象的类型派生 SQL 类型,这可能与你实际想要的类型不匹配。
  • 感谢@Jeroen Mostert 的解释
【解决方案2】:

感谢大家在这方面的帮助。查看_cmd 对象的建议使我找到了解决方案。有一段代码应该更改数据库以使用数据库ABC。这段代码工作不正常,因此数据库连接停留在数据库XYZ 上。使这个问题难以解决的原因是数据库XYZ 定义了从数据库ABC 返回数据的视图,但PeriodEnd 列作为DateTime 而不是decimal。我不知道这些视图,当我看到符合我预期的数据时,我什至没有想过要查看并确保正确分配了数据库。

【讨论】:

    猜你喜欢
    • 2020-11-08
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 2019-08-29
    • 1970-01-01
    • 2021-12-24
    • 2013-07-04
    相关资源
    最近更新 更多