1

I've a data.frame in R - matches with some 1000+ rows

names(matches)
[1] "name"  "c_id"  "fname" "lname" "address" "zip_code"    "Weight"

nrow(matches)
[1] 1253

I have a postgresql database table - list_m with following columns

db_name, db_cid, db_weight, processing_status, request_id, fname, mname, lname, etc.

I want to udpate the values of only few columns (db_c_id, db_weight and processing status) in the table using values from the data.frame.

As of now, I am looping over the data.frame to create the update queries and then run the queries.

for(row in 1:nrow(matches) {   
    query1 <- paste0(query1, "UPDATE list_m SET db_name = ",matches$name[row],", db_weight = ",matches$weight[row],",  processing_status = 'MATCHED'
 WHERE request_id=111 AND db_c_id = '", matches$c_id[row], "';")
}

so it basically creates a query1 variable with

 UPDATE list_m SET db_name = 'HILLARY', db_weight = 51.41, processing_status = 'MATCHED' WHERE request_id=111 AND db_c_id = '1015310246';

 UPDATE list_m SET db_name = 'SANDERS', db_weight = 45.16, processing_status = 'MATCHED' WHERE request_id=111 AND db_c_id = '1015120982';

 ...

 ...

 ...

 UPDATE list_m SET db_name = 'OBAMA', db_weight = 67.11, processing_status = 'MATCHED' WHERE request_id=111 AND db_c_id = '1015110111'; 

 UPDATE list_m SET db_name = 'TRUMP', db_weight = 41.22, processing_status = 'MATCHED' WHERE request_id=111 AND db_c_id = '1013024634';

which will then be executed using

dbSendStatement(con, query1)

What I would like is to do this by parameterizing the values.. something like

query2 <- "UPDATE list_m SET db_name=?,db_weight=?,processing_status='MATCHED' WHERE request_id=111 and db_c_id=?";

dbSendStatement(con, query2, matches$name, matches$weight, matches$c_id)

this statement should execute for each row of matches data.frame.

1
  • con is the db connection string: > drv <- dbDriver("PostgreSQL") > con <- dbConnect(drv, dbname=config$db$name,host=config$db$host,port=config$db$port,user=config$db$user,password=config$db$pass ) Commented Dec 21, 2016 at 14:24

1 Answer 1

3

This could be closely approximated using sprintf

sql_string <- "UPDATE list_m SET db_name = %s, db_weight = %s,  processing_status = 'MATCHED' WHERE request_id=111 AND db_c_id = '%s';"

dbSendStatement(con, paste(sprintf(sql_string, matches$name, matches$weight, matches$c_id), collapse=""))
Sign up to request clarification or add additional context in comments.

4 Comments

@Parfait changed answer to approximate parameters using sprintf
I thought your approach was great. Just needed to adhere to Postgres syntax and advise OP to export dataframe as temp table, altogether avoiding for loop.
This approach is great! Would it be possible with named parameters instead of just relying on the parameter order?
@SunWuKung the command could be wrapped in a function which would make it possible to used named parameters. However, the function will revert back to parameter order if the parameter names are not used when calling the function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.