oracle 在SQL*Plus上格式化报告中的输出(假脱机到CSV后)

oymdgrw7  于 2022-12-26  发布在  Oracle
关注(0)|答案(3)|浏览(137)

我有一个关于格式化报告中的输出的问题,我从csv中获得的,从SQL * Plus假脱机。我有一个初始表,其数据如下所示:
| 订单编号|ls_产品_部门|ls_产品_面积|ls_产品系列名称|ls产品系列代码|ls产品通用名称|ls_品牌_名称|ls_参考_产品|ls_描述|ls_atc_代码|ls_atc_描述|ls_适应症|最小值_平均值_药物水平|ls_inds_中间驱动器|ls_ind_医疗器械代码|ls_c指示|ls_psur_int_生日|ls_数据_整数_出生日期|ls_eu_出生日期|ls_压力_参考_日期|ls_压力_类型|ls_压力_子系统_频率_值|LS_压力_子频率_单位|ls_日期_压力_开始|ls_日期_压力_结束|ls_压力_提交_到期日|
| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------|
| 1个||药品|醋氯芬酸||醋氯芬酸|醋氯芬酸1.5% w/w乳膏|||第16章|醋氯芬酸|镇痛和抗炎|||||||||||||||
| 1个||药品|醋氯芬酸||醋氯芬酸|醋氯芬酸100 mg片剂|||第16章|醋氯芬酸|非甾体抗炎药|||||||||||||||
| 1个||药品|醋氯芬酸||醋氯芬酸|醋氯芬酸100 mg片剂|||第16章|醋氯芬酸|抗炎药|||||||||||||||
| 1个||药品|醋氯芬酸||醋氯芬酸|醋氯芬酸100 mg片剂|||一月|抗炎和抗风湿产品|抗炎药|||||||||||||||
我尝试格式化该表的报告输出,因此得到如下结果:
| 订单编号|ls_产品_部门|ls_产品_面积|ls_产品系列名称|ls产品系列代码|ls产品通用名称|ls_品牌_名称|ls_参考_产品|ls_描述|ls_atc_代码|ls_atc_描述|ls_适应症|最小值_平均值_药物水平|ls_inds_中间驱动器|ls_ind_医疗器械代码|ls_c指示|ls_psur_int_生日|ls_数据_整数_出生日期|ls_eu_出生日期|ls_压力_参考_日期|ls_压力_类型|ls_压力_子系统_频率_值|LS_压力_子频率_单位|ls_日期_压力_开始|ls_日期_压力_结束|ls_压力_提交_到期日|
| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------|
| 1个||药品|醋氯芬酸||醋氯芬酸|醋氯芬酸1.5% w/w乳膏|||第16章|醋氯芬酸|镇痛和抗炎|||||||||||||||
| 1个||||||醋氯芬酸100 mg片剂|||一月|抗炎和抗风湿产品|非甾体抗炎药|||||||||||||||
| 1个|||||||||||抗炎药|||||||||||||||
| 1个|||||||||||抗炎药|||||||||||||||
我使用下面的代码:

set colsep '|'
set trimspool on
set termout off
set echo off
set trim on
set heading on
set feedback off
set linesize 32000
set trimout on
set pagesize 50000
set underline off
col ord_no format 99999
col ls_prod_area format a200
col ls_prod_family_name format a200
col ls_prod_family_code format a200
col ls_prod_generic_name format a200
col ls_brand_name format a200
col ls_reference_prod format a200
col ls_description format a200
col ls_atc_code format a200
col ls_atc_desc format a200
col ls_indication format a200
col ls_ind_meddra_lvl format a200
col ls_ind_meddra_ver format a200
col ls_ind_meddra_code format a200
spool export.csv
break on ls_prod_area on ls_prod_family_name on ls_prod_generic_name on ls_atc_code on ls_atc_desc on ls_brand_name on ls_indication

SELECT rpad(ord_no, 200, ' ') ord_no ,rpad(ls_prod_area, 200, ' ') ls_prod_area ,rpad(ls_prod_family_name, 200, ' ') ls_prod_family_name ,rpad(ls_prod_family_code, 200, ' ') ls_prod_family_code ,rpad(ls_prod_generic_name, 200, ' ') ls_prod_generic_name ,rpad(ls_brand_name, 200, ' ') ls_brand_name ,rpad(ls_reference_prod, 200, ' ') ls_reference_prod,rpad(ls_description, 200, ' ') ls_description ,rpad(ls_atc_code, 200, ' ') ls_atc_code ,rpad(ls_atc_desc, 200, ' ') ls_atc_desc ,rpad(ls_indication, 200, ' ') ls_indication ,rpad(ls_ind_meddra_lvl, 200, ' ') ls_ind_meddra_lvl ,rpad(ls_ind_meddra_ver, 200, ' ') ls_ind_meddra_ver ,rpad(ls_ind_meddra_code, 200, ' ') ls_ind_meddra_code 
from tmp_product_family
order by ord_no, ls_brand_name,LS_ATC_CODE, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL, LS_IND_MEDDRA_VER, LS_IND_MEDDRA_CODE ;

