I am having issues working with the schemas in Redshift connecting using R.
url <- "jdbc:url:port/database?user=X123&password=fakepassword"
conn <- dbConnect(driver, url)
so I connect fine, and when I list tables I notice the default schema is public, but I don't want to work with that schema, how do I switch schemas ?
say if it is: lab_space
when I try this, it still lists tables in public:
dbListTables(conn, schema='lab_space')
tried this and I get an error:
SET search_path = lab_space;
> SET search_path = 'cust_usr';
Error: unexpected symbol in "SET search_path"
I must be doing something wrong ?
When I try to say check for a table and delete:
droptable <- dbSendQuery(conn, "drop table if exists lab_space.Tablebla")
it will drop it, but still give me an error:
Error in .verify.JDBC.result(r, "Unable to retrieve JDBC result set for ", :
Unable to retrieve JDBC result set for drop table if exists lab_space.Tablebla ([JDBC Driver]com.amazon.dsi.dataengine.impl.DSISimpleRowCountResult cannot be cast to com.amazon.dsi.dataengine.interfaces.IResultSet)
You can change the schema using dbSendUpdate to change the search_path for the connection:
dbSendUpdate(jdbc_con,"set search_path to my_schema")
ok, on this one I went with this driver
drv <- dbDriver("PostgreSQL")
and then things worked with no stupid warnings errors, I guess R and Redshift still has a lot of growing up to do, not sure :- )
In redshift, you can set the search path with set search_path to <schema_name> (no equals)
dbSendQuery(con,"set search_path to <schema_name>");
You may assign dbSendQuery() result to var if underlying sql returns a resultset. Here drop query doesn't return any result set Object. Try without assigning to any var.
dbSendQuery(conn, "drop table if exists lab_space.Tablebla")
Related
i am using the below code for connecting to PostgreSQL from R.
library(DBI)
con <- dbConnect(RPostgres::Postgres(),dbname = 'postgres',
host = host_name,
port = 5432,
user = user_name,
password = password)
by using the above connection i tried to update the PostgreSQL table with sys.time() in R as character.
For that i am sending the below query to database.
dbSendQuery(con,paste0("update job_status set start_dttm=",as.character(sys.time()) ," where job_name='job';"))
but it throws the following error for me
Failed to prepare query: ERROR: syntax error at or near "04"
LINE 1: update job_status set start_dttm = 2019-03-04 04:50:12 where...
Can anyone help me to tackle this issue.
Thanks in advance.
Valid SQL requires quotes around the date:
update job_status set start_dttm='2019-03-04 04:50:12';
Therefore, you would need
paste0("update job_status set start_dttm='", as.character(sys.time(), "';")
The above query is safe from SQL injection since sys.time() should be safe.
However, in general (and especially when arguments are derived from user input), it is best
to use parametrized SQL to avoid SQL injection.
With the release of dplyr 0.7.0, it is now supposedly easy to connect to Oracle using the odbc package. However, I am running into a problem accessing tables not inside the default schema (for me it is my username). For example, suppose there is the table TEST_TABLE in schema TEST_SCHEMA. Then, example SQL syntax to get data would be: select * from TEST_SCHEMA.TEST_TABLE'.
To do the same in `dplyr, I am trying the following:
# make database connection using odbc: [here's a guide][1]
oracle_con <- DBI::dbConnect(odbc::odbc(), "DB")
# attempt to get table data
tbl(oracle_con, 'TEST_SCHEMA.TEST_TABLE')
Now, this leads to an error message:
Error: <SQL> 'SELECT *
FROM ("TEST_SCHEMA.TEST_TABLE") "zzz12"
WHERE (0 = 1)'
nanodbc/nanodbc.cpp:1587: 42S02: [Oracle][ODBC][Ora]ORA-00942: table or view does not exist
I think the problem here is the double quotation marks, as:
DBI::dbGetQuery(oracle_con, "select * from (TEST_SCHEMA.TEST_TABLE) where rownum < 100;")
works fine.
I struggled with this for a while until I found the solution at the bottom of the introduction to dbplyr. The correct syntax to specify the schema and table combo is:
tbl(oracle_con, in_schema('TEST_SCHEMA', 'TEST_TABLE'))
As an aside, I think the issue with quotation marks is lodged here: https://github.com/tidyverse/dplyr/issues/3080
There are also the following alternate work-arounds that may be suitable depending on what you wish to do. Since the connection used DBI, one can alter the schema via:
DBI::dbSendQuery(oracle_con, "alter session set current_schema = TEST_SCHEMA")
after which tbl(oracle_con, 'TEST_TABLE') will work.
Or, if you have create view privileges, you can create a "shortcut" in your default schema to any table you are interested in:
DBI::dbSendQuery(oracle_con, "CREATE VIEW TEST_TABLE AS SELECT *
FROM TEST_SCHEMA.TEST_TABLE")
Note that the latter may be more suitable for applications where you wish to copy local data to the database for a join, but do not have write access to the table's original schema.
I have a synonym statement:
CREATE OR REPLACE SYNONYM sample-table-name FOR master.sample-table-name
I want to execute this by using R language using RJDBC library. I've tried different functions including dbGetQuery function etc. But it is not able to execute this statement.
Could someone please advise on how to execute these statements in R.
I would expect that using dbExecute() should work. Failing that, dbSendStatement() should almost certainly work, as it seems to be intended for that sort of DDL.
The docs on dbGetQuery say:
This method is for SELECT queries only
To look at the functions that are available to you, it can be helpful to do something like ls('package:DBI'). Per the docs:
dbExecute:
Executes a statement and returns the number of rows affected.
dbExecute() comes with a default implementation (which should work
with most backends) that calls dbSendStatement(), then
dbGetRowsAffected(), ensuring that the result is always free-d by
dbClearResult().
dbSendStatement:
The dbSendStatement() method only submits and synchronously executes
the SQL data manipulation statement (e.g., UPDATE, DELETE, INSERT
INTO, DROP TABLE, ...) to the database engine. To query the number of
affected rows, call dbGetRowsAffected() on the returned result object.
You must also call dbClearResult() after that. For interactive use,
you should almost always prefer dbExecute().
EDIT: Those methods will likely work for other implementations of DBI, and perhaps for RJDBC in the future. In any case, it looks like they have implemented dbSendStatement() using dbSendQuery(), so they will not work for this purpose.
In the RJDBC framework, dbSendUpdate() is what you want.
dbSendQuery and dbSendUpdate submit a SQL query to the database. The
difference between the two is only that dbSendUpdate is used with DBML
queries and thus doesn't return any result set.
Confirmed using a similar query on another DBMS:
dbSendStatement(conn,'SET search_path=public;')
#Error in .verify.JDBC.result(r, "Unable to retrieve JDBC result set for ", :
#Unable to retrieve JDBC result set for SET search_path=public; (No results were returned by the query.)
traceback()
#7: stop(..., " (", .jcall(x, "S", "getMessage"), ")")
#6: .verify.JDBC.result(r, "Unable to retrieve JDBC result set for ",
# statement)
#5: .local(conn, statement, ...)
#4: dbSendQuery(conn, statement, ...)
#3: dbSendQuery(conn, statement, ...) ## this is the problem
#2: dbSendStatement(conn, "SET search_path=public;")
#1: dbSendStatement(conn, "SET search_path=public;")
dbSendUpdate(conn, 'SET search_path=public;')
# successful
dbCommit(conn)
# persist the change past the current session (RJDBC seems to give you transaction control here)
I am trying to upload data from R to database, I used package 'RJDBC' to connect R to Oracle. The connection is set up and I am able to load data from Oracle to R. When I tried to insert data into a table in Oracle using dbSendStatement():
sqlQuery_uploadResult<-function(A,B,C,D,E,F,G,H,I){
sprintf("INSERT INTO DEMAND_FCAST (A,B,C,D,E,F,G,H,I) VALUES (TO_DATE('%s','DD-MON-YY hh24:mi:ss'),%1.4f,%5.2f,%2.0f,%1.4f,%5.2f,%2.0f,%2.0f)",A,B,C,D,E,F,G,H,I)
}
dbSendStatement(conn,sqlQuery_uploadResult(A,B,C,D,E,F,G,H,I))
I got an error message:
Error in .verify.JDBC.result(md, "Unable to retrieve JDBC result set meta data for ", :
Unable to retrieve JDBC result set meta data for INSERT INTO DEMAND_FCAST (A,B,C,D,E,F,G,H,I) VALUES (TO_DATE('17-Oct-16 13:35:45','DD-MON-YY hh24:mi:ss'),0.1160,700,36,0.4037,965,35, 1) in dbSendQuery (ORA-00900: invalid SQL statement
)
However, I checked the table in Oracle, the record I tried to insert is in the table, is there anyone has any clue why does this error turn out and how to deal with this?
I was having the same issue. I tried dbExecute() and dbSendQuery() and got a similar error. A colleague suggested that I use dbSendUpdate() and it executed without error.
I'm using RJDBC to connect to a local database. This allows me to make SELECT queries easily using dbGetQuery, and CREATE TABLE using dbWriteTable.
However, I cannot figure out a method to DROP TABLE or DELETE or SELECT INTO directly from my R console. These things work when I do it directly in SQL Developer, but not when I pass the query onto the database from R.
How do I perform database record manipulations which are not SELECT statements using R?
I'd try using a different type instead.
dbGetQuery bases itself on finding and iterating over the DB rather than manipulating it's records.
Similar questions were asked before;
I couldn't find a nice R example, but if it helps, A nice java example could be found here:
EDIT:
I found the type I was talking about! Took me a while, anyhow - sqlQuery allows you to run pretty much any query, that is - a change in the DB records. Example I modified from this source:
res <- sqlQuery(con1,"DELETE TABLE TESTDATA", errors=FALSE)
# res will now hold the result of the query.
# -1 means error, otherwise iteration is sucessful, and it will hold the number of rows affected.
if (res == -1){ #if something messed up
cat ("An error has occurred.\n")
msg <- odbcGetErrMsg(con1) #Use your connection for this.
print (msg)
} else {
cat ("Table was deleted successfully.\n")
}
EDIT 2:
I got it confused with RODBC, however there's no reason to worry, since I found the RJDBC alternative as well! It's called, dbSendUpdate. Example:
# Assuming you have the connection saved as conn; these example shows how to use dbSendUpdate to create tables and insert values.
# You could use it with every non-selective query, that is, which manipulates the record (update,delete,insert,drop etc.)
# create table, with dbSendUpdate:
dbSendUpdate(conn, "CREATE TABLE foo(a INT,b VARCHAR(100))")
# insert value, bind parameters to placeholders in statement:
dbSendUpdate(conn, "INSERT INTO foo VALUES(?,?)", 42, "bar")
# feel free to modify the query itself, these are just example values.
this is similar to another answered question here
basically dbGetQuery() as it name implies is used to send queries and recive their result.
if you want to send a general statement to the db like 'drop table' etc.
you can use:
dbSendUpdate(connection_object, "drop table table_name")