简体   繁体   中英

PostgreSQL “Column ”foo“ does not exist”

I'm trying to make a search method for my program. In search page, there are 8 variables a user can search in. For example, If user types only into "Name:" this method will Select according to the name's. If user decided to type into "Id:" too, this method will Select according to both. I have 8 variables in the original.

Well... Whenever I try to search, I got "Column 'sth' does not exists" message. If I only type on name, it says column 'Name' does not exist. Same for Id, except it says cloumn 'Id' does not exist.

I can't figure out what is the problem. It's probably about the prepared statements. My null search works by the way.

    public ObservableCollection<Foo> Search(Foo foo)
    {
        ObservableCollection<Foo> results = new ObservableCollection<Foo>();

        IdParam = new NpgsqlParameter("@Id", NpgsqlTypes.NpgsqlDbType.Bigint);
        NameParam = new NpgsqlParameter("@Name", NpgsqlTypes.NpgsqlDbType.Varchar, 50);

        string sql;

        //Null search
        if (intern == null) 
            sql = "select * from \"Foos\"";
        else
        {    
            sql = "select * from \"Foos\" ";
            int parameterCount = 0;

            //This part goes too long, So I just put 2 sample of it. I have 8 parameters in the  
            //original
            if (foo.Id > 0)
            {
                if (parameterCount == 0)
                    sql += "WHERE \"Id\"=";
                if (parameterCount > 0)
                    sql += "AND \"Id\"=";
                IdParam.Value = foo.Id;
                    sql += "@Id ";
                parameterCount++;
            }

            if (foo.Name != "" && foo.Name != null)
            {
                if (parameterCount == 0)
                    sql += "WHERE \"Name\"=";
                if (parameterCount > 0)
                    sql += "AND \"Name\"=";
                NameParam.Value = foo.Name;
                    sql += "@Name ";
                parameterCount++;
            }

        }
        try
        {
            NpgsqlCommand cmd = new NpgsqlCommand(sql, dbConnection);
            NpgsqlDataReader dr = cmd.ExecuteReader();  //This line gives the error
            Intern result = new Intern();
            while (dr.Read())
            {
                result.Id = (long)dr.GetInt64(dr.GetOrdinal("Id"));
                result.Name = dr.GetString(dr.GetOrdinal("Name"));

                results.Add(result);
                result = new Intern();
            }
            return results;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
            return null;
        }
    }

When I don't use prepared statements, it works!

           if (intern.Id > 0)
            {
                if (parameterCount == 0)
                    sql += "WHERE \"Id\"=";
                if (parameterCount > 0)
                    sql += "AND \"Id\"=";

                //IdParam.Value = intern.Id;
                //sql += "@Id ";

                sql += intern.Id + " ";  //When I do this, it works.
                parameterCount++;
            }

What should I do to solve this problem?

Building SQL strings is a practice rife with problems. As you can see now, troubleshooting is a real pain. Then the guy after you has to understand what's going on when he tries to work on it...

One method is to write the query so no textual changes need be performed. Such as:

@SQL = "select * from \"foos\" "
     + "where (@ID is null or \"ID\" = @ID) "
     + "  and (@Name is null or \"Name\" = @Name) "
     + "  and (@so_forth...)"

So if there is a value in @Name, it will not be null and the value will be used to check against the column. If not, it will be null and the test skipped (read it as "...and TRUE and...".

The point is, now you are executing the same query every time, only the values change. Much easier to troubleshoot when something is not quite working the way you think it should.

Well, I'd forgot to add parameters into my command, that's why I got this error.

So I fixed it, it worked!

            if (intern.Id > 0)
            {
                if (parameterCount == 0)
                    sql += "WHERE \"Id\"=";
                if (parameterCount > 0)
                    sql += "AND \"Id\"=";
                IdParam.Value = intern.Id;
                sql += "@Id ";

                cmd.Parameters.Add(IdParam);
                parameterCount++;
            }

            if (intern.Name != "" && intern.Name != null)
            {
                if (parameterCount == 0)
                    sql += "WHERE \"Name\" ILIKE ";
                if (parameterCount > 0)
                    sql += "AND \"Name\" ILIKE ";
                NameParam.Value = intern.Name;
                sql += "@Name ";

                cmd.Parameters.Add(NameParam);
                parameterCount++;
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM