java应用中如何捕抓SAS存储过程输出的流信息
2007-06-28 15:17
796 查看
java应用中如何捕抓SAS存储过程输出的流信息
这个指南演示如何在存储过程中使用ods格式化输出流并被用某种语言编写的应用所接收,如java语言
l 注:宏 ®ION 用于指示取数据的一个子集
%let REGION=Pacific;
ods html body="shoe_sales.html";
title Shoe Sales by Subsidiary;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary sales;
define subsidiary / group;
define sales / analysis sum;
run;
title Shoe Sales Detail;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary product stores sales;
define subsidiary / order;
define product / order;
define sales / analysis sum;
run;
ods html close;
1、 每一个存储过程应该有一个标志用来指示其是存储过程,如下行,该行应该在%let 和 第一个ods输出之间
*ProcessBody;
2、 转换宏符号作为存储过程的参数,如下
%global REGION;
3、 我们应该初始化ods的开始和结束句子,在存储过程中,我们可以使用下面宏帮助我们自动初始化
%stpbegin
%stpend
改后的代码如下:
%global REGION;
*ProcessBody;
%stpbegin;
title Shoe Sales by Subsidiary;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary sales;
define subsidiary / group;
define sales / analysis sum;
run;
title Shoe Sales Detail;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary product stores sales;
define subsidiary / order;
define product / order;
define sales / analysis sum;
run;
%stpend;
我们把该后的程序部署到存储过程服务器上去
一旦部署完成,我们就可以使用外部工具来访问该存储过程,如用excel (需要装Add-In for Microsoft Office)
当然,也可以通过浏览器来访问该存储过程
你可以使用SAS IT APIS 来调用存储过程,你甚至可以使用SAS8.2来完成这一步骤
在开始写java代码前,我们应该明白下面概念
Integrated Object Model (IOM) 是我们远端调用SAS的API.
当我们连接到SAS时,我们将从SAS会话中获得workspace对象.
然后我们从Workspace.中取得其他服务对象
简单的java代码
要调用一个存储过程,你应该包含一个 IStoredProcessService 对象的引用并告诉它:
repository 位置,它是一个定位存储过程的目录路径,格式如 "file:/some/directory". 如果我们异步调用存储过程,那java将不会等待存储过程执行完
存储过车文件的名字
存储过程参数,如"name1=value1 name2=value2 …"
下面通过java定义了一个方法,用于设置且执行存储过程,代码如下:
private SocketListener executeImpl(
String stpName,
Properties params,
IWorkspace workspace)
throws IOException, GenericError
{
// create a socket for SAS to send result stream
// SocketListener is an AppDev Studio utility
SocketListener socket = new SocketListener();
int port = socket.setup();
socket.start();
// get IOM objects from Workspace
ILanguageService languageService = workspace.LanguageService();
IStoredProcessService stpService =
languageService.StoredProcessService();
// get stored process call info
String repository =
LocalEnvironment.getProperty("stp.repository");
String stpParams = buildParamString(params);
Log.debug("repository = "+repository);
Log.debug("stpName = "+stpName);
Log.debug("stpParams = "+stpParams);
// define fileref for socket and issue startup statements
initWorkspace(languageService, port);
// call stored process
stpService.Repository(repository);
languageService.Async(false);
Log.debug("calling stp");
stpService.Execute(stpName, stpParams);
// send SAS log to web app log
Log.debug("checking log");
dumpLog(languageService);
return socket;
}
在上面的代码中,使用了下面3个iom的接口
IWorkspace, ILanguageService, IStoredProcessService
SocketListener类用于监听SAS输出信息,通过端口号和SAS建立联络
该类还使用了2个实用类
LocalEnvironment 类用于环境信息初始和输出
Log类用于简单的记录输出
其他有用的方法,我们将在下面列出
private String buildParamString(Properties params)
{
StringBuffer paramBuff = new StringBuffer();
Iterator iter = params.keySet().iterator();
while (iter.hasNext())
{
String key = (String) iter.next();
paramBuff.append(key);
paramBuff.append('=');
paramBuff.append('/"');
paramBuff.append(params.getProperty(key));
paramBuff.append('/"');
paramBuff.append(' ');
}
String stpParams = paramBuff.toString();
return stpParams;
}
private void initWorkspace(ILanguageService languageService, int port)
throws IOException, GenericError
{
// create fileref to my server socket
// CHEAT ALERT: using localhost as host name for socket!
StringBuffer block = new StringBuffer();
block.append("filename _WEBOUT SOCKET ");
block.append('/'');
block.append("localhost");
block.append(':');
block.append(port);
block.append('/'');
block.append(';');
block.append("/n");
String startupStatement =
LocalEnvironment.getProperty("stp.startupStatement");
if (startupStatement != null)
block.append(startupStatement);
Log.debug("submitting "+block.toString());
languageService.Submit(block.toString());
}
private void dumpLog(ILanguageService languageService)
throws GenericError
{
int count = 0;
String log = null;
Log.sas("/nLOG START/n/n");
do
{
log = languageService.FlushLog(BUFFSIZE);
Log.sas(log);
count++;
}
while (log.length() == BUFFSIZE);
Log.sas("/nLOG END (" + count + ")/n");
}
这个指南演示如何在存储过程中使用ods格式化输出流并被用某种语言编写的应用所接收,如java语言
例子报告
首先我们引用一个简单例子,其用ods格式化输出2个html报表,由于其使用的是sashelp中的数据,故下面例子你可以直接运行在你的环境中,例子如下l 注:宏 ®ION 用于指示取数据的一个子集
%let REGION=Pacific;
ods html body="shoe_sales.html";
title Shoe Sales by Subsidiary;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary sales;
define subsidiary / group;
define sales / analysis sum;
run;
title Shoe Sales Detail;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary product stores sales;
define subsidiary / order;
define product / order;
define sales / analysis sum;
run;
ods html close;
转换上面例子报告到存储过程
只需要下面3个简单步骤就可以1、 每一个存储过程应该有一个标志用来指示其是存储过程,如下行,该行应该在%let 和 第一个ods输出之间
*ProcessBody;
2、 转换宏符号作为存储过程的参数,如下
%global REGION;
3、 我们应该初始化ods的开始和结束句子,在存储过程中,我们可以使用下面宏帮助我们自动初始化
%stpbegin
%stpend
改后的代码如下:
%global REGION;
*ProcessBody;
%stpbegin;
title Shoe Sales by Subsidiary;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary sales;
define subsidiary / group;
define sales / analysis sum;
run;
title Shoe Sales Detail;
title2 Region: ®ION;
proc report data=sashelp.shoes(where=(region="®ION")) nowd;
column subsidiary product stores sales;
define subsidiary / order;
define product / order;
define sales / analysis sum;
run;
%stpend;
调用存储过程
我们把该后的程序部署到存储过程服务器上去
一旦部署完成,我们就可以使用外部工具来访问该存储过程,如用excel (需要装Add-In for Microsoft Office)
当然,也可以通过浏览器来访问该存储过程
从java调用存储过程
你可以使用SAS IT APIS 来调用存储过程,你甚至可以使用SAS8.2来完成这一步骤
在开始写java代码前,我们应该明白下面概念
Integrated Object Model (IOM) 是我们远端调用SAS的API.
当我们连接到SAS时,我们将从SAS会话中获得workspace对象.
然后我们从Workspace.中取得其他服务对象
简单的java代码
要调用一个存储过程,你应该包含一个 IStoredProcessService 对象的引用并告诉它:
repository 位置,它是一个定位存储过程的目录路径,格式如 "file:/some/directory". 如果我们异步调用存储过程,那java将不会等待存储过程执行完
存储过车文件的名字
存储过程参数,如"name1=value1 name2=value2 …"
下面通过java定义了一个方法,用于设置且执行存储过程,代码如下:
executeImpl方法
private SocketListener executeImpl(
String stpName,
Properties params,
IWorkspace workspace)
throws IOException, GenericError
{
// create a socket for SAS to send result stream
// SocketListener is an AppDev Studio utility
SocketListener socket = new SocketListener();
int port = socket.setup();
socket.start();
// get IOM objects from Workspace
ILanguageService languageService = workspace.LanguageService();
IStoredProcessService stpService =
languageService.StoredProcessService();
// get stored process call info
String repository =
LocalEnvironment.getProperty("stp.repository");
String stpParams = buildParamString(params);
Log.debug("repository = "+repository);
Log.debug("stpName = "+stpName);
Log.debug("stpParams = "+stpParams);
// define fileref for socket and issue startup statements
initWorkspace(languageService, port);
// call stored process
stpService.Repository(repository);
languageService.Async(false);
Log.debug("calling stp");
stpService.Execute(stpName, stpParams);
// send SAS log to web app log
Log.debug("checking log");
dumpLog(languageService);
return socket;
}
在上面的代码中,使用了下面3个iom的接口
IWorkspace, ILanguageService, IStoredProcessService
SocketListener类用于监听SAS输出信息,通过端口号和SAS建立联络
该类还使用了2个实用类
LocalEnvironment 类用于环境信息初始和输出
Log类用于简单的记录输出
其他有用的方法,我们将在下面列出
绑定参数字符串
一个存储过程可以接收0个或者多个参数,如下private String buildParamString(Properties params)
{
StringBuffer paramBuff = new StringBuffer();
Iterator iter = params.keySet().iterator();
while (iter.hasNext())
{
String key = (String) iter.next();
paramBuff.append(key);
paramBuff.append('=');
paramBuff.append('/"');
paramBuff.append(params.getProperty(key));
paramBuff.append('/"');
paramBuff.append(' ');
}
String stpParams = paramBuff.toString();
return stpParams;
}
初始化SAS会话
如同通过api直接调用存储过程,SAS本身不知道是如何输出到指定的socket端口中取,而在默认情况下会输出到_webout中取,故我们可以在初始化时分配好_webout并指向指定的socket端口private void initWorkspace(ILanguageService languageService, int port)
throws IOException, GenericError
{
// create fileref to my server socket
// CHEAT ALERT: using localhost as host name for socket!
StringBuffer block = new StringBuffer();
block.append("filename _WEBOUT SOCKET ");
block.append('/'');
block.append("localhost");
block.append(':');
block.append(port);
block.append('/'');
block.append(';');
block.append("/n");
String startupStatement =
LocalEnvironment.getProperty("stp.startupStatement");
if (startupStatement != null)
block.append(startupStatement);
Log.debug("submitting "+block.toString());
languageService.Submit(block.toString());
}
获得SAS输出日志
直接调用languageService的flushlog方法可以及时地把日志输出private void dumpLog(ILanguageService languageService)
throws GenericError
{
int count = 0;
String log = null;
Log.sas("/nLOG START/n/n");
do
{
log = languageService.FlushLog(BUFFSIZE);
Log.sas(log);
count++;
}
while (log.length() == BUFFSIZE);
Log.sas("/nLOG END (" + count + ")/n");
}
相关文章推荐
- 存储过程的输出参数为游标,PL/SQL中如何调用 Java代码如何调用
- 如何写安全的Java Web应用之输入校验(一):不要在输出中包含Debug信息
- java调用输入、输出参数为对象的存储过程
- 如何在Oracle中使用Java存储过程 (详解)
- 如何在Oracle中使用Java存储过程 (详解)
- 如何创建Java存储过程
- 存储过程输出调试信息
- 如何实现在Oracle中应用存储过程调用MatLab函数(3)
- 如何用Jstack把java进程中的堆栈信息输出到文件
- Java多线程调试如何完成信息输出处理
- 如何在Oracle中使用Java存储过程(详解)
- JAVA如何调用mysql写的存储过程
- 【数据库】如何获取存储过程的输出参数值
- SQL2000系统表、存储过程、函数的功能介绍及应用2009年01月21日 星期三 11:38虽然使用系统存储过程、系统函数与信息架构视图已经可以为我们提供了相当丰富的元数据信息,但是对于某些特殊的元数据信息,我们仍然需要直接对系统表进行查询。因为SQL
- 学习笔记6-Android查看应用输出的错误信息 如何部署应用到真实手机 发布软件
- 如何获取存储过程的返回值和输出值
- Java调用Oracle集合类型输出参数的存储过程
- 【java工具】使用jdbc访问数据库获取某个存储过程信息及下面参数信息
- mysql 在存储过程中输出日志信息
- C#中如何获取存储过程的输出参数值