SAS connection to Teradata Database using Teradata ODBC - odbc

I'm trying to connect to Teradata in SAS. I set up an teradata ODBC on the machine. The assumption currently for me is that using ODBC is the only way for me to access the database. And here is the syntax of my connection command:
Libname Teradata ODBC dsn = 'dsnname' uid = 'uid' pwd = 'pwd';
results:
Error: The ODBC engine cannot be found.
Error: Error in the LIBNAME statement.
It keeps saying that the ODBC engine cannot be found. I'm really confused now. Is there anything wrong with the command? Or I have to do something else outside SAS?
I check the licence
Proc Setinit;
result:
SAS/ACCESS Interface to Teradata ** the date shows not expired.
Could anyone give me some idea. Thank you very much!

Can't say I've ever used ODBC to access Teradata, can see it being highly inefficient.
Normally, you'd do pass-thru SQL to Teradata...
proc sql ;
connect to teradata (user='username' pass='password' tdpid=prodserver) ;
create table mydata as
select * from connection to teradata
(select a.*
from ds.enterprise_table as a) ;
disconnect from teradata ;
quit ;
For a direct libname, the syntax would be
libname tdata teradata user='username' pass='password' tdpid=prodserver schema=ds ;
data mydata ;
set tdata.enterprise_table ;
run ;

Related

How to read an escaped table in SQL Server from R DBI?

