Send multiple parameters to SQL Server using dbBind in R - r

I am working on a program that has to send data to Microsoft SQL Server through R. Since SQL Server doesn't have any INSERT OR IGNORE INTO like PostgreSQL, I have to check if the value is already in the table. However, I don't know if I'm doing it right. How do I send multiple parameters (or the same parameter twice) into SQL Server using dbBind?
Here is my code:
statement <- "IF NOT EXISTS (SELECT * FROM dbo.nodes WHERE node_id=?) INSERT INTO dbo.nodes (node_id) VALUES (?)"
insertnew <- dbSendQuery(conn, statement)
test_p1 <- list(5, 6)
test_p2 <- list(test_p1, test_p1)
dbBind(insertnew, params=test_p2)
When I run it it gives me the following error:
Error in result_bind(res#ptr, params, batch_rows) :
RAW() can only be applied to a 'raw', not a 'double'
Using RStudio's Show Traceback feature, it shows this:
result_bind(res#ptr, params, batch_rows)
.local(res, params, ...)
dbBind(insertnew, params = test_p1)
Does anybody know what I'm doing wrong here? If the parameters should be something other than a list of lists, what should they be? Is there a way to name parameters to use twice in the same statement? What is RAW() and what is it trying to apply it to?
dbo.nodes is a table with one column, node_id NVARCHAR(1000) NOT NULL PRIMARY KEY.
conn is a DBIConnection object created earlier using dbConnect(odbc::odbc(), ...). It works for executing other statements so there shouldn't be a problem there.
Adding the argument batch_rows=1 to dbBind doesn't change anything (not that I understand what that is supposed to do).
Thanks in advance for the help!

test_p1 = c(5, 6)
test_p2 = unname(data.frame(I(test_p1), I(test_p1)))
In case this helps someone looking this up later, changing it from a list of lists to a data frame made from vectors worked.

Related

Julia Querying from SQLite

Following this tutorial https://www.youtube.com/watch?app=desktop&v=qUrtLJcehE0, I created a database called Movies. Within the database a table called movies was created and next an entry was also added,
using SQLite
db = SQLite.DB("Movies")
SQLite.execute(db,"CREATE TABLE IF NOT EXISTS movies(movie_id REAL,movie_name TEXT, location TEXT)")
SQLite.execute(db,"INSERT INTO movies (movie_id,movie_name,location) VALUES(1,'Avengers','USA')")
However now when I try to Query the entry as follows,
SQLite.Query(db, "SELECT * from movies")
I get the this error, Error: MethodError: no method matching SQLite.Query.(::SQLite.DB,::String).
Any Ideas what I am doing wrong?
I don't know SQL, but I think you want to use SQLite.execute again not SQLite.Query. SQLite.Query is a struct not a function, and it doesn't have any documentation. I don't think you are meant to call it externally. Further documentation is here.
Method error means you are calling something with the wrong arguments. The SQLite.Query struct expects all of the following arguments:
struct Query
stmt::Stmt
status::Base.RefValue{Cint}
names::Vector{Symbol}
types::Vector{Type}
lookup::Dict{Symbol, Int}
end
The SQLite.execute function expects arguments in one of these forms:
SQLite.execute(db::SQLite.DB, sql, [params])
SQLite.execute(stmt::SQLite.Stmt, [params])
By convention in Julia, functions are all lowercase and types are capitalized.
To load a table using SQLite package,
using SQLite
using DataFrames
# Make a connection
db = SQLite.DB("Movies")
# To find out all tables available in schema
tbls = SQLite.tables(db)
# To load a specific table (movies table from Movies.db)
q = "SELECT * FROM movies"
data = SQLite.DBInterface.execute(db,q)
# To get as a dataframe
df = DataFrames.DataFrame(data)

difference between 2 syntaxes of the 'reactive' instruction

warning: I'm pretty new to R, sniny and co ==> I don't realize whether this question is interesting.
update : It turns out that it is a shiny question and it seems to be a frequent problem, that is not obvious. Please read all answers, they don't address the same cases.
I have a Data base in DB. Is there a difference between DBtoto <- reactive({DB()}) and DBtoto <- reactive({DB}) ? If so, what is it ?
In fact I don't see what BD() (with parentheses) means.
Yes, there's a difference. DB() is a call to the function named DB. DB is the function itself. If it's not a function, then DB() doesn't make sense, and will trigger a run-time error (unless there's another object somewhere which is a function).
reactive() is a Shiny function, that says the value of its argument may change over time. Usually it would make more sense to think the value of the function call would change, but it's (remotely) possible that the function itself could change.
I also found the first answer of What is “object of type ‘closure’ is not subsettable” error in Shiny? addresses this question. To summary, everything created with 'reactive()' in shiny must be referred as a function.
In my example, if DB was reactive (for instance DB <- reactive(read_DataBase())), then DB() must be referred with parenthesis. For instance, to get the attribute 'x', you must write BD()$x. In my 'DBtoto' example above the first expression holds in the case DB is itself reactive.

how do you check if a lists exists or not?

I am reading an html table. As a result, sometimes I get one list and sometimes I get two lists.
url<-c("example.com/table")
q <- html(url1) %>% html_table(fill=T)
if(exists('q[[2]]')){
I need to put in a check that if q[[2]] exists do something, if now just process q[[1]]
I tried exists and
if(!is.na(q[[2]]))
I get this error on both:
Error in q[[2]] : subscript out of bounds
how do you check if lists exists or not?

R - Assigning "NA" to objects 'not found' inside a function; is it possible?

I am running a data set (in the example, "data object ") through several different functions in R and concatenating the numeric results at the end. See:
a<-median((function1(x=1,dataobject,reps=500)),na.rm=TRUE)
b<-median((function2(x=1,dataobject,reps=500)),na.rm=TRUE)
c<-median((function3(x=1,dataobject,reps=500)),na.rm=TRUE)
d<-median((function4(x=1,dataobject,reps=500)),na.rm=TRUE)
e<-median((function5(x=1,dataobject,reps=500)),na.rm=TRUE)
f<-median((function6(x=1,dataobject,reps=500)),na.rm=TRUE)
c(a,b,c,d,e,f)
However, some of the functions cannot be run with the data set I am using, and so they return an error; e.g. "function3" can't be run so when it gets to the concatenation step it gives "Error: object 'e' not found" and does not return anything. Is there any way to tell R at the concatenation step to assign a value of "NA" to an object that is not found and continue to run the rest of the code instead of stopping? So that the return would be
[1] 99.233 75.435 77.782 92.013 NA 97.558
A simple question, but I could not find any other instances of it being asked. I originally tried to set up a function to run everything and output the concatenated results, but ran into the same problem (when a function can't be run, the entire wrapper function stops as well and I don't know how to tell R to skip something it can't compute).
Any thoughts are greatly appreciated! Thanks!
A couple of solutions I can think of,
Initialize all the variables you plan to use, so they have a default value that you want.
a = b = c = d = e = NA
then run your code. If an error pops up, you will have NA in the variable.
Use "tryCatch". If you are unaware what this is, I recommend reading on it. It lets you handle errors.
Here is an example from your code,
tryCatch({
a<-median((function1(x=1,dataobject,reps=500)),na.rm=TRUE)
},
error = function(err){
print("Error in evaluating a. Initializing it to NA")
a <<- NA
})

Passing Optional Arguments in Classic ASP for Stored Procedure

I'm trying to run some stored queries in an Access database from an ASP page. I'd like to use an ADO Command object to run the procedure instead of simply sending a string to the database to execute. My trouble is occurring when I try to create the parameters to send to the stored procedure. I'm using the 'CreateParameter' method of the Command object. It takes 5 optional arguments, of which I only want to use two; name and value (arguments 1 and 5 respectively).
I've tried the following approaches to set up the parameters:
1) Using named arguments
command.Parameters.Append command.CreateParameter name:="name", value:="value"
2) Using named arguments inside brackets
command.Parameters.Append command.CreateParameter(name:="name", value:="value")
3) Leaving out optional parameters I don't need
command.Parameters.Append command.CreateParameter("name", , , , "value")
What is a simple way to achieve what I'm trying to do, and why does my syntax fail in these cases? I'm clearly missing something here!
VBScript doesn't support named arguments with or without brackets. All parameters required to pass (specific or blank) for CreateParameter method of the Command object.
For the section 3 in the question, have a look:
CreateParameter(
name`[optional], <- fits ("name")
type [optional, default = adEmpty], <- NOT fits (type is not empty)
direction[Optional default = adParamInput], <- fits (blank)
size [optional default = 0], <- NOT fits (at least 5 for "value")
value[optional] <- fits ("value")
)
So, you should specify at least type and size for a text valued parameter. Direction is adParamInput already.
Const adVarChar = 200 ' From adovbs.inc or Ado TypeLib
command.Parameters.Append command.CreateParameter("name", adVarChar, , 5, "value")
here is an example that can be followed.
http://www.webconcerns.co.uk/asp/accessqueries/accessqueries.asp
see also
http://bytes.com/topic/asp-classic/answers/628368-running-access-stored-queries-parameters
Remember access uses stored queries not stored procedures so some differences apply. For additional information search for
ASP with Access stored queries using parameters - .net

Resources