2

当我在 SQL Server Management Studio 中执行以下语句时

exec sp_executesql N'select 1 其中 1 = @p1',N'@p1 nvarchar(3)',@p1=N'a'

我收到以下错误

消息 245,第 16 级,状态 1,第 1 行

将 nvarchar 值“a”转换为数据类型 int 时转换失败。

但是当我使用 ExecuteReader 时,我没有得到任何异常

为什么?

如何在应用程序中将此错误作为异常获取和处理

导入 System.Data.SqlClient

模块模块1

Sub Main()

    Dim TestSqlConnection As SqlConnection = Nothing

    Dim TestSqlCommand As SqlCommand = Nothing

    Dim TestReader As SqlDataReader = Nothing

    Dim TestGetSchemaTable As DataTable = Nothing

    TestSqlConnection = New SqlConnection
    TestSqlConnection.ConnectionString = "Data Source=(local);Database=master;Integrated Security=true"
    TestSqlConnection.Open()
    TestSqlCommand = New SqlCommand()
    TestSqlCommand.Connection = TestSqlConnection
    TestSqlCommand.CommandType = CommandType.Text
    TestSqlCommand.CommandText = "select 1 where 1 = @p1"

    Dim TestSqlParameter As SqlParameter = New SqlParameter
    TestSqlParameter.ParameterName = "@p1"
    TestSqlParameter.SqlDbType = SqlDbType.NVarChar
    TestSqlParameter.Size = 3
    TestSqlParameter.Direction = ParameterDirection.Input
    TestSqlParameter.Value = "a"
    TestSqlCommand.Parameters.Add(TestSqlParameter)

    Try
        TestReader = TestSqlCommand.ExecuteReader()
    Catch ex As Exception
        Console.WriteLine("Exception")
    Finally
        Console.WriteLine("Finally")
    End Try
End Sub

端模块

4

3 回答 3

3

ExecuteReader 实际上并不执行查询。第一次调用.Read()将引发错误。

如果您只想捕获,SqlException可以执行以下操作:

Try
    TestReader = TestSqlCommand.ExecuteReader()
    TestReader.Read()
Catch ex As SqlException
    Console.WriteLine("SQL error.")
Catch ex As Exception
    Console.WriteLine("Exception")
Finally
    Console.WriteLine("Finally")
End Try
于 2013-10-28T12:24:28.690 回答
0

对我来说,这修复了 SSMS

exec sp_executesql N'select 1 where N''a'' = @p1',N'@p1 nvarchar(3)',@p1=N'a'

exec sp_executesql N'select 1 where N''1'' = @p1',N'@p1 nvarchar(3)',@p1=N'a'

我完全不同意雷内读者。
在我的系统上,它在 ExecuteReader 上执行。
如果 ExecuteReader 没有实际执行,那将是一个真正的坏名字。
您是否认为它没有捕获和异常,因为它没有抛出异常。
我知道您在 SQL Profiler 中看到了一个错误,但是如果我引入了一个语法错误,它就会被捕获。

这是 C#,但不会对我抛出异常。
如果我将其更改为:
"select 1 where N'a' = @p1";
然后它返回一行。

如果我引入语法错误:
“select 1 whereX 1 = @p1”;
然后它会抛出一个异常并将它抛出到 ExecuteReader 行。

如果您希望 1 成为文字,您应该使用:
"select 1 where '1' = @p1";

SQLcmd.CommandType = CommandType.Text;
SQLcmd.CommandText = "select 1 where N'1' = @p1";
SqlParameter TestSqlParameter = new SqlParameter();
TestSqlParameter.ParameterName = "@p1";
TestSqlParameter.SqlDbType = SqlDbType.NChar;
TestSqlParameter.Value = "a";
SQLcmd.Parameters.Add(TestSqlParameter);
try
{
    rdr = SQLcmd.ExecuteReader();
    Int32 waste;
    if (rdr.HasRows)
    {
        while (rdr.Read())
        {
            waste = rdr.GetInt32(0);
        }
    }
}
catch (Exception Ex)
{
    Debug.WriteLine(Ex.Message);
}
于 2013-10-29T13:57:20.957 回答
0

如果传递的 sql 字符串使用 EXEC sp_executesql,我通过确保读取每个结果和结果集来解决这个问题......就像这样:

  ....
        using (var conn = new SqlConnection(_connectionString))
        {
            try
            {
                conn.Open();
                using (var cmd = new SqlCommand(sql, conn))
                {
                    cmd.CommandTimeout = 0;
                    using (var rdr = cmd.ExecuteReader())
                    {


                       // TODO: Do stuff with the rdr here.



                        FlushReader(rdr);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Fatal("Exception: {0}\r\nSQL:\r\n{1}", ex.Message, sql);
                throw;
            }
            finally
            {
                conn.Close();
            }
        }
    ...


    /// <summary>
    /// Continue trying to read in case the server threw an exception.
    /// </summary>
    private static void FlushReader(IDataReader rdr)
    {
        while (rdr.Read())
        {
        }

        while (rdr.NextResult())
        {
            while (rdr.Read())
            {
            }
        }
    }

如果不调用 FlushReader 方法,应用程序将继续运行,而不会引发任何类型的异常。即使我使用 SQL THROW 语句。在 SQL Management Studio 中运行相同的 sql 会显示错误。

希望这可以帮助。

于 2014-04-23T07:30:42.520 回答