SQL 异常:将数据类型 nvarchar 转换为 int 时出错
SQL Exception: Error converting data type nvarchar to int
看起来像是一个转换问题,但是当应用转换(我认为是正确的格式)时,我仍然得到 SQL在 Visual Studio Web Developer 2010 Express 中引发的异常(VB.NET)
从具有 1 个输入参数和 4 个输出参数的存储过程开始,相关代码片段如下所示:
ALTER PROCEDURE [dbo].[SelectCompanies]
@tickersList NVARCHAR(max) = NULL,
@YearInWhichEarningsExistForAllComparisonCompanies int OUTPUT,
@topEndToStartYear nvarchar(9) OUTPUT,
@middleEndToStartYear nvarchar(9) OUTPUT,
@bottomEndToStartYear nvarchar(9) OUTPUT
AS
BEGIN
SET @YearInWhichEarningsExistForAllComparisonCompanies = (SELECT TOP 1 ey.[Year] FROM company c, earningspershare e, earningspershareYear ey WHERE c.ticker_id = e.ticker_id AND e.EarningsPerShareID = ey.EarningsPerShareID AND c.tickerSymbol IN ( SELECT * FROM dbo.fnCSVStringToTable(@tickersList,',') ) AND ey.Value is not null ORDER by ey.[Year] DESC);
DECLARE @topStartYear int, @topEndYear int;
DECLARE @middleStartYear int, @middleEndYear int;
DECLARE @bottomStartYear int, @bottomEndYear int;
SET @topStartYear = @YearInWhichEarningsExistForAllComparisonCompanies;
SET @topEndYear = @topStartYear - 2;
SET @topEndToStartYear = CAST(@topEndYear As nvarchar(4)) + N'-' ; --ERROR
....
相关VB.NET代码如下:
Dim year As New SqlParameter
Dim topEndToStartYear As New SqlParameter
Dim middleEndToStartYear As New SqlParameter
Dim bottomEndToStartYear As New SqlParameter
'Add tables
dadCompanies = New SqlDataAdapter("SelectCompanies", conn)
dadCompanies.SelectCommand.CommandType = CommandType.StoredProcedure
If Not IsNothing(tBx_c_tickerSymbol.Text.ToString) Then
dadCompanies.SelectCommand.Parameters.AddWithValue("@tickersList", tBx_c_tickerSymbol.Text.ToString)
'year Output Parameter
year = dadCompanies.SelectCommand.Parameters.AddWithValue("@YearInWhichEarningsExistForAllComparisonCompanies", SqlDbType.Int)
year.Size = 4
year.Direction = ParameterDirection.Output
'topEndToStartYear Output Parameter
topEndToStartYear = dadCompanies.SelectCommand.Parameters.AddWithValue("@topEndToStartYear", SqlDbType.NVarChar)
topEndToStartYear.Size = 10
topEndToStartYear.Direction = ParameterDirection.Output
'middleEndToStartYear Output Parameter
middleEndToStartYear = dadCompanies.SelectCommand.Parameters.AddWithValue("@middleEndToStartYear", SqlDbType.NVarChar)
middleEndToStartYear.Size = 12
middleEndToStartYear.Direction = ParameterDirection.Output
'bottomEndToStartYear Output Parameter
bottomEndToStartYear = dadCompanies.SelectCommand.Parameters.AddWithValue("@bottomEndToStartYear", SqlDbType.NVarChar)
bottomEndToStartYear.Size = 12
bottomEndToStartYear.Direction = ParameterDirection.Output
End If
dadCompanies.Fill(dstCompanies, "company")
....
注意事项:
- 从 SQL Server Managment Studio 2012 中执行的存储过程执行良好,没有任何错误。
- 当使用 IISExpress .NET v2.0.50727 通过 Visual Studio Web Developer Express 2010 进行调试时,抛出 SQL 服务器异常。
- 将 SQL 服务器中的这一行 CAST(@topEndYear As nvarchar(4)) + N'-'(发生错误的地方)切换为 N'-' + CAST(@topEndYear As nvarchar( 4)) 纠正问题,即以 nvarchar 字符开头,然后转换
- 在 VB.NET 中将值 SqlDbType.NVarChar 更改为 SqlDbType.NVarChar.ToString 更正问题,如果我将问题行保留为 CAST(@topEndYear As nvarchar(4)) + N' -'
我真的很想了解为什么会这样。即使我有一些解决方案,他们也没有给我解释原因。我以为我对 Casting 掌握得很好,也许我遗漏了什么?
如果您使用 AddWithValue
,则第二个参数是值,但您传递了 SqlDbType
。而是使用 Add
。这是反对AddWithValue
的原因之一:
'year Output Parameter
Dim Year = dadCompanies.SelectCommand.Parameters.Add("@YearInWhichEarningsExistForAllComparisonCompanies", SqlDbType.Int)
Year.Size = 4
Year.Direction = ParameterDirection.Output
'topEndToStartYear Output Parameter
Dim topEndToStartYear = dadCompanies.SelectCommand.Parameters.Add("@topEndToStartYear", SqlDbType.NVarChar)
topEndToStartYear.Size = 10
topEndToStartYear.Direction = ParameterDirection.Output
'middleEndToStartYear Output Parameter
Dim middleEndToStartYear = dadCompanies.SelectCommand.Parameters.Add("@middleEndToStartYear", SqlDbType.NVarChar)
middleEndToStartYear.Size = 12
middleEndToStartYear.Direction = ParameterDirection.Output
'bottomEndToStartYear Output Parameter
Dim bottomEndToStartYear = dadCompanies.SelectCommand.Parameters.Add("@bottomEndToStartYear", SqlDbType.NVarChar)
bottomEndToStartYear.Size = 12
bottomEndToStartYear.Direction = ParameterDirection.Output
看起来像是一个转换问题,但是当应用转换(我认为是正确的格式)时,我仍然得到 SQL在 Visual Studio Web Developer 2010 Express 中引发的异常(VB.NET)
从具有 1 个输入参数和 4 个输出参数的存储过程开始,相关代码片段如下所示:
ALTER PROCEDURE [dbo].[SelectCompanies]
@tickersList NVARCHAR(max) = NULL,
@YearInWhichEarningsExistForAllComparisonCompanies int OUTPUT,
@topEndToStartYear nvarchar(9) OUTPUT,
@middleEndToStartYear nvarchar(9) OUTPUT,
@bottomEndToStartYear nvarchar(9) OUTPUT
AS
BEGIN
SET @YearInWhichEarningsExistForAllComparisonCompanies = (SELECT TOP 1 ey.[Year] FROM company c, earningspershare e, earningspershareYear ey WHERE c.ticker_id = e.ticker_id AND e.EarningsPerShareID = ey.EarningsPerShareID AND c.tickerSymbol IN ( SELECT * FROM dbo.fnCSVStringToTable(@tickersList,',') ) AND ey.Value is not null ORDER by ey.[Year] DESC);
DECLARE @topStartYear int, @topEndYear int;
DECLARE @middleStartYear int, @middleEndYear int;
DECLARE @bottomStartYear int, @bottomEndYear int;
SET @topStartYear = @YearInWhichEarningsExistForAllComparisonCompanies;
SET @topEndYear = @topStartYear - 2;
SET @topEndToStartYear = CAST(@topEndYear As nvarchar(4)) + N'-' ; --ERROR
....
相关VB.NET代码如下:
Dim year As New SqlParameter
Dim topEndToStartYear As New SqlParameter
Dim middleEndToStartYear As New SqlParameter
Dim bottomEndToStartYear As New SqlParameter
'Add tables
dadCompanies = New SqlDataAdapter("SelectCompanies", conn)
dadCompanies.SelectCommand.CommandType = CommandType.StoredProcedure
If Not IsNothing(tBx_c_tickerSymbol.Text.ToString) Then
dadCompanies.SelectCommand.Parameters.AddWithValue("@tickersList", tBx_c_tickerSymbol.Text.ToString)
'year Output Parameter
year = dadCompanies.SelectCommand.Parameters.AddWithValue("@YearInWhichEarningsExistForAllComparisonCompanies", SqlDbType.Int)
year.Size = 4
year.Direction = ParameterDirection.Output
'topEndToStartYear Output Parameter
topEndToStartYear = dadCompanies.SelectCommand.Parameters.AddWithValue("@topEndToStartYear", SqlDbType.NVarChar)
topEndToStartYear.Size = 10
topEndToStartYear.Direction = ParameterDirection.Output
'middleEndToStartYear Output Parameter
middleEndToStartYear = dadCompanies.SelectCommand.Parameters.AddWithValue("@middleEndToStartYear", SqlDbType.NVarChar)
middleEndToStartYear.Size = 12
middleEndToStartYear.Direction = ParameterDirection.Output
'bottomEndToStartYear Output Parameter
bottomEndToStartYear = dadCompanies.SelectCommand.Parameters.AddWithValue("@bottomEndToStartYear", SqlDbType.NVarChar)
bottomEndToStartYear.Size = 12
bottomEndToStartYear.Direction = ParameterDirection.Output
End If
dadCompanies.Fill(dstCompanies, "company")
....
注意事项:
- 从 SQL Server Managment Studio 2012 中执行的存储过程执行良好,没有任何错误。
- 当使用 IISExpress .NET v2.0.50727 通过 Visual Studio Web Developer Express 2010 进行调试时,抛出 SQL 服务器异常。
- 将 SQL 服务器中的这一行 CAST(@topEndYear As nvarchar(4)) + N'-'(发生错误的地方)切换为 N'-' + CAST(@topEndYear As nvarchar( 4)) 纠正问题,即以 nvarchar 字符开头,然后转换
- 在 VB.NET 中将值 SqlDbType.NVarChar 更改为 SqlDbType.NVarChar.ToString 更正问题,如果我将问题行保留为 CAST(@topEndYear As nvarchar(4)) + N' -'
我真的很想了解为什么会这样。即使我有一些解决方案,他们也没有给我解释原因。我以为我对 Casting 掌握得很好,也许我遗漏了什么?
如果您使用 AddWithValue
,则第二个参数是值,但您传递了 SqlDbType
。而是使用 Add
。这是反对AddWithValue
的原因之一:
'year Output Parameter
Dim Year = dadCompanies.SelectCommand.Parameters.Add("@YearInWhichEarningsExistForAllComparisonCompanies", SqlDbType.Int)
Year.Size = 4
Year.Direction = ParameterDirection.Output
'topEndToStartYear Output Parameter
Dim topEndToStartYear = dadCompanies.SelectCommand.Parameters.Add("@topEndToStartYear", SqlDbType.NVarChar)
topEndToStartYear.Size = 10
topEndToStartYear.Direction = ParameterDirection.Output
'middleEndToStartYear Output Parameter
Dim middleEndToStartYear = dadCompanies.SelectCommand.Parameters.Add("@middleEndToStartYear", SqlDbType.NVarChar)
middleEndToStartYear.Size = 12
middleEndToStartYear.Direction = ParameterDirection.Output
'bottomEndToStartYear Output Parameter
Dim bottomEndToStartYear = dadCompanies.SelectCommand.Parameters.Add("@bottomEndToStartYear", SqlDbType.NVarChar)
bottomEndToStartYear.Size = 12
bottomEndToStartYear.Direction = ParameterDirection.Output