我没有在CMD窗口中输出的问题,但通过Excel的文本/CSV工具转换CSV到Excel。我把自定义分隔符设置为'| '.
对于第一个ord_no(1),从CSV转换为Excel的第一行和第二行如下所示:
| 指令编号|LS_生产区|LS产品系列名称|LS产品系列代码|LS产品通用名称|LS品牌名称|LS_参比品_产品|LS_描述|LS ATC代码|LS_ATC_描述|LS_适应症|LS_IND_医疗器械_水平|LS_IND_药物_版本|LS_IND_医疗器械_代码|
| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------| - ------|
| 1个|药品|醋氯芬酸||醋氯芬酸|醋氯芬酸1.5% w/w乳膏|||第16章|醋氯芬酸|镇痛和抗炎||||
| 1个||醋氯芬酸100 mg片剂|||一月|抗炎和抗风湿产品|抗炎药|||||||
如第二行所示,ord_no之后的所有值都向左移动了三列(例如,Aceclofenac 100 mg tablets应位于LS_BRAND_NAME列)。
有谁知道如何摆脱这个问题。

qv7cva1a

qv7cva1a1#

当你问到break时,这就是我的意思。
普通查询,其中所有“单元格”都填充有数据:

SQL> select d.dname, e.job, e.ename, e.sal
  2  from emp e join dept d on d.deptno = e.deptno
  3  order by d.dname, e.job;

DNAME          JOB       ENAME             SAL
-------------- --------- ---------- ----------
ACCOUNTING     CLERK     MILLER           1300
ACCOUNTING     MANAGER   CLARK            2450
ACCOUNTING     PRESIDENT KING             5000
RESEARCH       ANALYST   SCOTT            3000
RESEARCH       ANALYST   FORD             3000
RESEARCH       CLERK     ADAMS            1100
RESEARCH       CLERK     SMITH             840
RESEARCH       MANAGER   JONES            2975
SALES          CLERK     JAMES             950
SALES          MANAGER   BLAKE            2850
SALES          SALESMAN  MARTIN           1250
SALES          SALESMAN  WARD             1250
SALES          SALESMAN  ALLEN            1600
SALES          SALESMAN  TURNER           1500

14 rows selected.

如果您在部门名称和职务等项上添加一个中断符,您将得到您所需的结果:

SQL> spool stefek.csv
SQL> break on dname on job
SQL> select d.dname, e.job, e.ename, e.sal
  2  from emp e join dept d on d.deptno = e.deptno
  3  order by d.dname, e.job;

DNAME          JOB       ENAME             SAL
-------------- --------- ---------- ----------
ACCOUNTING     CLERK     MILLER           1300
               MANAGER   CLARK            2450
               PRESIDENT KING             5000
RESEARCH       ANALYST   SCOTT            3000
                         FORD             3000
               CLERK     ADAMS            1100
                         SMITH             840
               MANAGER   JONES            2975
SALES          CLERK     JAMES             950
               MANAGER   BLAKE            2850
               SALESMAN  MARTIN           1250
                         WARD             1250
                         ALLEN            1600
                         TURNER           1500

14 rows selected.

SQL> spool off
SQL>

如果您在Excel中打开该文件,将得到以下内容:
1.在2016版中,转到“数据-来自文本”并按照向导操作
1.选择“固定宽度”
1.必要时移动分隔线
1.查看结果

连接到SQL*Plus

你应该知道用户名,密码和数据库你连接。例如,我正在扫描我的TNSNAMES.ORA文件与mctnsping实用程序(编写的Michel Cadot;它不需要Oracle客户端即可工作。您可以在OraFAQ Forum上找到它)。或者,如果您有TNSPING,请使用它:

C:\Temp>mctnsping orcl

McTnsping Utility by Michel Cadot: Version 2021.12.03 on 20-PRO-2022 14:09:02

Copyright (c) Michel Cadot, 2016-2021. All rights reserved.

Using ping version 11

Used parameter files:
C:\Users\littlefoot\Documents\sqlnet.ora
C:\Users\littlefoot\Documents\tnsnames.ora

Found tnsnames.ora entry:
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=db_orcl)(PORT=1521))(CONNECT_DATA=(SID=orcl)))

Attempting to contact db_orcl:1521
OK (46 msec)

现在,使用你收集的数据;连接字符串的格式为@database_server:port/service_name

C:\Temp>sqlplus scott/tiger@db_orcl:1521/orcl

SQL*Plus: Release 18.0.0.0.0 - Production on Uto Pro 20 14:09:17 2022
Version 18.5.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
   
