I've googled for a few days and can't get this working.
I'm using SQL 2014 and the adventureworks database.
I've got SAS 9.3.
I've tried different ODBC settings, as in setting a default database, using Windows login, or SQL login. Different drivers. Still nothing, used complete and noprompt:
libname mylib odbc complete='TrustedConnection=True;DSN=test2;SERVER=MYSERVER\SQLEXPRESS;DATABASE=AdventureWorks2012;'stringdates=yes;
proc print data=mylib.Person;
Error message:
NOTE: Libref MYLIB was successfully assigned as follows:
Engine: ODBC
Physical Name: test2
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS release.
Inserting white space between a quoted string and the succeeding identifier is
recommended.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE PRINT used (Total process time):
real time 5.48 seconds
cpu time 0.34 seconds
700 proc print data=mylib.Person;
ERROR: File MYLIB.Person.DATA does not exist
I've tried with Person.Person and also in the connection string using schema=Person.
However if I use the following it works. I put the default database in the ODBC:
proc sql;
connect to odbc as mycon
(required = "dsn=awlt32;uid=sa;password=mypassword");
select *
from connection to mycon
(select *
from Person.Person);
disconnect from mycon;
quit;
I know this is a super simple question but I can't seem to get it working, no matter what example code I find. Thanks in advance.
Add the database connection to your ODBC driver; you will need the name of this connection in your libname,
Use the libname below and update the datasrc, sql user and password
LIBNAME mylib ODBC DATASRC=name from step1 SCHEMA=dbo USER=sql user PASSWORD="xxx" ;
proc datasets lib=mylib ;
quit;
Related
Using following code I have created a temp table in azure sql database.
CREATE TABLE ##UpsertTempTable (
eno varchar(25),
ename varchar(25)
);
and I am want to check the data using the below query
select * from ##UpsertTempTable
Ideally it should run without any issue as in all of the azure documentation it works without any issues but unfortunately it is not working and giving below error.
I tried looking solution in all places in the internet but could not find any relevant documentation for this issue.
Error : Failed to execute query. Error: Invalid object name '##UpsertTempTable'.
I tried in Query Editor(Preview) in Portal, and create temporary table code doesn't work. I both used ##UpsertTempTable and #UpsertTempTable.
For example, when we run the code, no error happens .
When you run select * from ##UpsertTempTable, Query editor will gives the error:
I also try with SSMS V17.9 and SSMS V18.1, everything is ok.
What I think is the query editor doesn't support create temporary table well.
I asked Azure Support and wait their replay, please wait my update.
Update:
Azure Support replied me:
"This is by design, the temp tables exists as long as the connection is open.
The current way portal query editor is designed, the connection is killed resulting in temp table being deleted.
"
Hope this helps.
Good Afternoon All,
I have spent about 6 hours trying to get formatting to work through SSIS using a Max Date Variable to identify into a where clause - Just have no luck!
I have created a variable called my_date which fetched the Max(Date) from a local SQL server table to understand the last load point for that table - using the below code:
SELECT CAST(FORMAT(MAX(Business_Date), 'dd-MMM-yyyy') AS varchar) AS my_date FROM Table
This fetches the date correctly as 17-Sep-2018.
I have then mapped my result set as my_date -> User::max_date
I have set my max_date variable to a string data type under the package scope.
I have tested my variable out by using breakpoints to ensure this runs all the way through in the correct format - and this works 100%.
I then have a data flow task running to fetch data from my ORACLE DB to insert into my SQL Server table which contains the following SQL command:
SELECT *
FROM Table2
WHERE (BUSINESS_DATE > to_date('#[User::max_date]', 'DD-MON-YYYY'))
However I get the ORA-01858 - [TABLE] Error: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E07.
An OLE DB record is available. Source: "Microsoft OLE DB Provider for Oracle" Hresult: 0x80040E07 Description: "ORA-01858: a non-numeric character was found where a numeric was expected
".
If I go and replace my variable directly with the contents of the variable shown by the breakpoint in locales it works perfectly!
I have attempted multiple format types from the initial export through to the final where clause and this seems to be the closest I have come to pushing it through but it is still complaining about format.
Please help - Images below to help see setup.
Control Flow - displaying the execute SQL and the data flow task
Locale showing Variable is inserting after breakpoint is reached
Managed to get it working!
By adding an intermediary variable where the value and expression contains the following:
"SELECT *
FROM TABLE
WHERE (BUSINESS_DATE > to_date('"+#[User::max_date]+"' , 'DD-MON-YYYY'))"
I then amended my source OLEDB to SQL Command from variable and selected the above variable created and it worked perfectly!
Try mapping your user parameter in the "OLE DB Data Source Editor", under "Parameters".
1) Change SQL Command Text (change #[User::max_date] to ?), like this:
SELECT *
FROM Table2
WHERE (BUSINESS_DATE > to_date('?', 'DD-MON-YYYY'))
2) Then in the parameter editor, map parameter 1 to #[User::max_date].
https://learn.microsoft.com/en-us/sql/integration-services/data-flow/map-query-parameters-to-variables-in-a-data-flow-component?view=sql-server-2017
Also, the "Oracle Provider for OLE DB" behaves differently than the "Microsoft OLE DB Provider for Oracle", so it depends which you are using.
I am using SAS Enterprise Guide (EG) 6.1 and want to know what are the indexes of our Oracle tables. Is there a way to write a program to get this information?
I tried to do:
LIBNAME DW ORACLE USER='username' PASSWORD='password' PATH='path.world' SCHEMA='schema';
DATA _NULL_ ;
dsid = OPEN(DW.some_table) ;
isIndexed = ATTRN(dsid,"ISINDEX") ;
PUT isIndexed = ;
RUN ;
some_table is the name of (my table), but I get an error:
ERROR: DATA STEP Component Object failure. Aborted during the COMPILATION phase.
ERROR 557-185: Variable some_table is not an object.
Reference: https://communities.sas.com/t5/ODS-and-Base-Reporting/check-if-index-exists/td-p/1966
OPEN takes a string or a value that resolves to a string. So you need
dsid= OPEN('dw.some_dataset');
I don't know if you can use that with Oracle or not, and I don't know whether ATTRN will be useful for this particular purpose or not. These all work well with SAS datasets, but it's up to the libname engine (and whatever middleware it uses) to implement the functionality that ATTRN would use.
For example, I don't use Oracle but I do have SQL Server tables with indexes, and I can run the above code on them; the code appears to work (it doesn't show errors) but it shows the tables as being unindexed, when they clearly are.
Your best bet is to connect using pass-through (CONNECT TO ...) instead of libname, and then you can run native Oracle syntax rather than using SAS.
This is not a purely Teradata Question. I am not asking to create a volatile table in Teradata. This is a question for someone who uses OLEDB connection to Teradata from SAS. I am aware Volatile tables can be created in a heartbeat using SQL assistant or even Teradata Interface to SAS. But if there are users who are NOT on the SAS grid and they don't have SAS i/f to teradata installed amd they use OLEDB to connect SAS and Teradata.
Here is a snippet of code that Runs well using OLEDB which gives some idea what we are talking about.
Below code will run well:
proc sql;
connect to OLEDB(Provider='MSDASQL' Extended_Properties='DRIVER={Teradata};DBCNAME=UDWPROD;AUTHENTICATION=ldap' UID="&DMID" PWD="&DMPWD");
create table out.TB as
select a.*, b.C7
from connection to OLEDB
(select
DB.C1,
DB.C2,
from
DB
) as a inner join mytb as b
on DB.C9=b.C9
and (intnx('year',b.C7,-1,'same') le a.fst_srvc_dt lt intnx('year',b.C7,1,'same'));
%put &sqlxmsg ;
disconnect from OLEDB ;
quit;
Along the same lines we tried to run this but either there is a syntax error ( hopefully) or it doesn't like it ( bummer on that ..wont be too good ) :
proc sql;
connect to OLEDB(Provider='MSDASQL' Extended_Properties='DRIVER={Teradata};DBCNAME=SITEPRD;AUTHENTICATION=ldap' UID="&DMID" PWD="&DMPWD");
execute (create multiset volatile table idlist (my_id integer, mydate date)
ON COMMIT PRESERVE ROWS) by teradata;
execute (COMMIT WORK) by teradata;
insert into idlist
select distinct MyId_sas, mydate
from mysource;
quit; 3:52 PM
And got this output: 3:52 PM
proc sql;
28 connect to OLEDB(Provider='MSDASQL' Extended_Properties='DRIVER={Teradata};
28 ! DBCNAME=SITEPRD;AUTHENTICATION=ldap' UID="&DMID" PWD="&DMPWD");
SYMBOLGEN: Macro variable DMID resolves to ConfusedUser
SYMBOLGEN: Macro variable DMPWD resolves to Youbetcha!
29 execute (create multiset volatile table idlist (my_id integer, mydate date)
30 ON COMMIT PRESERVE ROWS) by teradata;
ERROR: The TERADATA engine cannot be found.
ERROR: A Connection to the teradata DBMS is not currently supported, or is not installed at
your site.
31 execute (COMMIT WORK) by teradata;
ERROR: The TERADATA engine cannot be found.
ERROR: A Connection to the teradata DBMS is not currently supported, or is not installed at
your site.
32 insert into idlist
33 select distinct MyId_sas, mydate
34 from mysource;
ERROR: File WORK.idlist.DATA does not exist.
NOTE: SGIO processing active for file WORK.mysource.DATA.
35 quit;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE SQL used (Total process time):
real time 9.19 seconds
cpu time 1.75 seconds
This is what's presently installed AFAIK for SAS
NOTE: PROCEDURE SETINIT used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
Operating System: WX64_SV .
Product expiration dates:
---Base SAS Software
30DEC2016
---SAS/STAT
30DEC2016
---SAS/GRAPH
30DEC2016
---SAS/Secure 168-bit
30DEC2016
---SAS/Secure Windows
30DEC2016
---SAS/ACCESS Interface to PC Files
30DEC2016
---SAS/ACCESS Interface to ODBC
30DEC2016
---SAS/ACCESS Interface to OLE DB
30DEC2016
---SAS Workspace Server for Local Access
30DEC2016
---High Performance Suite
30DEC2016
How do you get it to work?
I don't have a teradata instance to reference, but I think your issue is that you do not create the oledb connection with a reference name, then you try to reference it as "teradata".
Try this:
connect to OLEDB as teradata (Provider='MSDASQL' Extended_Properties='DRIVER={Teradata};DBCNAME=SITEPRD;AUTHENTICATION=ldap' UID="&DMID" PWD="&DMPWD");
You have two mistakes. First you defined a connection to OLEDB and then tried to execute commands on a connection named TERADATA that wasn't defined. Either add AS TERADATA to your CONNECT statement so that the connection is named or change the EXECUTE statement to use the OLEDB connection name instead.
Also your insert statement at the end is going to create a table in the SAS WORK library. Did you expect it to be able to insert or read from the OLEDB connect? If you want to insert data from SAS into a Teradata table then you need to create libref that points to Teradata. There is no need to "create" the table first. SAS will happily create the table for you.
libname TERADATA OLEDB ... connection details ... ;
proc sort data=mysource(keep=myid_sas mydate) nodupkey out=TERADATA.idlist;
by _all_;
run;
Addendum: As of Stata 14, volatile tables work without any hacks.
Is there a way to tweak Stata to work with temporary volatile tables? These tables and the data are deleted after a user logs off the session.
Here's an example of a simple toy SQL query that I am using in Stata and Teradata:
odbc load, exec("
BEGIN TRANSACTION;
CREATE VOLATILE MULTISET TABLE vol_tab AS (
SELECT TOP 10 user_id
FROM dw_users
) WITH DATA
PRIMARY INDEX(user_id)
ON COMMIT PRESERVE ROWS;
SELECT * FROM vol_tab;
END TRANSACTION;
") dsn("mozart");
This is the error message I am getting:
The ODBC driver reported the following diagnostics
[Teradata][ODBC Teradata Driver][Teradata Database] Only an ET or null statement is legal after a DDL Statement.
SQLSTATE=25000
r(682);
The Stata error code means:
error . . . . . . . . . . . . . . . . . . . . . . . . Return code
682
could not connect to odbc dsn;
This typically occurs because of incorrect permissions, such
as a bad User Name or Password. Use set debug on to display
the actual error message generated by the ODBC driver.
As far as I can tell permission are fine since I can pull data if I just execute the "SELECT TOP 10..." query. I set debug on, but it did not produce any additional information.
Session mode is Teradata. ODBC manager is set to unixODBC. I am using Stata 13.1 on an Ubuntu server.
I believe the underlying issue may be that separate connections are established for each SQL statement, so the volatile table evaporates by the time the select is issued. I am waiting on tech support to verify this.
I tried using the odbc sqlfile command well, but this approach does not work unless I create a permanent table at the end of it. There's no load option with odbc sqlfile.
Volatile tables seem to work just fine in SAS and R. For example, this works perfectly:
library("RODBC")
db <- odbcConnect("mozart")
sqlQuery(db,"CREATE VOLATILE MULTISET TABLE vol_tab AS (
SELECT TOP 10 user_id
FROM dw_users
) WITH DATA
PRIMARY INDEX(user_id)
ON COMMIT PRESERVE ROWS;
")
data<- sqlQuery(db,"select * from vol_tab;",rows_at_time=1)
Perhaps this is because the connection to the DB remains open until close(db).
I'm not familiar with Stata, but I'm guessing that your ODBC is connecting in "ANSI" mode. Try adding this between the create volatile table and the select statements:
commit work;
If that doesn't work, you may need to make two separate calls somehow.
UPDATE: Thinking a bit more about this, perhaps you can try this:
odbc load, exec("select distinct user_id from dw_users where cast(date_confirm as
date) > '2011-09-15'") clear dsn("mozart") lowercase;
In other words, just execute the query in one step; don't try to create a volatile table.
What if you try the following with your connection mode as TERADATA (which is more often then not the default):
odbc load, exec("BT; create volatile table new_usr as
(select top 10 user_id from dw_users) with data primary index(user_id) on commit
preserve rows;
ET;
select * from new_usr;") clear dsn("mozart") lowercase;
The BT; and ET; statements wrap the SQL contained between in an explicit transaction. This SQL has been tested in SQL Assistant as I don't have access to the tool you are using. Typically, BT and ET are used to enforce logical transactions (or units of work) that must be completed successfully or everything is rolled back. This may allow you to get around the issue you are having in your tool.
EDIT
Failing the ability to wrap the Volatile Table creation in a BT and ET do you have the ability to create a stored procedure or macro that can embed all the logic necessary to complete the task then call the stored procedure or macro from Stata?
Put
BT;
--UR LOGIC--
ET;
IF any thing fails in between.it rolls back
got from here
This answer is not longer correct. Stata now allows multiple SQL statements as long as the multistatement option is added to the odbc command.
Stata's odbc command does not allow combining multiple SQL statements into a single odbc command and altering TD's mode. It also creates a separate connection for each odbc command issued, so the volatile table goes poof by the time you want to use it to do something. This makes it impossible to use volatile tables directly.
However, there is a way to use R through Stata to produce a Stata data file. You need to install rsource from SSC and the foreign and RODBC packages in R. The 2 globals Rterm_path and Rterm_options for rsource can be defined in sysprofile.ado or in your own profile.ado. As far as I can determine, R does not allow exporting timestamps, so I had to do some conversion of dates and timestamps by hand. These conversions are somewhat at odds with the suggestions in the Stata manuals and the Stata blog.
rsource, terminator(END_OF_R)
library("RODBC")
library("foreign")
db <- odbcConnect("mydsn")
sqlQuery(db,"CREATE VOLATILE MULTISET TABLE vol_tab AS (SELECT ...) WITH DATA PRIMARY INDEX(...) ON COMMIT PRESERVE ROWS;")
data<- sqlQuery(db,"SELECT * FROM vol_tab;",rows_at_time=1)
write.dta(data,"mydata.dta",convert.dates = FALSE)
close(db)
END_OF_R
use "mydata.dta", replace
/* convert dates and timestamps to Stata format */
gen stata_date = rdate + td(01jan1970)
format stata_date %td
gen double stata_timestamp = (rtimestamp + 315594000)*1000
format stata_timestamp %tc