I was able to use DBI::dbWriteTable to write a table with a non-standard name [name#place:funny/pages], but I am unable to read it back in with DBI::dbReadTable.
When I try with:
dbReadTable(con, '[name#place:funny/pages]')
I see the error:
Error: nanodbc/nanodbc.cpp:1655: 00000: [Microsoft][ODBC Driver 17 for SQL Server][SQL Serv [Microsoft][ODBC Driver 17 for SQL Server][S L Serv 'SELECT * FROM "[name#place:funny/pages]"'
sessionInfo tells me I am using odbc_1.3.2 and DBI_1.1.1.
What am I doing wrong? Is there a way around the problem? I need to use that naming scheme to maintain compatibility with established processes.
I am able to read this table without issue from SQL with:
select * from [name#place:funny/pages]
The answer is to not include brackets at all.

Push/Export large datframe from R to Vertica database

I have a dataframe of 10M rows which needs to be uploaded back from R to Vertica Database.
The DBwrite() function from DBI is running into memory issues and I have tried increasing memory to 16g by
options(java.parameters = c("-XX:+UseConcMarkSweepGC", "-Xmx16g"))
Still the process is running into memory issue. I am planning to use bulk copy option of vertica to copy the csv file to create the table.
I have created an empty table on vertica
When I am executing the query
dbSendQuery(vertica, "COPY hpcom_usr.VM_test FROM LOCAL \'/opt/mount1/musoumit/MarketBasketAnalysis/Code/test.csv\' enclosed by \'\"\' DELIMITER \',\' direct REJECTED DATA \'./code/temp/rejected.txt\' EXCEPTIONS \'./code/temp/exceptions.txt\'")
I am running into this error.
Error in .verify.JDBC.result(r, "Unable to retrieve JDBC result set", :
Unable to retrieve JDBC result set
JDBC ERROR: [Vertica]JDBC A ResultSet was expected but not generated from query "COPY hpcom_usr.VM_test FROM LOCAL '/opt/mount1/musoumit/MarketBasketAnalysis/Code/test.csv' enclosed by '"' DELIMITER ',' direct REJECTED DATA './code/temp/rejected.txt' EXCEPTIONS './code/temp/exceptions.txt'". Query not executed.
Please help with what i'm doing wrong here.
Vertica also provides STDIN option aswell. Link
Please help me how can I execute this.
My Environment.
CENT OS 7
R 3.6.3 (No R Studio here I have to execute this from CLI)
Tidyverse 1.0.x
Vertica driver 9.x
System 128GB Memory and 28Core system.
Your problem is that you fire dbSendQuery() , which lives with a following dbFetch() and a final dbClearResult() - but only for query SQL statements - those that actually return a result set.
Vertica's COPY <table> FROM [LOCAL] 'file.ext' ... command is treated like a DML command. And for those - as this docu says ...
https://www.rdocumentation.org/packages/DBI/versions/0.5-1/topics/dbSendQuery
.. you need to use dbSendStatement() for data manipulation statements.
Have a go at it that way - good luck ...
dbSendUpdate(vertica, "COPY hpcom_usr.VM_test FROM LOCAL \'/opt/mount1/musoumit/MarketBasketAnalysis/Code/test.csv\' enclosed by \'\"\' DELIMITER \',\' direct REJECTED DATA \'./code/temp/rejected.txt\' EXCEPTIONS \'./code/temp/exceptions.txt\'")
instead of dbSendQuery did the trick for me.

Access parquet files in Azure DataBricks by R via RODBC

I successfully configured connection to Azure DataBricks cluster and can query tables with
conn <- odbcConnect("AzureDatabricks")
sqlQuery(conn, "SELECT * FROM my_table")
but I need to access parquet files.
In Databricks I can do it with this code:
%sql
Select * FROM parquet.`/path/to/folder`
If I try this by R as
sqlQuery(conn, "Select * FROM parquet.`/path/to/folder`")
I receive error:
[Simba][SQLEngine] Table or view not found: SPARK.parquet./path/to/folder"
[RODBC] ERROR: Could not SQLExecDirect 'Select * FROM parquet.`/path/to/folder`
Is there way to access parquet files via RODBC?
You are experiencing this issue due to an error in your sql query itself. When you run Select * FROM parquet./path/to/folder, command you will not see table or view not found due to syntax error.
Example: Sample example for understanding the issue (when you run SELECT * FROM parquer.'somepath'), you will see the syntax error.
Note: After creating a Dataframe from parquet file, you have to register it as a temp table to run sql queries on it.
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
val df = sqlContext.read.parquet("src/main/resources/peopleTwo.parquet")
df.printSchema
// after registering as a table you will be able to run sql queries
df.registerTempTable("people")
sqlContext.sql("select * from people").collect.foreach(println)
Reference: Spark SQL guide - Parquet files
You need to add UseNativeQuery=1; parameter to the odbc connection string.
Examlpe: Driver={Simba Spark ODBC Driver};Host=[serverHost];Port=443;HTTPPath=[httpPath];ThriftTransport=2;SSL=1;AuthMech=3;UID=token;PWD=[pwd];UseNativeQuery=1;
https://docs.databricks.com/integrations/jdbc-odbc-bi.html#ansi-sql-92-query-support-in-odbc

Execute SQL with "like" statement in R Language

I am trying to execute a SQL Query through R to get the data from Access DB
Normal SQL statement works fine, but when it comes to like statement its throwing error
Below is code :
library(RODBC);
channel = odbcDriverConnect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:/Users/ADMIN/Documents/R.accdb")
test = sqlQuery(channel ,paste('SELECT R.ID, R.Template, R.WEDate FROM R WHERE R.Template Like "*slow*"'))
Error:
[1] "07002 -3010 [Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 2."
[2] "[RODBC] ERROR: Could not SQLExecDirect 'SELECT R.ID, R.Template, R.WEDate FROM R WHERE (R.Template Like \"slow\")'
Is there a way to fix this.
Consider both of #joran's suggestions with single quote enclosing string literals AND using the ANSI-92 wildcard operator %. You would use asterisk, * (ANSI-89 mode) when running an internal query, namely inside the MSAccess.exe GUI program (which defaults to DAO) or if you connect externally to Access with DAO. Meanwhile, ADO connections uses the percent symbol which most external interfaces uses including RODBC.
I was able to reproduce your issue and both these remedies worked. Also, no need to use paste() as you are not concatenating any other object to query statement.
library(RODBC);
channel = odbcDriverConnect("Driver={Microsoft Access Driver (*.mdb, *.accdb)};
DBQ=C:/Users/ADMIN/Documents/R.accdb")
test = sqlQuery(channel,
"SELECT R.ID, R.Template, R.WEDate FROM R WHERE R.Template Like '%slow%'")

Why won't RODBC upload a dataframe to SQL Server?

library(RODBC)
con <- odbcDriverConnect("driver=SQL Server; server=name")
df <- data.frame(a=1:10, b=10:1, c=11:20)
Trying to upload the dataframe:
sqlSave(con, df, tablename='[MyDatabase].[MySchema].[MyTable]', rownames=F)
>Error in sqlColumns(channel, tablename) :
‘MyDatabase.MySchema.MyTable’: table not found on channel
..alternatively creating the table first and then appending to it:
cmd <- "create table [MyDatabase].[MySchema].[MyTable] ([a] int, [b] int, [c] int)"
sqlQuery(con, cmd)
sqlSave(con, df, tablename='[MyDatabase].[MySchema].[MyTable]', rownames=F, append=T)
>Error in sqlSave(con, df, tablename = "MyTable", rownames = F, :
42S01 2714 [Microsoft][ODBC SQL Server Driver][SQL Server]There is already an object named MyDatabase.MySchema.MyTable in the database.
[RODBC] ERROR: Could not SQLExecDirect 'CREATE TABLE MyDatabase.MySchema.MyTable ("a" int, "b" int, "c" int)'
What am I doing wrong?
If I add brackets I also get an error.
If I use a connection string with the database to make sure that I am in the correct database (not master) and execute the statement sqlSave(con, df, tablename='dbo.MyTable4', rownames=F) or sqlSave(con, df, tablename='MyTable5', rownames=F) it works.
When connecting to a Microsoft SQL Server, it is essential to use odbcDriverConnect instead of odbcConnect in order to perform sqlSave statements etc. Only odbcDriverConnect allows to specifiy a specific database in the connection string.
RODBC looks at the default folder for the ODBC server connection to see if you have write permissions there (even if you are going for a subdirectory). If you don't have master permissions, then it fails.
I had to create two connections within R, one for reading from the master and one for writing to my temp directory.
These were set by creating two server connections using my local computer's ODBC Administration (within Win7):
-One that defaults to the write-protected master server directory and that I use to pull read-only data.
-One that defaults to the server directory that I have write/drop permissions to.
In other words, your problem is solved by changing your machine's ODBC connection and having R point to the new server connection you will make (the one that defaults to your write-permissioned table.

Resources