问题
I have a custom method that handles calls to SQL which takes in a script and a list of SqlParamaters
, executes the SQL and then fills a DataSet
with any results via SqlDataAdapter
. This has been in use for over 3 years on various projects without issue.
Here is a code snippet of how the custom method is called (the actual SQL script is stored in a file):
using (SQLClass _sql = new SQLClass(_Config.DatabaseInfo))
{
FileInfo _file = new FileInfo("\\scripts\\GetEmployeeTable.sql");
List<SqlParameter> _sqlParams = new List<SqlParameter>();
// Convert DateTime to Decimal
_sqlParams.Add(new SqlParameter("PERIODEND", DateToDecimal(periodEnd)));
_sql.ExecuteSqlCommandScript(_file, _sqlParams);
}
private Decimal DateToDecimal(DateTime myDate)
{
Decimal _periodEndDecimal;
String _periodEndString = myDate.ToString("yyyyMMdd");
if (Decimal.TryParse(_periodEndString, out _periodEndDecimal))
return _periodEndDecimal;
return 0;
}
Here is the custom method:
ExecuteSqlCommandScript(FileInfo file, List<SqlParams> sqlParams)
{
. . . (get _sqlScript by reading info from 'file')
. . . (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); <!-- program falls into catch block here
SqlResult _result = new SqlResult();
_result.DataSet = _dataSet;
_result.TableCount = _dataSet.Tables.Count;
this.Results.Add(_result);
}
}
}
}
}
I am now updating an older project to use this method to query an employee table which stores dates as Decimal
type (i.e., 12/25/2016 is stored in SQL as 21061225). This is a table from another company/product that we integrate with, so I CANNOT change this column to DateTime
.
Here is the script I am executing:
SELECT ch.EMPLOYEE
FROM UPCHKH ch
WHERE ch.PEREND = @PERIODEND
The older code used SqlDataReader
to retrieve the results and this script would execute successfully. When I run this script using our custom procedure (using SqlDataAdapter
), I get this error:
ERROR: Arithmetic overflow error converting expression to data type datetime.
I traced this call though SQL Server Profiler and this is the actual call to SQL:
exec sp_executesql N'
SELECT ch.EMPLOYEE
FROM UPCHKH ch
WHERE
ch.PEREND = @PERIODEND
',N'@PERIODEND decimal(8,0)',@PERIODEND=20161101
If I copy this exact script to a SQL window and run it, I get the expected results.
So, is SqlDataAdapter
doing something funky to the SQL call or the results that are coming back from SQL? The custom method above is failing on the line identified. We are using .NET 4.5 and SQL 2014 in case that matters.
来源:https://stackoverflow.com/questions/40468272/sqldataadapter-fill-throwing-arithmetic-overflow-error-converting-expression-t