I\'m having trouble creating a table using RODBC\'s sqlSave (or, more accurately, writing data to the created table).
This is different than the existing sqlSave qu
After re-reading the RODBC vingette and here's the simple solution that worked:
sqlDrop(db, "df", errors = FALSE)
sqlSave(db, df)
Done.
After experimenting with this a lot more for several days, it seems that the problems stemmed from the use of the additional options, particularlly table =
or, equivalently, tablename =
. Those should be valid options but somehow they manage to cause problems with my particular version of RStudio ((Windows, 64 bit, desktop version, current build), R (Windows, 64 bit, v3), and/or MS SQL Server 2008.
sqlSave(db, df)
will also work without sqlDrop(db, "df")
if the table has never existed, but as a best practice I'm writing try(sqlDrop(db, "df", errors = FALSE), silent = TRUE)
before all sqlSave
statements in my code.
I've encountered the same problem-- the way I found around it is to create the an empty table using regular CREATE TABLE
SQL syntax, and then append to it via sqlSave
. For some reason, when I tried it your way, I could actually see the table name in the MSSQL database - even after R threw the error message you showed above - but it would be empty.
Here are a few rules of thumb:
columnTypes <- list(Record = "VARCHAR(10)", Case_Number = "VARCHAR(15)", Claim_Type = "VARCHAR(15)", Block_Date = "datetime", Claim_Processed_Date = "datetime", Status ="VARCHAR(100)")
sqlSave(myconn2, MainClmDF2, tablename = "##R_Claims_Data", verbose=TRUE, rownames= FALSE, varTypes=columnTypes)
VARCHAR(255)
. Treat this as a temp or staging table, and move the data over with sqlQuery
with your next step, just as @danas.zuokas suggested. This should work, but even if it doesn't, it gets you closer to the metal and puts you in better position to debug the problem with SQL Server Profiler if you need it. <- And yes, if you still have a problem, it's likely due to either a parsing error or type conversion.columnTypes <- list(Record = "VARCHAR(255)", Case_Number = "VARCHAR(255)", Claim_Type = "VARCHAR(255)", Block_Date = "VARCHAR(255)", Claim_Processed_Date = "VARCHAR(255)", Status ="VARCHAR(255)")
sqlSave(myconn2, MainClmDF2, tablename = "##R_Claims_Data", verbose=TRUE, rownames= FALSE, varTypes=columnTypes)
sqlQuery(channel, 'insert into real_table select * from R_Claims_Data')
logical
type (i.e. [TRUE, FALSE]
) will not convert to T-SQL's BIT
type (i.e. [1, 0]), so don't try this. Either convert the logical
type to [1, 0] in the R layer or take it down to the SQL layer as a VARCHAR(5)
and convert it to a BIT
in the SQL layer. After hours of working on this, I was finally able to get sqlSave to work while specifying the table name--deep breathe, where to start. Here is the list of things I did to get this to work:
odbcConnection(Name)
. Here is my code myconn2 <- odbcConnect("SYSTEMDB")
.columnTypes <- list(Record = "VARCHAR(10)", Case_Number = "VARCHAR(15)", Claim_Type = "VARCHAR(15)", Block_Date = "datetime", Claim_Processed_Date = "datetime", Status ="VARCHAR(100)")
.as.character
and as.Date
to match the data types listed above.sqlDrop(myconn2, "##R_Claims_Data")
.sqlSave(myconn2, MainClmDF2, tablename = "##R_Claims_Data", verbose=TRUE, rownames= FALSE, varTypes=columnTypes)
Then my head fell off because it worked! I really hope this helps someone going forward. Here are the links that helped me get to this point:
Table not found
sqlSave in R
RODBC
In addition to some of the answered posted earlier, here's my workaround. NOTE: I use this as part of a small ETL process, and the destination table in the DB is dropped and recreated each time.
Basically you want to name your dataframe what you destination table is named:
RodbcTest <- read.xlsx('test.xlsx', sheet = 4, startRow = 1, colNames = TRUE, skipEmptyRows = TRUE)
Then make sure your connection string includes the target database (not just server):
conn <- odbcDriverConnect(paste("DRIVER={SQL Server};Server=localhost\\sqlexpress;Database=Charter;Trusted_Connection=TRUE"))
after that, I run a simple sqlQuery that conditionally drops the table if it exists:
sqlQuery(conn, "IF OBJECT_ID('Charter.dbo.RodbcTest') IS NOT NULL DROP TABLE Charter.dbo.RodbcTest;")
Then finally, run sqlSave without the tablename param, which will create the table and populate it with your dataframe:
sqlSave(conn, RodbcTest, safer = FALSE, fast = TRUE)
We have had this same problem, which after a bit of testing we solved simply by not using square brackets in the schema and table name reference.
i.e. rather than writing
table = "[Jason].[dbo].[df]"
instead write
table = "Jason.dbo.df"
Appreciate this is now long past the original question, but just for anyone else who subsequently trips up on this problem, this is how we solved it. For reference, we found this out by writing a simple 1 item dataframe to a new table, which when inspected in SQL contained the square brackets in the table name.