下面是工作中的一个实例。任务需求是查询几个相关数据表,然后把结果输出为csv文件。
1.先写一个sql文件,如果是在windows环境下运行要用ansi内码存盘。文件框架如下:
SET feedback off
SET pagesize 50000
SET linesize 20000
SET verify off
SET pagesize 0
SET term off
SET trims ON
SET heading off
SET trimspool ON
SET trimout ON
SET timing off
SET verify off
SET colsep
spool C:\Users\Administrator\Desktop\result.csv
--需要运行的sql语句写在这里。
spool off
quit
2.形成表头的sql语句
csv文件字段之间用逗号分隔,所以下面这句用来形成表头:
select ‘品名,规格,单位,有效期,数量,整件数量,零头数量‘ from dual;
3.查询结果字段之间用 ||‘,‘|| 这个形式分隔:
SELECT a.TRADE_NAME ||‘,‘|| a.SPECS ||‘,‘|| a.PACK_UNIT ||‘,‘|| b.VALID_DATE ||‘,‘|| b.STORE_SUM / b.pack_qty ||‘,‘||
CASE WHEN (select pkg_num from drug_packages where drug_name=a.TRADE_NAME) is null THEN 0 ELSE floor((b.STORE_SUM / b.pack_qty) / (select pkg_num from drug_packages where drug_name=b.TRADE_NAME)) END ||‘,‘||
CASE WHEN (select pkg_num from drug_packages where drug_name=a.TRADE_NAME) is null THEN (b.STORE_SUM / b.pack_qty) ELSE mod((b.STORE_SUM / b.pack_qty) ,(select pkg_num from drug_packages
where drug_name=a.TRADE_NAME)) END AS qty
FROM PHA_COM_BASEINFO a , PHA_COM_STOCKINFO b WHERE a.DRUG_CODE = b.DRUG_CODE
and b.DRUG_DEPT_CODE = ‘0039‘
and b.drug_code in (select DISTINCT DRUG_CODE from PHA_COM_APPLYOUT WHERE trunc(apply_date) = trunc(sysdate) AND DRUG_DEPT_CODE = ‘0039‘)
AND (b.DRUG_QUALITY = ‘ALL‘ OR ‘ALL‘ = ‘ALL‘)
ORDER BY a.drug_type, a.CUSTOM_CODE ;
4.case when end 结构的使用
这个查询有两个字段是计算出来的。为便于清点,需要根据库存数量计算出库存一共有多少整件,多数零头。
计算字段先要查询些该品种是否在整件包装规格的表内,如果在,取出数值进行计算然后显示,不在则直接显示。计算零头数语句如下:
CASE
WHEN (select pkg_num from drug_packages where drug_name=a.TRADE_NAME) is null
THEN (b.STORE_SUM / b.pack_qty)
ELSE mod((b.STORE_SUM / b.pack_qty) ,(select pkg_num from drug_packages where drug_name=a.TRADE_NAME))
END
5.其它需要注意的地方
spool后面似乎只能用绝对路径。相对路径不好使。
写好sql之后可以再写一个bat文件让这些东西在系统环境下直接调用。
这里写了一个 calc.bat ,内容如下:
sqlplus user/password@orcl @dev_tools\count.sql
直接运行这个批处理文件,结果就spool指定的位置生成好了。
6.总结
起初这个任务想用python或者C++来写,但后来发现oracle自己就提供了很多方便工具。本着越简单越好的原则就上面的方法解决了问题。在工作中充分发掘基础工具的功能来完成任务可以减少很多麻烦。