SAS libname to odbc only show one row? - odbc

For example I have in MySql database a table named "courses":
"course_code" "course_title"
"C001" "Basic Telecommunications"
"C002" "Structured Query Language"
"C003" "Local Area Networks"
"C004" "Database Design"
"C005" "Artificial Intelligence"
"C006" "Computer Aided Design"
then in SAS I did this:
libname samples odbc dsn=mydsn (Assuming mydsn connects to MySql);
Now in the explorer I will have a dataset "courses" in samples library.
However, when I double click to open the dataset it only shows ONE row???
I am using SAS 9.

Have you tried running a proc print instead?
proc print data=samples.courses ;
run ;

Related

SQL Server - running daily jobs with r scipts

I was wondering if anybody had any ideas on how to set up a SQL Server Job to run r scripts? Here is what I have so far in terms of the SQL code: I have to extract data out of a database (ETL) and want that data to be aggregated/analyzed by R by a specified date. After that, the database would run automatically. Does anybody have any ideas where the SQL ETL Code (from the database) will go and where the R script procedure would go that would eventually run automatically? Thanks!
DATABASE -> ETL Code from database (generating own dataset) -> Using ONLY that dataset where an R script can then manipulate/transform it.
DECLARE #job_name NVARCHAR(128),
#description NVARCHAR(512),
#owner_login_name NVARCHAR(128),
#database_name NVARCHAR(128);
SET #job_name = N'Some Title';
SET #description = N'Periodically do something';
SET #owner_login_name = N'login';
SET #database_name = N'DATABASE';
-- Delete job if it already exists:
IF EXISTS(SELECT job_id FROM msdb.dbo.sysjobs WHERE (name = #job_name))
BEGIN
EXEC msdb.dbo.sp_delete_job
#job_name = #job_name;
END
EXEC msdb.dbo.sp_add_job
#job_name=#job_name,
#enabled=1,
#notify_level_eventlog=0,
#notify_level_email=2,
#notify_level_netsend=2,
#notify_level_page=2,
#delete_level=0,
#description=#description,
#category_name=N'[Uncategorized (Local)]',
#owner_login_name=#owner_login_name;
-- Add server:
EXEC msdb.dbo.sp_add_jobserver #job_name=#job_name;
-- Add step to execute SQL:
EXEC msdb.dbo.sp_add_jobstep
#job_name=#job_name,
#step_name=N'Execute SQL',
#step_id=1,
#cmdexec_success_code=0,
#on_success_action=1,
#on_fail_action=2,
#retry_attempts=0,
#retry_interval=0,
#os_run_priority=0,
#subsystem=N'TSQL',
#command=N'EXEC my_stored_procedure; -- OR ANY SQL STATEMENT',
#database_name=#database_name,
#flags=0;
-- Update job to set start step:
EXEC msdb.dbo.sp_update_job
#job_name=#job_name,
#enabled=1,
#start_step_id=1,
#notify_level_eventlog=0,
#notify_level_email=2,
#notify_level_netsend=2,
#notify_level_page=2,
#delete_level=0,
#description=#description,
#category_name=N'[Uncategorized (Local)]',
#owner_login_name=#owner_login_name,
#notify_email_operator_name=N'',
#notify_netsend_operator_name=N'',
#notify_page_operator_name=N'';
-- Schedule job:
EXEC msdb.dbo.sp_add_jobschedule
#job_name=#job_name,
#name=N'Daily',
#enabled=1,
#freq_type=4,
#freq_interval=1,
#freq_subday_type=1,
#freq_subday_interval=0,
#freq_relative_interval=0,
#freq_recurrence_factor=1,
#active_start_date=20170101, --YYYYMMDD
#active_end_date=99991231, --YYYYMMDD (this represents no end date)
#active_start_time=010000, --HHMMSS
#active_end_time=235959; --HHMMSS
Sql-server supports running R and python since sql-server 2014. Take a look on this.
Method before sql-server 2014
However if you are using version before 2014, you need to have some other way else. My suggestion is using R to kick start the sql (if you can).
Using library like taskscheduleR. You first make a schedule task of R for computing your data. And then connect to your sql-server by some library like obdc, dbi, etc. to update what you want.
ps. I didn't try this before, but I can make some test if you still have further problem about it.

Unable to CREATE TABLE; why does this code fail?

I have a problem with SQLite v3.22.0 and AutoIt v3.3.14.3. Trying to create a database works but the table does not get created. I use the AutoIt example code:
#include <MsgBoxConstants.au3>
#include <SQLite.au3>
#include <SQLite.dll.au3>
Local $hQuery, $aRow, $sMsg
_SQLite_Startup()
ConsoleWrite("_SQLite_LibVersion=" & _SQLite_LibVersion() & #CRLF)
_SQLite_Open() ; open :memory: Database
_SQLite_Exec(-1, "CREATE TABLE aTest (a,b,c);") ; CREATE a Table
_SQLite_Exec(-1, "INSERT INTO aTest(a,b,c) VALUES ('c','2','World');") ; INSERT Data
_SQLite_Exec(-1, "INSERT INTO aTest(a,b,c) VALUES ('b','3',' ');") ; INSERT Data
_SQLite_Exec(-1, "INSERT INTO aTest(a,b,c) VALUES ('a','1','Hello');") ; INSERT Data
_SQLite_Query(-1, "SELECT c FROM aTest ORDER BY a;", $hQuery) ; the query
While _SQLite_FetchData($hQuery, $aRow) = $SQLITE_OK
$sMsg &= $aRow[0]
WEnd
_SQLite_Exec(-1, "DROP TABLE aTest;") ; Remove the table
MsgBox($MB_SYSTEMMODAL, "SQLite", "Get Data using a Query : " & $sMsg)
_SQLite_Close()
_SQLite_Shutdown()
; Output:
; Hello World
If I request the SQLite error, I get "Library used incorrectly". What's the problem in this case?
Whats the problem in this case?
As per Documentation - Script breaking changes :
_SQLite_Startup() function no longer automatically downloads the SQLite DLL files from autoitscript.com. Most users were completely unaware that this download was occuring on each script run and it was also a severe bandwidth hog for the website. The SQLite DLLs must now be manually download. See the _SQLite_Startup() documentation for details.
If _SQLite_Startup()'s first parameter is omitted, then dll file must reside in #SystemDir, #WindowsDir, #ScriptDir or #WorkingDir for this function to succeed.
Download sqlite3.dll,
remove #include <SQLite.dll.au3>, then
provide _SQLite_Startup()'s first parameter with location of dll file (redundant if present in one of four previously mentioned locations).
Related.
AutoIt v3.3.14.3 has a bug; install AutoIt v3.3.14.2 or get the bug-fix.

Create a stored procedure using RMySQL

Background: I am developing a rscript that pulls data from a mysql database, performs a logistic regression and then inserts the predictions back into the database. I want the entire system to be self contained in the script in case of database failure. This includes all mysql stored procedures that the script depends on to aggregate the data on the backend since these would be deleted in such a database failure.
Question: I'm having trouble creating a stored procedure from an R script. I am running the following:
mySQLDriver <- dbDriver("MySQL")
connect <- dbConnect(mySQLDriver, group = connection)
query <-
"
DROP PROCEDURE IF EXISTS Test.Tester;
DELIMITER //
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
END //
DELIMITER ;
"
sendQuery <- dbSendQuery(connect, query)
dbClearResult(dbListResults(connect)[[1]])
dbDisconnect(connect)
I however get the following error that seems to involve the DELIMITER change.
Error in .local(conn, statement, ...) :
could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER //
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
EN' at line 2
What I've Done: I have spent quite a bit of time searching for the answer, but have come up with nothing. What am I missing?
Just wanted to follow up on this string of comments. Thank you for your thoughts on this issue. I have a couple Python scripts that need to have this functionality and I began researching the same topic for Python. I found this question that indicates the answer. The question states:
"The DELIMITER command is a MySQL shell client builtin, and it's recognized only by that program (and MySQL Query Browser). It's not necessary to use DELIMITER if you execute SQL statements directly through an API.
The purpose of DELIMITER is to help you avoid ambiguity about the termination of the CREATE FUNCTION statement, when the statement itself can contain semicolon characters. This is important in the shell client, where by default a semicolon terminates an SQL statement. You need to set the statement terminator to some other character in order to submit the body of a function (or trigger or procedure)."
Hence the following code will run in R:
mySQLDriver <- dbDriver("MySQL")
connect <- dbConnect(mySQLDriver, group = connection)
query <-
"
CREATE PROCEDURE Test.Tester()
BEGIN
/***DO DATA AGGREGATION***/
END
"
sendQuery <- dbSendQuery(connect, query)
dbClearResult(dbListResults(connect)[[1]])
dbDisconnect(connect)

SAS libname odbc, how to access a two-level name table

I recently found the libname statement is very handy to access tables reside in odbc. But I don't know how to access those tables having a two-level names. Below is an example.
Old code I use (this code works):
proc sql;
connect to odbc(dsn=edw_nz user=&username. pw=&password.);
create table test select * from connection to odbc(
select *
from EDW_XYZ_PROD01..Table_xyz);
quit;
Now, I want to use the libname facility to access the odbc:
libname edw odbc database=edw_nz user=&username. pw=&password.;
proc sql;
create table test as
select *
from edw.EDW_XYZ_PROD01..Table_xyz;
quit;
I got this error:
ERROR 22-322: Syntax error, expecting one of the following: a name, (, ), ',', ANSIMISS, AS, CROSS, EXCEPT, FULL, GROUP, HAVING, INNER, INTERSECT, JOIN, LEFT, NATURAL, NOMISS, OUTER, RIGHT, UNION, WHERE.
ERROR 200-322: The symbol is not recognized and will be ignored.
Any one can help?
Thanks a lot!
SAS cannot handle 3 level names.
You need to specify the schema/database inside the libname section. You have a few options (read the doc for all the options).
We use ODBC to connect to our SQL server instances like this:
libname pdata odbc complete='DSN=SQLServerProd;Database=MyDatabase';
The complete= option allows you specify the full ODBC connection string. This should allow you to specify the database/schema.
Is EDW_XYZ_PROD01 a schema or something?
I think you might have to specify that on the datasource= option. For example:
libname mydblib odbc user=testuser password=testpass datasrc=mydatasource;
Have you tried the schema= option on the libname statement. The schema is equivalent to the first level name.
libname edw odbc database=edw_nz user=&username. pw=&password. schema=edw;
proc sql;
create table test as
select *
from EDW_XYZ_PROD01..Table_xyz;
quit;

What's the easiest way to use SQLite with SAS?

I want to investigate how to access SQLite DB from SAS. What's the easiest way of doing this? Is there a SAS product that we can license to do that? I don't want to use ODBC drivers as that seems to have been written a long time ago and is not officially part of SQLite.
SAS supports reading data from pipes (in a unix environment). Essentially, you can set up a filename statement to execute an sqlite command in the host environment, then process the command output as if reading it from a text file.
SAS Support page: http://support.sas.com/documentation/cdl/en/hostunx/61879/HTML/default/viewer.htm#pipe.htm
Example:
*----------------------------------------------
* (1) Write a command in place of the file path
* --> important: the 'pipe' option makes this work
*----------------------------------------------;
filename QUERY pipe 'sqlite3 database_file "select * from table_name"';
*----------------------------------------------
* (2) Use a datastep to read the output from sqlite
*----------------------------------------------;
options linesize=max; *to prevent truncation of results;
data table_name;
infile QUERY delimiter='|' missover dsd lrecl=32767;
length
numeric_id 8
numeric_field 8
character_field_1 $40
character_field_2 $20
wide_character_field $500
;
input
numeric_id
numeric_field $
character_field_1 $
character_field_2 $
wide_character_field $
;
run;
*----------------------------------------------
* (3) View the results, process data etc.
*----------------------------------------------;
proc contents;
proc means;
proc print;
run;

Resources