Search code examples
rubysqliteeachnomethoderror

unable to sum a float iteration


ruby -v 2.3.7 (sqlite3 has compatability issues with newer ruby -v) sqlite3 -v 3.22 sqlite -v 2.8 lsb_release -a 18.04

I have condensed the code as much as I can.

def some_method(info_hash)
    ...
    db.results_as_hash = true
    sum = 0
    db.transaction
    db.execute2 "CREATE table if not exists a_table(Id INT PRIMARY KEY, Type TEXT, Month TEXT, Amount FLOAT, TOTAL FLOAT)"
    db.execute2 "INSERT into a_table(Type, Month, Amount) values(:Type , :Month , :Amount)", info_hash[:category], info_hash[:month], info_hash[:amount]
    get_amt =  db.prepare "SELECT Amount from a_table WHERE Type = :Type" 
    get_amt.execute info_hash[:category]
    get_amt.each do |g| 
        sum += g #here I get a NoMethodError for Nil:NilClass
    end
    db.execute2 "INSERT into bills(Total) values(:sum)", sum
    db.commit
    ...
end

I use mainly the execute2 method. I rely on the execute method where I need to ignore headers, such as in my get_amt.each block.

I want to sum the Amount column for Type. But I run into a NoMethodError when I run my block.

The full error is: undefined method '+' for nil:NilClass (NoMethodError)

Please advise as to where I've gone wrong.

EDIT: I rewrote the code to reflect @Shawn 's suggestion:

def some_method(info_hash)
        ...
        db.transaction
        db.execute2 "CREATE table if not exists a_table(Id INTEGER PRIMARY KEY, Type TEXT, Month TEXT, Amount FLOAT, Total FLOAT)"
        db.execute2 "INSERT into a_table(Type, Month, Amount) values(:Type , :Month , :Amount)", info_hash[:category], info_hash[:month], info_hash[:amount]
        get_amt =  db.execute2 "SELECT sum(Amount) from a_table WHERE Type = :Type", info_hash[:category]
        db.execute2 "INSERT into a_table(Total) values(:get_amt)", get_amt
        db.commit
        ...
end

This yields the sqlite3 Exception Index out of range


Solution

  • db.execute2 "INSERT into a_table(Total) values(:get_amt)", get_amt[1][0]
    

    Essentially statement get_amt = db.execute2 "SELECT sum(Amount) from a_table WHERE type = :type", hash_info[category] writes more than 1 value into get_amt variable. the variable must be provided with therow and column of the specific value that INSERT utilize. Hence get_amt[1][0] Or the first row (next row after headers row) and the first column.