I would like to call a stored procedure from a function in R. See my code below. unfortunately this code only generates a dataframe without values in it. I would like to fix this with RJDBC&DBI, since there seems to be a problem with RODBC.
RPT_09_Hourly_Connected_v3<- function(Year, Month="NULL",State = "NULL",Region="NULL", City="NULL", District="NULL", Subdistrict="NULL" ,Address='NULL'){
drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver", "/opt/sqljdbc_3.0/sqljdbc4.jar")
conn <- DBI::dbConnect(drv, "jdbc:sqlserver://***;databaseName=***;user=***;password=***")
sqlText <- paste("exec [dbo].[RPT_09_Hourly_Connected_v3]#Year=",Year,
",#Month=",Month,
",#State=",State,"",
",#Region=",Region,"",
",#City=N'",City,"'",
",#District=",District,"",
",#Subdistrict=",Subdistrict,"",
",#Address=N'",Address,"'",
sep="")
data <- RJDBC::dbGetQuery(conn,sqlText)
}
a<- RPT_09_Hourly_Connected_v3(Year = 2016)
> str(a)
'data.frame': 0 obs. of 9 variables:
$ Regio : chr
$ Stad : chr
$ Stadsdeel : chr
$ Buurtcombinatie: chr
$ Adres : chr
$ Jaar : num
$ Maand : num
$ hourNR : num
$ HoursConnected : num
This worked for me before RODBC crashed. Is there any difference between RODBC and RJDBC?
RPT_09_Hourly_Connected_v3<- function(Year, Month="NULL",State = "NULL",Region="NULL", City="NULL", District="NULL", Subdistrict="NULL" ,Address='NULL'){
dbhandle <- odbcConnect("***;DATABASE=***;UID=***;PWD=***")
data <- sqlQuery(dbhandle,paste("exec [ dbo].[RPT_09_Hourly_Connected_v3]#Year=",Year,
",#Month=",Month,
",#State=",State,"",
",#Region=",Region,"",
",#City=N'",City,"'",
",#District=",District,"",
",#Subdistrict=",Subdistrict,"",
",#Address=N'",Address,"'",
sep=""))
odbcCloseAll()
data
}
If I execute the stored procedure in SQL Server by hand it will look like this:
EXEC #return_value = [dbo].[RPT_09_Hourly_Connected_v3]
#Year = 2016,
#Month = NULL,
#State = NULL,
#Region = NULL,
#City = N'Amsterdam',
#District = NULL,
#Subdistrict = NULL,
#Address = NULL
Can you explain what's wrong and how to fix it?
I find the RODBCext a lot easier to use since it uses parameter binding. It also makes it easier to use NA in place of "NULL" and eliminates the concern about matching up the quote characters correctly.
library(RODBCext)
RPT_09_Hourly_Connected_v3<- function(Year, Month=NA, State = NA, Region=NA, City=NA, District=NA, Subdistrict=NA ,Address=NA){
ch <- odbcDriverConnect([connection_string])
sqlText <- paste("exec [dbo].[RPT_09_Hourly_Connected_v3]#Year=? ",
",#Month=? ",
",#State=? ",
",#Region=? ",
",#City=? ",
",#District=? ",
",#Subdistrict=? ",
",#Address=? ",
sep="")
sqlExecute(channel = ch,
query = sqlText,
data = list(Year, Month, State, Region, City, District, Subdistrict, Address),
fetch = TRUE,
stringAsFactors = FALSE)
}
I found a very easy solution, and I wish I knew this before! Maybe I can help someone else with my answer.
FACT_CHARGESESSION<- function (username, password, country = "NULL",state = "NULL", region = "NULL",city = "NULL",
district = "NULL",subdistrict = "NULL", provider= "NULL",startDateView = "NULL",endDateView = "NULL") {
InstallCandidates <-c("DBI","rJava","RJDBC","dplyr")
toInstall<-InstallCandidates[!InstallCandidates %in% library()$results[,1]]
if(length(toInstall) !=0){install.packages(toInstall,repos="http://cran.r-project.org")}
lapply(InstallCandidates,library,character.only=TRUE)
rm("InstallCandidates","toInstall")
NAME <- "dbo.R_00_ValidTransactions_ID_PW_v4"
options(java.parameters = "- Xmx1024m")
drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver", "/opt/sqljdbc_3.0/sqljdbc4.jar")
conn <- dbConnect(drv, "jdbc:sqlserver://***.**.***.***;databaseName=****;user=***;password=***")
# Make a SQL text
sqlText <- paste(NAME, paste(username,password, country,state,region,city,district,subdistrict,provider,startDateView,endDateView,sep=","))
data <- dbGetQuery(conn,sqlText)
return(data)
}
output of sqlText:
"dbo.R_00_ValidTransactions_ID_PW_v4 M.Kooi , Stackoverflow , NULL , NULL , Amsterdam , NULL , NULL , NULL , NULL , NULL , NULL "
Instead of using the SP execute window you just execute now the SP with the paremters in a new query window.
I've used this in the past successfully with RJDBC:
d <- dbGetQuery(conn, paste0("exec my_STOREDPROC #Field1= '",Field1,"';"))
It might be simply a matter of syntax. Hard to tell w/o a reproducible example. Note the extra set of quotes.
Related
I have the following dataframe which contains the AxiomaID.
x<-c(0123, 234, 2348, 345, 3454)
And trying to run the following SQL Query within R.
SQL6<-data.frame(sqlQuery(myConn, "SELECT top 10 [AxiomaDate]
,[RiskModelID]
,[AxiomaID]
,[Factor1]
FROM [PortfolioAnalytics].[Data_Axioma].[SecurityExposures]
Where AxiomaID = x"))
How can I paste all the x values which contain the AxiomaID's into the SQL Query?
Try the following query:
SQL6<-data.frame(sqlQuery(myConn, paste("SELECT top 10 [AxiomaDate]
,[RiskModelID]
,[AxiomaID]
,[Factor1]
FROM [PortfolioAnalytics].[Data_Axioma].[SecurityExposures]
Where AxiomaID IN (", paste(x, collapse = ", "), ")")))
Hope it helps!
You would try a function like
InsertListInQuery <- function(querySentence, InList) {
InValues <- ""
for (i in 1:length(InList)){
if (i < length(InList)) {
InValues <- paste(InValues,InList[[i]],",")}
else {
InValues <- paste(InValues,InList[[i]],sep = "")
}
}
LocOpenParenthesis <- gregexpr('[(]', querySentence)[[1]][[1]]
LocCloseParenthesis <- gregexpr('[)]', querySentence)[[1]][[1]]
if (LocCloseParenthesis-LocOpenParenthesis==1) {
querySentence<- gsub("[(]", paste("(",InValues,sep = ""), querySentence)
}
return (querySentence )
}
Function InsertListInQuery requires you to change your original query to one that use constraint IN () in WHERE clausule. What function does is to conform a string with vector elements separated by comma, and replace "(" string with the one composed. Finally, return a character variable.
Hence, you can define your vector of constraints list of elements, your query and call the function as shown:
x<-c(0123, 234, 2348, 345, 3454)
query <- "SELECT top 10 [AxiomaDate]
,[RiskModelID]
,[AxiomaID]
,[Factor1]
FROM [PortfolioAnalytics].[Data_Axioma].[SecurityExposures]
Where AxiomaID IN ()"
finalQuery <- InsertListInQuery(query, x)
Value of finalQuery is:
finalQuery
[1] "SELECT top 10 [AxiomaDate] \n ,[RiskModelID]\n,[AxiomaID]\n,[Factor1]\nFROM [PortfolioAnalytics].[Data_Axioma].[SecurityExposures]\nWhere AxiomaID IN ( 123 , 234 , 2348 , 345 ,3454)"
Note the line return with special character \n.
I hope it may help.
I'm trying to create a report in BIRT. I've created a stored proc in SQL Server 2008 which works perfectly. However, when I try to run the report in BIRT, it won't run with NULL value.
var DepartmentValue = params["DepartmentValue"].value;
var AccountValue = params["AccountValue"].value;
sqlText = " EXEC SP_Report_ByDept '"+DepartmentValue+"','"+AccountValue+"','"+startdt+"','"+enddt+"' ";
Works perfectly if there is a valid AcccountValue. Any idea how to pass null value for the AccountValue?
Cheers.
If I understand it correctly you want to pass the string 'null' when the actual parameter is null?
var DepartmentValue = params["DepartmentValue"].value;
var AccountValue = params["AccountValue"].value;
if (AccountValue == null){
AccountValue = 'null';
}
sqlText = " EXEC SP_Report_ByDept '"+DepartmentValue+"','"+AccountValue+"','"+startdt+"','"+enddt+"' ";
I do not understand the error which appears in my SQL Query. If i choose in SQL
Select * -> it is working fine and i do get the table,
however if i select any of the column/s it is giving me an Error:
Error in $<-.data.frame(*tmp*, "PROBE", value =
structure(integer(0), .Label = character(0), class = "factor")) :
replacement has 0 rows, data has 1427
Here is my SQL code:
if(input$filter == 1){
sqlOutput <- reactive({
sqlInput <- paste("select * from DWH.PROBE where DWH.PROBE.Nr =",paste0("'",d(),"'"), "And DWH.PROBE.AB BETWEEN",input$abmfrom, "AND",input$abmto,"ORDER BY Datum asc")
print(sqlInput)
dbGetQuery(con$cc, sqlInput)
})
}else{
sqlOutput <- reactive({
sqlInput <- paste("select * from DWH.PROBE where DWH.PROBE.S BETWEEN",d2(), "AND",input$sgehalt2, "And DWH.PROBE.AB BETWEEN",input$abmfrom2, "AND",input$abmto2,"ORDER BY Datum asc")
dbGetQuery(con$cc, sqlInput)
})}
And if i just add to those SQL Queries
select DWH.PROBE.S, DWH.PROBE.AB.. from DWH.PROBE
Then it comes above mentioned Error.
Additionally i need to say if i will use this SQL Query in a simple code:
rs <- dbSendQuery(con, paste("select DWH.PROBE.AB, DWH.PROBE.S from DWH.PROBE where DWH.PROBE.Nr = '50' And DWH.PROBE.AB BETWEEN 40 AND 50 ORDER BY Datum asc"))
data <- fetch(rs)
It is giving me the results...
Any ideas?
[EDIT *as my question is not a duplicate]
The question posted here: http://stackoverflow.com/questions/32048072/how-to-pass-input-variable-to-sql-statement-in-r-shiny actually has nothing to do with my topic. As we can see the error in this post:
Error in .getReactiveEnvironment()$currentContext() : Operation not
allowed without an active reactive context. (You tried to do something
that can only be done from inside a reactive expression or observer.)
I do not have a problems with passing input variable to sql statement and additionally if you can see in my SQL: The Query is in reactive context!:
sqlOutput <- reactive({...
The solution for above question was:
to put SQL Query in reactive context which is not a thing in my case
[EDIT 2] -> bits related to sqlOutput()
Here is a bit of code related to sqlOutput() which i am using in my Shiny App (at the moment this is the only bit because i am stuck with SQL Query)
output$tabelle <- DT::renderDataTable({
data <- sqlOutput()
data$PROBE <- as.factor(as.character(data$PROBE))
data
}, rownames=TRUE, filter="top", class = 'cell-border stripe',
options = list(pageLength = 100, lengthMenu=c(100,200,500), columnDefs = list(list(width = '200px', targets = "_all"),list(bSortable = FALSE, targets = "_all"))))
Thanks
Error doesn't relate to SQL statements, however, try changing your code to below:
sqlOutput <- reactive({
if(input$filter == 1){
sqlInput <- paste("select * from DWH.PROBE where DWH.PROBE.Nr =",paste0("'",d(),"'"), "And DWH.PROBE.AB BETWEEN",input$abmfrom, "AND",input$abmto,"ORDER BY Datum asc")
} else {
sqlInput <- paste("select * from DWH.PROBE where DWH.PROBE.S BETWEEN",d2(), "AND",input$sgehalt2, "And DWH.PROBE.AB BETWEEN",input$abmfrom2, "AND",input$abmto2,"ORDER BY Datum asc")
}
dbGetQuery(con$cc, sqlInput)
})
I have a table in a lua file.
This is the table:
main = {}
main["first"] = {
{name = "sammy", type = "dog", age = 2, color = "blue"},
{name = "tom", type = "cat", age = 3, color = "orange"},
.
.
.
.
}
main["second"] = {
{name = "grim", type = "cow", age = 1, color = "green"},
{name = "jerry", type = "horse", age = 2, color = "grey"},
.
.
.
.
}
The table has two tables. I want to read all tables in main. So I wrote this code. (I use delphi. plua_state means pointer of lua_state)
This is my code:
procedure TForm1.PrintTable(l: Plua_State);
var
TempStr : String;
begin
lua_pushnil(l);
TempStr := '';
while lua_next(l,-2) <> 0 do
begin
case lua_type(l,-1) of
LUA_TTABLE :
PrintTable(l);
else
TempStr := TempStr + lual_checkstring(L, -2) + '='
+ lua_typename(L, lua_type(L, -1)) + ',';
end;
lua_pop(l,1);
end;
fStringList.Add(TempStr);
end;
This code prints the key and value type in the main table.However, If I change lua_typename(L, lua_type(L, -1)) to lual_checkstring(L, -1), It does not work. I want to print the key and value.
How can I print the value?
You must be careful when using lua_next as several string API functions will alter the value on the stack which confuses lua_next. From the manual:
While traversing a table, do not call lua_tolstring directly on a key, unless you know that the key is actually a string. Recall that lua_tolstring may change the value at the given index; this confuses the next call to lua_next.
So, calling lua_tostring, lua_tolstring, or luaL_checklstring on a key pushed by lua_next will change the key into a string.
As you have discovered it is best to use lua_type to make sure the value is indeed a string before calling lua_tolstring (or any API function that calls it), or push a copy of the key which can be popped leaving the original key returned by lua_next unmodified.
I am running a stored procedure in MS SQL using perl
The return value is an integer (0 = if ok, and some negative values if it exited early at certain points)
while the code runs the SP - it doesn't give me the return value at all.
my code:
use dbd::odbc;
#...
$dbh->do("use XXX"); #Name of the DB
my $sth = $dbh->prepare( "
DECLARE \#return_value int
EXEC \#return_value = [dbo].[test1]
\#BeginDate = '11/11/2011',
\#EndDate = '11/11/2011'
select \#return_value
");
$sth->execute( );
#### AFTER THIS I TRIED:
while ( #dbrow = $sth->fetchrow_array( ) ) {
$return_value = #dbrow[0]
}
#### i also tried:
my $return_value = $sth->fetchrow_array( )
#### both get nothing.
When I use regular SELECT queries, both of the above work.
What does it return? Try this:
while ( #dbrow = $sth->fetchrow_array( ) ) {
use Data::Dumper;
$Data::Dumper::Useqq = 1;
print Dumper( { "got row" => \#dbrow } );
}
Try executing the procedure in SQL server and make sure it returns
atleast one record
Check the return value of the execute statement, print error if it is not successful
$sth->execute() or die "Couldn't execute: " . $sth->errstr;
Check the number of rows from sth
if ($sth->rows == 0) {print "Zero records"}
I'm not sure if this helps but can you try this one.
while ( $row_ref = $sth->fetch_arrayref() ) {
my $return_value = $row_ref->[0];
print $return_value;
}