2013-10-28 23 views
0

當我在SQL Server Management Studio中執行以下語句與SqlDataReader.ExecuteReader也不例外,而SQL Server返回converstion錯誤

EXEC sp_executesql的N'select 1,其中1 = @ P1' ,N'@ P1爲nvarchar(3 ) '@ P1 = N'a'

我得到下面的錯誤

消息245,級別16,狀態1,行1

轉換˚F在將nvarchar值'a'轉換爲數據類型int時變成了ailed。

但是當我使用的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 

前端模塊

回答

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 where X 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); 
} 
+0

Blam,也許這取決於錯誤發生的位置,在解析或執行期間。奇怪的錯誤報告,那是經驗豐富的開發人員所在! – datadev

2

的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 
+0

通常,如果HasRows爲false,我不會調用read(),或者我應該調用read()呢? – datadev

+0

在讀取()之前的executereader()之後,我可以看到SQL Profiler中的錯誤,甚至被稱爲 – datadev

+0

@datadev HasRows會拋出錯誤嗎?或者只是使用while(reader.read()) – Paparazzi

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管理工作室中運行相同的SQL將顯示錯誤。

希望這會有所幫助。