• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

Oracle中使用PL/SQL操作COM对象

发布: 2008-9-05 14:05 | 作者: 网络转载 | 来源: blog | 查看: 55次 | 进入软件测试论坛讨论

领测软件测试网

数据包体内容(PACKAGE BODY)

CREATE OR REPLACE PACKAGE BODY oraExcel IS
FUNCTION CreateExcelWorkSheet(servername VARCHAR2) RETURN BINARY_INTEGER IS
BEGIN
-- 创建Excel对象
i:=ordcom.CreateObject(’Excel.Application’, 0, servername,applicationToken);
IF (i!=0) THEN -- 创建失败,提示返回的错误信息
ordcom.GetLastError(err_src, err_desc, err_hpf, err_hpID);
raise_application_error(-20000,err_src || err_desc || err_hpf || err_hpID);
END IF;
-- 通过程序对象句柄获取工作簿句柄
i:=ordcom.GetProperty(applicationToken, ’WorkBooks’, 0, WorkBooksToken);
ordcom.InitArg();
ordcom.SetArg(-4167,’I4’);
i:=ordcom.Invoke(WorkBooksToken, ’Add’, 1, WorkBookToken);
ordcom.InitArg();
ordcom.SetArg(’Sheet 1’,’BSTR’);

-- 获取工作表句柄
i:=ordcom.GetProperty(applicationToken, ’WorkSheets’, 0, WorkSheetToken1);
i:=ordcom.Invoke(WorkSheetToken1, ’Add’, 0, WorkSheetToken);
RETURN i;
END CreateExcelWorkSheet;
FUNCTION setCellValues(RANGE VARCHAR2,data VARCHAR2, TYPE VARCHAR2)
RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE,’BSTR’);
-- 获取Range区句柄,之后将数据写入到指定的单元格
i:=ordcom.GetProperty(WorkSheetToken, ’Range’, 1, RangeToken);
i:=ordcom.SetProperty(RangeToken, ’Value’, data, TYPE);
i:=ordcom.DestroyObject(RangeToken);
RETURN i;
END setCellValues;
FUNCTION setCellValues(RANGE VARCHAR2,data BINARY_INTEGER,TYPE VARCHAR2)
RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE, ’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken, ’Range’, 1, RangeToken);
i:=ordcom.SetProperty(RangeToken, ’Value’, data, type);
i:=ordcom.DestroyObject(RangeToken);
RETURN i;
END setCellValues;
FUNCTION setCellValuesReal(RANGE VARCHAR2,data DOUBLE PRECISION,TYPE VARCHAR2)
RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE, ’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken, ’Range’, 1, RangeToken);
i:=ordcom.SetProperty(RangeToken, ’Value’, data, type);
i:=ordcom.DestroyObject(RangeToken);
RETURN i;
END setCellValuesReal;
FUNCTION setCellValues(RANGE VARCHAR2,data DATE,TYPE VARCHAR2)
RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE, ’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken, ’Range’, 1, RangeToken);
i:=ordcom.SetProperty(RangeToken, ’Value’, data, TYPE);
i:=ordcom.DestroyObject(RangeToken);

RETURN i;
END setCellColWidth;
FUNCTION setCellMerge(RANGE VARCHAR2,bValues BOOLEAN,TYPE VARCHAR2)
RETURN i;
END setCellValues;
FUNCTION setCellColWidth(RANGE VARCHAR2,width DOUBLE PRECISION,TYPE VARCHAR2)
RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE,’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken,’Range’,1,RangeToken);
i:=ordcom.SetProperty(RangeToken,’ColumnWidth’,width,TYPE);
i:=ordcom.DestroyObject(RangeToken);
RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE,’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken,’Range’,1,RangeToken);
i:=ordcom.SetProperty(RangeToken,’MergeCells’,bValues,’BOOLEAN’);
i:=ordcom.DestroyObject(RangeToken);
RETURN i;
END setCellMerge;
FUNCTION setCellLines(RANGE VARCHAR2,BordersIndex BINARY_INTEGER,
weight BINARY_INTEGER DEFAULT xlThin,TYPE VARCHAR2) RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE,’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken,’Range’,1,RangeToken);
ordcom.InitArg();
ordcom.SetArg(BordersIndex,TYPE); -- 画表格的具体载入参数
i:=ordcom.GetProperty(RangeToken,’Borders’,1,hLines);
i:=ordcom.SetProperty(hLines,’weight’,weight,TYPE);
i:=ordcom.DestroyObject(hLines);
i:=ordcom.DestroyObject(RangeToken);
RETURN i;
END setCellLines;
FUNCTION setCellFont(RANGE VARCHAR2,Property VARCHAR2,fontValues BINARY_INTEGER,TYPE
VARCHAR2) RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE,’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken,’Range’,1,RangeToken);
ordcom.InitArg();
ordcom.SetArg(Property,TYPE);

