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")
....

注意事项:

我真的很想了解为什么会这样。即使我有一些解决方案,他们也没有给我解释原因。我以为我对 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