Reader不读取DB值

时间:2015-10-14 19:13:48

标签: c# sql asp.net sql-server

我有这个问题正在吃我的脑海。问题是_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。

任何线索?我试图改变存储过程,但没有运气,

3 个答案:

答案 0 :(得分:2)

您无法在T-SQL中参数化字段。您的查询实际上将以WHERE 'someStringValue' = 'anotherStringValue'执行,这将永远不会为真,因此永远不会返回任何字段(当然,除非您在@field = 'foo'@value = 'foo'中输入 - 在这种情况下,每一行都将被退回)。

如果要将字段名称设为变量,则必须使用动态SQL。

答案 1 :(得分:1)

它没有读取任何内容,因为SQL没有返回任何内容。 @Field = @Value没有按照你的想法做到。如果分别传递'a'和'b',则查询将返回此条件为真的所有行(即0行)。

@Field只是一个变量,它不是一个关于用户的专栏(我猜)你认为它可能是。

答案 2 :(得分:0)

变量和字段名称之间存在混淆。

你不能这样做。您必须使用动态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 [&#34;&#34;]的情况下处理DBNull.Value

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

可以替换为

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

如果该字段是DBNull对象,则将其强制转换为字符串将导致null值。如果它发生了,一元?运算符将其转换为string.Empty。