ordcom.InitArg();
i:=ordcom.GetProperty(WorkSheetToken, ’ChartObjects’, 0, ChartObjectToken);
ordcom.InitArg();
ordcom.SetArg(xpos,’I2’); -- 载入图表对象位置参数
ordcom.SetArg(ypos,’I2’);
ordcom.SetArg(width,’I2’);
ordcom.SetArg(height,’I2’);
i:=ordcom.Invoke(ChartObjectToken, ’Add’, 4, ChartObject1); -- 添加图表
i:=ordcom.GetProperty(ChartObject1, ’Chart’, 0,Chart1Token);
ordcom.InitArg();
ordcom.SetArg(RANGE, ’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken,’Range’, 1, RangeToken); -- 选取区域
ordcom.InitArg();
ordcom.SetArg(RangeToken, ’DISPATCH’);
IF TYPE=’xlPie’ THEN
charttype := -4102;
ELSIF TYPE=’xl3DBar’ THEN
charttype := -4099;
ELSIF TYPE=’xlBar’ THEN
charttype := 2;
ELSIF TYPE=’xl3dLine’ THEN
i:=ordcom.GetProperty(RangeToken,’Font’,0,hLines); -- 获取字体对象
i:=ordcom.SetProperty(hLines,Property,fontValues,TYPE);
i:=ordcom.DestroyObject(hLines);
i:=ordcom.DestroyObject(RangeToken);
RETURN i;
END;
FUNCTION callMethod(RANGE VARCHAR2,MethodName VARCHAR2) RETURN BINARY_INTEGER IS
reti BINARY_INTEGER := -1;
BEGIN
ordcom.InitArg();
ordcom.SetArg(RANGE,’BSTR’);
i:=ordcom.GetProperty(WorkSheetToken,’Range’,1,RangeToken);
ordcom.InitArg();
i:=ordcom.Invoke(RangeToken,MethodName,0,reti); -- 调用对象的方法
i:=ordcom.DestroyObject(RangeToken);
RETURN reti;
END;
FUNCTION InsertChart(xpos BINARY_INTEGER, ypos BINARY_INTEGER,
width BINARY_INTEGER, height BINARY_INTEGER,
RANGE VARCHAR2, TYPE VARCHAR2)
RETURN BINARY_INTEGER IS
charttype BINARY_INTEGER:= -4099;
BEGIN

charttype:= -4101;
END IF;
ordcom.SetArg(charttype,’I4’);
i:=ordcom.Invoke(Chart1Token,’ChartWizard’, 2, DummyToken);
i:=ordcom.DestroyObject(RangeToken);
i:=ordcom.DestroyObject(ChartObjectToken);
i:=ordcom.DestroyObject(ChartObject1);
i:=ordcom.DestroyObject(Chart1Token);
RETURN i;
END InsertChart;
FUNCTION SaveToFile(filename VARCHAR2) RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.SetArg(filename,’BSTR’);
i:=ordcom.Invoke(WorkBookToken, ’SaveAs’, 1, DummyToken); -- 保存文件
IF (i!=0) THEN
ordcom.GetLastError(err_src, err_desc, err_hpf, err_hpID);
raise_application_error(-20000,err_src || err_desc || err_hpf || err_hpID);
END IF;
RETURN i;
END SaveToFile;
FUNCTION CloseExcel RETURN BINARY_INTEGER IS
BEGIN
ordcom.InitArg();
ordcom.InitArg();
ordcom.SetArg(FALSE,’BOOL’);
i:=ordcom.Invoke(WorkBookToken, ’Close’, 0, DummyToken);
i:=ordcom.DestroyObject(WorkBookToken);
ordcom.InitArg();
i:=ordcom.Invoke(WorkBooksToken, ’Close’, 0, DummyToken);
i:=ordcom.DestroyObject(WorkBooksToken);
i:=ordcom.Invoke(applicationToken, ’Quit’, 0, DummyToken);
-- 关闭所有句柄
i:=ordcom.DestroyObject(WorkSheetToken);
i:=ordcom.DestroyObject(WorkSheetToken1);
i:=ordcom.DestroyObject(applicationToken);
i:=ordcom.DestroyObject(ChartObjectToken);
i:=ordcom.DestroyObject(Chart1Token);
i:=ordcom.DestroyObject(hLines);
i:=ordcom.DestroyObject(ChartObject1);
i:=ordcom.DestroyObject(dummyToken);
RETURN i;
END CloseExcel;
END oraExcel;

  成功创建oraExcel包后,最后创建使用包的存储过程,实现把数据表里的字符型、日期型和数值型分别传到Excel工作表里,对数值型数据进行统计和使用Excel中的图表。该过程具体操作步骤为:

  ·创建Excel对象。

  ·建立表头,设置列宽。

  ·将游标数据传到工作表。

  ·画表格。

  ·设置字体属性。

  ·插入图表。

  ·保存为Excel格式文件,关闭Excel对象。

  如下为dp_toExcel存储过程:

CREATE OR REPLACE PROCEDURE dp_ToExcel IS
CURSOR c1 IS SELECT ITS_ID,ITS_DATE,ITS_TOTAL FROM IT_SALE_TAB;
n BINARY_INTEGER:=2;
i BINARY_INTEGER;
filename VARCHAR2(255);
cellIndex VARCHAR2(40);
cellValue VARCHAR2(40);
cellColumn VARCHAR2(10);
returnedTime VARCHAR2(20);
currencyvalue DOUBLE PRECISION;
dateValue DATE;
xlThin BINARY_INTEGER:=2;
xlEdgeLeft BINARY_INTEGER:=7;
xlEdgeTop BINARY_INTEGER:=8;
xlEdgeBottom BINARY_INTEGER:=9;
xlEdgeRight BINARY_INTEGER:=10;
xlInsideVertical BINARY_INTEGER:=11;
xlInsideHorizontal BINARY_INTEGER:=12;
BEGIN
i:=oraExcel.CreateExcelWorkSheet(’’);
i:=oraExcel.setCellValues(’A2’, ’序号’, ’BSTR’);
i:=oraExcel.setCellValues(’B2’, ’日期’, ’BSTR’);
i:=oraExcel.setCellValues(’C2’, ’销售’, ’BSTR’);

cellValue:=c1_rec.ITS_TOTAL;
currencyValue:=cellValue;
i:=oraExcel.setCellValuesReal(cellIndex, currencyValue, ’CY’);
n:=n+1;
END LOOP;
i:=oraExcel.setCellValues(’A’||n,’合计’,’BSTR’);
i:=oraExcel.setCellValues(’C’||n,’=SUM(C3:C’||to_char(n-1)||’)’,’BSTR’);
-- 画表格
i:=oraExcel.setCellLines(’A1:C’||n,xlEdgeLeft,xlThin,’I2’);
i:=oraExcel.setCellLines(’A1:C’||n,xlEdgeTop,xlThin,’I2’);
i:=oraExcel.setCellLines(’A1:C’||n,xlEdgeBottom,xlThin,’I2’);
i:=oraExcel.setCellLines(’A1:C’||n,xlEdgeRight,xlThin,’I2’);
i:=oraExcel.setCellLines(’A1:C’||n,xlInsideVertical,xlThin,’I2’);
i:=oraExcel.setCellLines(’A1:C’||n,xlInsideHorizontal,xlThin,’I2’);
-- 设置字体属性
i:=oraExcel.setCellFont(’A1:C1’,’Size’,20,’I2’);
i:=oraExcel.setCellFont(’A1:C1’,’Bold’,1,’I2’);
i:=oraExcel.callMethod(’A1:C1’,’Merge’); -- 合并单元格
i:=oraExcel.setCellValues(’A1:C1’,’合计’,’BSTR’);
-- 插入图表
i:=oraExcel.setCellColWidth(’B:B’, 12.75,’CY’); -- 设置列宽
i:=oraExcel.setCellColWidth(’C:C’, 12.75,’CY’);
n:=3;
For c1_rec IN c1 LOOP
cellColumn:=TO_CHAR(n);
cellIndex:= ’A’||cellColumn;
cellValue:= TO_CHAR(c1_rec.ITS_ID);
i:=oraExcel.setCellValues(cellIndex, cellValue, ’BSTR’);
cellIndex:= ’B’ || cellColumn;
dateValue:=c1_rec.ITS_DATE;
i:=oraExcel.setCellValues(cellIndex, dateValue, ’DATE’);
cellIndex:= ’C’ || cellColumn;
i:=oraExcel.InsertChart(350,200,250,250,’C3:C’||TO_CHAR(n-1),’xlPie’);
SELECT TO_CHAR(SYSDATE, ’HH24MISS’) INTO returnedTime FROM dual;
filename:=’D:\testExcel’ || returnedTime || ’.xls’;
i:=oraExcel.SaveToFile(filename); -- 保存文件
i:=oraExcel.closeExcel(); -- 关闭对象
END;

  小结

  本文介绍如何从PL/SQL中直接调用C程序的外部例程,并以操作Excel对象为示例。在调用该外部例程时,有如下相关的限制:

  ·操作系统必需支持动态链接库(DLL)和共享库功能。

  ·监听器和extproc进程必须运行在数据库所在的同一台机子上,不支持远程数据库。

  ·extproc唯一支持的是C例程,但可以通过先调用C外部例程去使用其它对象(如:COM对象)。

  除了限制外,调用外部例程会引起额外的系统资源开销,在使用外部例程之前要考虑是否一定要用到外部例程。

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/

22/2<12

关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网