SQL> select * from dual;

D
-
X

SQL>
hts6caw3

hts6caw32#

如果只有最少的样本数据:

CREATE TABLE table_name (a, b, c, d ) AS
  SELECT 'A1', 'B1', 'C1', 'D1' FROM DUAL UNION ALL
  SELECT 'A2', 'B1', 'C2', 'D1' FROM DUAL UNION ALL
  SELECT 'A3', 'B2', 'C2', 'D1' FROM DUAL UNION ALL
  SELECT 'A4', 'B3', 'C2', 'D1' FROM DUAL;

并且您希望将数据沿行向上移动,以便不显示重复项,则可以对每列中的值进行排序,取消透视,然后重新透视数据:

SELECT a, b, c, d
FROM   (
  SELECT a, b, c, d,
         DENSE_RANK() OVER (ORDER BY a) AS a_rnk,
         DENSE_RANK() OVER (ORDER BY b) AS b_rnk,
         DENSE_RANK() OVER (ORDER BY c) AS c_rnk,
         DENSE_RANK() OVER (ORDER BY d) AS d_rnk
  FROM   table_name
)
UNPIVOT (
  (value, rnk) FOR key IN (
    (a, a_rnk) AS 'A',
    (b, b_rnk) AS 'B',
    (c, c_rnk) AS 'C',
    (d, d_rnk) AS 'D'
  )
)
PIVOT (
  MAX(value) FOR key IN ('A' AS a, 'B' AS b, 'C' AS c, 'D' AS d)
)
ORDER BY rnk

其输出:
| A类|B| C级|D级|
| - ------|- ------|- ------|- ------|
| A1|地下一层|C1|第1天|
| A2| B2| C2| * 无效 *|
| A3| B3| * 无效 | 无效 *|
| A4| * 无效 | 无效 | 无效 *|
fiddle

nfzehxib

nfzehxib3#

我实际上是通过将分隔符从'| '到固定宽度0,800,1000,1200等。现在工作得很好,所以谢谢你们所有人的努力。我需要一点更多的调整与休息的命令,但我认为这解决了我所有未来的报告问题。巨大的感谢@Littlefoot,荣誉使我的生活更容易。
Solved import from Text/CSV
除了使用SQL * Plus和break on命令之外,我还在SQL Developer中使用LAG函数和一些partition by子句,然后将列值与前面的行进行比较,从而实现了同样的目的。
大概是这样的

SELECT ord_no,case when ls_prod_area=prev_ls_prod_area then null else ls_prod_area end,case when ls_prod_family_name=prev_ls_prod_family_name then null else ls_prod_family_name end,ls_prod_family_code,case when ls_prod_generic_name=prev_ls_prod_generic_name then null else ls_prod_generic_name end,case when ls_brand_name=prev_ls_brand_name then null else ls_brand_name end,ls_reference_prod,ls_description,case when ls_atc_code=prev_ls_atc_code then null else ls_atc_code end,case when ls_atc_desc=prev_ls_atc_desc then null else ls_atc_desc end,case when ls_indication=prev_ls_indication then null else ls_indication end,case when ls_ind_meddra_lvl=prev_ls_ind_meddra_lvl then null else ls_ind_meddra_lvl end,case when ls_ind_meddra_ver=prev_ls_ind_meddra_ver then null else ls_ind_meddra_ver end,case when ls_ind_meddra_code=prev_ls_ind_meddra_code then null else ls_ind_meddra_code end
  FROM (
SELECT ord_no,ls_prod_area,ls_prod_family_name,ls_prod_family_code,ls_prod_generic_name,ls_brand_name,ls_reference_prod,ls_description,ls_atc_code,ls_atc_desc,ls_indication,ls_ind_meddra_lvl,ls_ind_meddra_ver,ls_ind_meddra_code,
       LAG( ls_prod_area, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE) AS prev_ls_prod_area,
       LAG( ls_prod_family_name, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_prod_family_name,
       LAG( ls_prod_generic_name, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_prod_generic_name,
        LAG( ls_brand_name, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_brand_name,
        LAG( ls_atc_code, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_atc_code,
        LAG( ls_atc_desc, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_atc_desc,
        LAG( ls_indication, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_indication,
        LAG( ls_ind_meddra_lvl, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_ind_meddra_lvl,
        LAG( ls_ind_meddra_ver, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_ind_meddra_ver,
        LAG( ls_ind_meddra_code, 1 ) OVER ( PARTITION BY ord_no ORDER BY ord_no, ls_brand_name, LS_ATC_CODE desc, LS_ATC_DESC, LS_INDICATION, LS_IND_MEDDRA_LVL nulls last, LS_IND_MEDDRA_VER nulls last, LS_IND_MEDDRA_CODE ) AS prev_ls_ind_meddra_code
        FROM tmp_product_family);

相关问题