2015-10-14 84 views
1

我有這個問題正在吃掉我的思想。問題是_reader沒有讀取任何內容。閱讀器不讀數據庫值

我有這樣的代碼:

public DataEntities.Usuario GetUser(string field, string value) 
    { 
     using (SqlConnection connection = new SqlConnection(@"connectionstring")) 
     { 
      using (SqlCommand query = new SqlCommand()) 
      { 
       DataEntities.Usuario _usuario = new DataEntities.Usuario(); 

       if (field == "id" || field == "username" || field == "emailaddress") 
       { 
        query.Connection = connection; 
        query.CommandType = CommandType.StoredProcedure; 
        query.CommandText = "GetUser"; 
        var pField = query.Parameters.AddWithValue("@Field", field); 
        pField.Direction = ParameterDirection.Input; 
        var pValue = query.Parameters.AddWithValue("@Value", value); 
        pValue.Direction = ParameterDirection.Input; 

        try 
        { 
         connection.Open(); 

         SqlDataReader _reader = query.ExecuteReader(); 
         >>> while(_reader.Read()) 
         { 
          _usuario.EmailAddress = (string)_reader["EmailAddress"]; 
          _usuario.Username =  (string)_reader["Username"]; 
          _usuario.FirstName = (_reader["FirstName"] != DBNull.Value) ? (string)_reader["FirstName"] : string.Empty; 
          _usuario.LastName =  (_reader["LastName"] != DBNull.Value) ? (string)_reader["LastName"] : string.Empty; 
          _usuario.MobileNumber = (_reader["MobileNumber"] != DBNull.Value) ? (string)_reader["MobileNumber"] : string.Empty; 
         } 
         _reader.Close(); 

         return _usuario; 
        } 
        catch (SqlException ex) 
        { 
         Console.WriteLine("SQL Error: " + ex.Message); 
        } 
        finally 
        { 
         connection.Close(); 
        } 
       } 
       return _usuario; 
      } 
     } 
    } 

而且我這個存儲過程:

CREATE PROCEDURE [dbo].[GetUser] 
@Field nvarchar(100), 
@Value nvarchar(100) 
AS 
SELECT EmailAddress, 
Username, 
FirstName, 
LastName, 
MobileNumber, 
Register_Date 
FROM Users 
WHERE @Field = @Value 
RETURN 0 

,這是不返回任何東西。這不會產生異常,但是當它到達while循環時,它會跳轉並結束它返回創建的對象,其中的所有內容都爲null。

任何線索?我試圖更改存儲過程,但運氣不佳,

+0

你的代碼不會做你認爲會的事。你不能動態地看這樣的列。你沒有得到任何迴應的原因是where where謂詞正在查看這兩個參數的值,而不是實際的列數據。如果你傳入相同的值,你將得到表中的所有行。否則你什麼也得不到。你應該做的是傳遞三個可爲空的參數,並擴展你的where謂詞來處理這三個參數中的任何一個。 –

+1

存儲過程結束時返回0? – haraman

+0

首先,我已經使用了一個函數來列出所有的用戶。 其次,在創建存儲過程時,Visual Studio默認創建「返回0」 –

回答

3

您無法在T-SQL中對參數化字段進行參數設置。您的查詢將實際執行爲WHERE 'someStringValue' = 'anotherStringValue',這將永遠不會是真實的,因此永遠不會返回任何字段(除非您管道@field = 'foo'@value = 'foo',當然 - 在這種情況下,每行都會返回)。

如果你想讓字段名變成一個變量,你必須使用動態SQL。

2

它沒有讀取任何內容,因爲SQL沒有返回任何內容。 @Field = @Value不會做你認爲它做的事。如果分別傳遞'a'和'b',則查詢將返回此條件爲true的所有行(即0行)。

@Field只是一個變量,它不是用戶的列,因爲(我猜)你認爲它可能是。

1

變量和字段名稱之間存在混淆。

你不能這樣做。你必須使用動態SQL。

請注意潛在的SQL注入攻擊!

我建議您首先在存儲過程中驗證輸入。

CREATE PROCEDURE [dbo].[GetUser] 
@Field nvarchar(100), 
@Value nvarchar(100) 
AS 

-- Do check @Field to prevent SQL injection ! 
-- IF @Field <> 'Username' or @Field <> 'id' ... 
    -- RAISEERROR ... 

DECLARE @sql NVARCHAR(max) 
SET @sql = 
    'SELECT EmailAddress, 
    Username, 
    FirstName, 
    LastName, 
    MobileNumber, 
    Register_Date 
    FROM Users 
    WHERE [' + @Field + '] = ' + @Value 

EXEC sp_executesql @sql 

RETURN 0 

編輯:我剛剛意識到的動態SQL東西,而我打這一點,已被接受的答案已經提到。爲了避免這個答案是多餘的,這裏是一個很好的提示,在不重複_reader [「」]的情況下處理DBNull.Value

_usuario.FirstName = (_reader["FirstName"] != DBNull.Value) ? (string)_reader["FirstName"] : string.Empty; 

可以與

_usuario.FirstName = _reader["FirstName"] as string ?? string.Empty; 

替換如果該字段是一個的DBNull對象,那麼它鑄造爲字符串將導致一個空值。如果真的發生了,那麼這個單子呢?運算符將其轉換爲一個字符串.Empty。