Hi, im trying to get output data of my sas program into a object wich conatins simliar methods to OLAPDataSetInterface
WorkspaceFactory factory = new WorkspaceFactory(new Properties[] { p }, null, null);
WorkspaceConnector connector = factory.getWorkspaceConnector(0L);
IWorkspace workspace = connector.getWorkspace();
ILanguageService ls = workspace.LanguageService();
String stmt = " "
"%include \"/saswork/program.sas\" ;";
ls.Submit(stmt);
// com.sas.sasserver.dataset.DataSetInterface ds;
// ds = ...
Thanks
Edit: more info
Below is an example of using the IDataSet interface, however, you may find it simpler to use JDBC instead.
import com.sas.iom.SAS.*;
import com.sas.iom.SASIOMDefs.*;
import com.sas.services.connection.*;
import org.omg.CORBA.IntHolder;
import org.omg.CORBA.StringHolder;
import java.util.Arrays;
public class SasOutputDataExample {
public static void main(String... args) {
ConnectionInterface cx = null;
boolean failed = false;
try {
BridgeServer server = new BridgeServer(BridgeServer.CLSID_SAS, "sas.myhost.net", 8591);
server.setEncryptionContent(BridgeServer.ENCRYPTION_CONTENT_ALL);
server.setEncryptionAlgorithms(BridgeServer.ENCRYPTION_ALGORITHM_AES);
server.setSecurityPackage(BridgeServer.SECURITY_PACKAGE_NEGOTIATE);
server.setSecurityPackageList(BridgeServer.SECURITY_PACKAGE_LIST_DEFAULT);
ManualConnectionFactoryConfiguration mconf = new ManualConnectionFactoryConfiguration(server);
ConnectionFactoryManager manager = new ConnectionFactoryManager();
ConnectionFactoryInterface factory = manager.getFactory(mconf);
SecurityPackageCredential cred = new SecurityPackageCredential();
cx = factory.getConnection(cred);
} catch (ConnectionFactoryException err) {
System.out.print(err.getMessage());
failed = true;
}
if (!failed) {
IWorkspace workspace = IWorkspaceHelper.narrow(cx.getObject());
try {
ILanguageService ls = workspace.LanguageService();
ls.Submit("data kids; set sashelp.class; run;");
ILibref libWork = workspace.DataService().UseLibref("work");
int flags = 0;
StringHolder dataSetLabel = new StringHolder();
StringHolder dataSetType = new StringHolder();
DateTimeHolder dateCreated = new DateTimeHolder();
DateTimeHolder dateModified = new DateTimeHolder();
IntHolder recordLength = new IntHolder();
StringHolder compressionRoutine = new StringHolder();
IntHolder bookmarkLength = new IntHolder();
IntHolder logicalRecordCount = new IntHolder();
IntHolder physicalRecordCount = new IntHolder();
IntHolder attrs = new IntHolder();
IDataSet kids = libWork.OpenDataSet(flags, "kids", "", new String[]{"", "", ""}, dataSetLabel, dataSetType, dateCreated, dateModified, recordLength, compressionRoutine, bookmarkLength, logicalRecordCount, physicalRecordCount, attrs);
int bindKey = 0;
byte[] positionBookmark = new byte[]{};
int numberRowsToRead = 2;
int rowsOffset = 0;
VariableArray2dOfStringHolder characterValues = new VariableArray2dOfStringHolder();
VariableArray2dOfDoubleHolder numericValues = new VariableArray2dOfDoubleHolder();
VariableArray2dOfOctetHolder missingValues = new VariableArray2dOfOctetHolder();
OctetSeqHolder bookmarks = new OctetSeqHolder();
IntHolder status = new IntHolder();
kids.ReadRecords(flags, bindKey, positionBookmark, numberRowsToRead, rowsOffset, characterValues, numericValues, missingValues, bookmarks, status);
for (int i = 0; i < numberRowsToRead; i++) {
System.out.println(Arrays.toString(characterValues.value[i])); //character values are formatted
}
workspace.Close();
cx.close();
} catch (Exception err) {
err.printStackTrace();
}
}
}
}
This should then print the following to the console
[Alfred , M, Alfred , M, 14, 69, 112.5] [Alice , F, Alice , F, 13, 56.5, 84]
IDataSet can also provide you with the metadata for the data set (i.e. Column Names, etc...)
In C# (I don't do Java):
/*********************************************************************
* IMPORTANT: The folowing 2 lines MUST be included even though they
* appear to be unused
*********************************************************************/
const LanguageServiceCarriageControl cc = new LanguageServiceCarriageControl();
const LanguageServiceLineType lt = new LanguageServiceLineType();
lang.FlushLogLines(1000, out Array carriage, out Array lineTypes, out Array lines);
var lineList = lines.OfType<string>().ToList();
var typeList = lineTypes.OfType<SAS.LanguageServiceLineType>().ToList();
I tried this solution, but doing this i just get the log and i need export the results into a DataSetInterface instance.
Like this:
SessionPool sp = null;
SASSession ss = null;
sp = SessionPool.getInstance();
ss = sp.getSession();
com.sas.sasserver.dataset.DataSetInterface ds;
ds = (com.sas.sasserver.dataset.DataSetInterface)ss.getObject ("com.sas.sasserver.dataset.DataSetInterface");
Just like there is a FlushLog,there is also a FlushList:
Here is a simple example of both:
static void Main(string[] args)
{
var ws = new SAS.Workspace();
var lang = ws.LanguageService;
lang.LineSeparator = "\r\n";
lang.Submit(sasCode);
PrintResults(ws, lang);
}
private static void PrintResults(SAS.Workspace ws, SAS.LanguageService lang)
{
SetColor(ConsoleColor.Yellow);
Console.WriteLine("=========== LOG =============");
Console.WriteLine(lang.FlushLog(5000));
SetColor(ConsoleColor.Cyan);
Console.WriteLine("=========== LIST =============");
Console.WriteLine(lang.FlushList(5000).Replace("\f", ""));
ws.Close();
Console.WriteLine("Press any key to continue...");
Console.ReadLine();
}
I haven't run this code in awhile. Let me know if this works for you.
FlushList() doesn't work, anyways, i can get the result with ResultSet like this:
//table with the result of my sas program
String sql= "select * from WORK.dp_tot_cal";
MVAConnection mva = new MVAConnection(workspace, new Properties());
PreparedStatement preStmt = mva.prepareStatement(sql);
ResultSet res = preStmt.executeQuery(sql);
while (res.next()) {
String gas = res.getString("ID_GAS");
}
But i need save the info within an object similiar to OLAPDataSetInterface or DataSetInterface because i want to use similar methods.
For example:
getCellCount();
getCells(long, long);
getResultMetadata().getTuples(int, int, int);
...
FlushList does work but you have to specify how many lines you want. See my simple example.
Below is an example of using the IDataSet interface, however, you may find it simpler to use JDBC instead.
import com.sas.iom.SAS.*;
import com.sas.iom.SASIOMDefs.*;
import com.sas.services.connection.*;
import org.omg.CORBA.IntHolder;
import org.omg.CORBA.StringHolder;
import java.util.Arrays;
public class SasOutputDataExample {
public static void main(String... args) {
ConnectionInterface cx = null;
boolean failed = false;
try {
BridgeServer server = new BridgeServer(BridgeServer.CLSID_SAS, "sas.myhost.net", 8591);
server.setEncryptionContent(BridgeServer.ENCRYPTION_CONTENT_ALL);
server.setEncryptionAlgorithms(BridgeServer.ENCRYPTION_ALGORITHM_AES);
server.setSecurityPackage(BridgeServer.SECURITY_PACKAGE_NEGOTIATE);
server.setSecurityPackageList(BridgeServer.SECURITY_PACKAGE_LIST_DEFAULT);
ManualConnectionFactoryConfiguration mconf = new ManualConnectionFactoryConfiguration(server);
ConnectionFactoryManager manager = new ConnectionFactoryManager();
ConnectionFactoryInterface factory = manager.getFactory(mconf);
SecurityPackageCredential cred = new SecurityPackageCredential();
cx = factory.getConnection(cred);
} catch (ConnectionFactoryException err) {
System.out.print(err.getMessage());
failed = true;
}
if (!failed) {
IWorkspace workspace = IWorkspaceHelper.narrow(cx.getObject());
try {
ILanguageService ls = workspace.LanguageService();
ls.Submit("data kids; set sashelp.class; run;");
ILibref libWork = workspace.DataService().UseLibref("work");
int flags = 0;
StringHolder dataSetLabel = new StringHolder();
StringHolder dataSetType = new StringHolder();
DateTimeHolder dateCreated = new DateTimeHolder();
DateTimeHolder dateModified = new DateTimeHolder();
IntHolder recordLength = new IntHolder();
StringHolder compressionRoutine = new StringHolder();
IntHolder bookmarkLength = new IntHolder();
IntHolder logicalRecordCount = new IntHolder();
IntHolder physicalRecordCount = new IntHolder();
IntHolder attrs = new IntHolder();
IDataSet kids = libWork.OpenDataSet(flags, "kids", "", new String[]{"", "", ""}, dataSetLabel, dataSetType, dateCreated, dateModified, recordLength, compressionRoutine, bookmarkLength, logicalRecordCount, physicalRecordCount, attrs);
int bindKey = 0;
byte[] positionBookmark = new byte[]{};
int numberRowsToRead = 2;
int rowsOffset = 0;
VariableArray2dOfStringHolder characterValues = new VariableArray2dOfStringHolder();
VariableArray2dOfDoubleHolder numericValues = new VariableArray2dOfDoubleHolder();
VariableArray2dOfOctetHolder missingValues = new VariableArray2dOfOctetHolder();
OctetSeqHolder bookmarks = new OctetSeqHolder();
IntHolder status = new IntHolder();
kids.ReadRecords(flags, bindKey, positionBookmark, numberRowsToRead, rowsOffset, characterValues, numericValues, missingValues, bookmarks, status);
for (int i = 0; i < numberRowsToRead; i++) {
System.out.println(Arrays.toString(characterValues.value[i])); //character values are formatted
}
workspace.Close();
cx.close();
} catch (Exception err) {
err.printStackTrace();
}
}
}
}
This should then print the following to the console
[Alfred , M, Alfred , M, 14, 69, 112.5] [Alice , F, Alice , F, 13, 56.5, 84]
IDataSet can also provide you with the metadata for the data set (i.e. Column Names, etc...)
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.