/***********************************************************/
/* ODBLOAD.SAS contains two parts. The first part */
/* is a macro that generates PROC SQL EXECUTE */
/* statements and stores them in a file. The */
/* part contains the PROC SQL statement, connects */
/* to the database via ODBC and executes the */
/* EXECUTE statements to create the ODBC table */
/***********************************************************/
/* %ODBLOAD macro creates a table definition */
/* (optionally), and the necessary INSERT INTO */
/* statements to load an ODBC table from a SAS */
/* data set. */
%macro odbcload(
data=_last_, /* SAS data set to load from. */
create=Y, /* Y to define the table. */
table=DataBaseTable, /* database table name. */
connect=connect, /* the connection name used. */
sqlcode='loader.sas', /* a valid file name. */
debug=Y);
%local tmpmod; /* Stores file access mode. */
%let tmpmod=;
/* Now, create the temporary data set _ODBC_ which */
/* contains the structure and characteristics of */
/* the SAS data set, &DATA. */
proc contents data=&data noprint out=work._odbc_;
run;
filename sqlcode &sqlcode;
/* Use the _ODBC_ data set to generate the table */
/* definition. */
data _null_;
%if &create=Y %then
%do;
%let tmpmod=mod;
file sqlcode &tmpmod; /* Open file for write. */
%end;
set work._odbc_ end=end;
length puttext $200;
puttext="";
length comma $4;
comma=" ','";
retain putnum 0;
%if &create=Y %then
%do;
if _n_=1 then
/* Write to the file the first EXECUTE statement */
/* to create the table. */
put ///"execute ( create table &table ( ";
else
put ",";
%end;
if end then
comma="";
/* The PROC CONTENTS variable TYPE states if a SAS */
/* variable is numeric (type=1) or character */
/* (type=2). */
/* */
/* The PROC CONTENTS variable NAME contains the */
/* name of the SAS variable. */
if type=1 then
do;
%if &create=Y %then
%do;
put +8 name "number" @;
%end;
puttext = "_chartmp=put(" || trim(name) || ",
best16.);";
end;
else
do;
%if &create=Y %then
%do;
put +8 name "character (" length ")" @;
%end;
puttext = "_chartmp=quote(" || trim(name) ||
");";
end;
/* If it is the end of list of variables in &DATA, */
/* terminate the EXECUTE statement with BY */
/* CONNECT; otherwise, just write out the list of */
/* the variables that have been collected so far */
/* in the PUTTEXT variable and their length from */
/* PUTNUM. */
%if &create=Y %then
%do;
if end then
put +8 ") ) by &connect;";
%end;
putnum + 1;
puttext = trim(puttext) || " put _chartmp " ||
comma || " @;";
call symput('PUT'||left(put(putnum, 6.0)),
puttext);
file log;
put putnum= puttext=;
if end then
call symput('PUTNUM', left(put(putnum, 6.0)));
run;
/* Create the EXECUTE INSERT statements to load */
/* the table with values from the data set, &DATA. */
data _null_;
file sqlcode &tmpmod;
set &data;
length _chartmp $200;
if _n_=1 then
put ///;
put "execute ( insert into &table values (" @;
%do i=1 %to &putnum;
&&&put&i
%end;
put ") ) by &connect;";
run;
%mend; /* End of macro ODBCLOAD. */
/* The LIBNAME statement below designates the */
/* location of the SAS data set, &DATA. %ODBCLOAD */
/* takes the data from SASLIB.FROMSOGO and build */
/* the generated SQL code in a file called */
/* SQLCODE.SAS. This file is %INCLUDEd and it */
/* creates the Excel worksheet called FromSOGO. */
libname saslib 'Novell:SAS data';
%odbcload(data=saslib.fromsogo, create=Y, table=FromSOGO)
proc sql;
/* Using "prompt" in the CONNECT statement above */
/* will prompt you for which ODBC driver to use. */
/* The Excel version 4 driver is the correct */
/* choice because it allows you to create an */
/* Excel worksheet. */
connect to odbc as connect(prompt);
%inc sqlcode;
disconnect from connect;
quit;