管理层决定从db2 Luw v9迁移。到Oracle 11g。
这是我创建的DB2查询,用于将一堆数据转储到分隔文件中(在bash脚本中)。
EXPORT TO /tmp/dod.v3.del OF DEL MODIFIED BY NOCHARDEL COLDEL| DATESISO MESSAGES /tmp/dod.v3.msg SELECT DISTINCT A.CAMID, A.POSTTIME, A.MODDATE,A.RID,A.SOFTWAREVERSION,B.IPINFO,B.NUMBE ROFRESETSSINCELASTSWDL,C.TOTALNUMOFCOMPLETEDDLS,C. TOTALNUMBEROFDOWNLOADSSTARTED,C.DAILYDOWNLOADSIZE, C.DAILYDOWNLOADTIME,CONCAT(A.MODELNUMBER,(CONCAT('-',A.MANUFACTURERID))) FROM DMS.STBHEADER A JOIN DMS.STBSTATUS B ON A.DMS_ID=B.DMS_ID AND A.MODDATE = CURRENT_DATE - 1 DAY AND A.CAMID NOT IN (-11,125,117) LEFT JOIN DMS.BBVODSTATS C ON A.DMS_ID=C.DMS_ID FOR FETCH ONLY WITH UR;
数据输出看起来很漂亮,像这样整洁
2925917748|2003-12-05-17.26.58.000000|2013-11-03|36816426252|740||0|||||H25-500
3030176931|2004-11-07-11.48.52.000000|2013-11-03|25167455119|797||15|0|4|0|0|HR44-700
3026464853|2004-11-07-12.40.54.000000|2013-11-03|25166398575|797||17|0|3|0|0|HR44-500
这是我创建的ORACLE查询(在bash脚本中)
SET ARRAYSIZE 5000 FEEDBACK OFF ECHO OFF HEADING OFF LIN 999 MAXD 999 NEWP NONE;
SET RECSEP OFF TERM OFF TRIM ON TRIMSPOOL ON TRUNCATE OFF UND OFF VER OFF WRA OFF;
SET COLSEP |;
COLUMN CAMID FORMAT 9999999999999;
COLUMN RID FORMAT 9999999999999;
spool /tmp/dod.v3.del.ora;
SELECT DISTINCT
A.CAMID,
LTRIM(RTRIM(TO_CHAR(A.POSTTIME,'YYYY-MM-DD-HH24.MI.SS.FF6'),' ') ,' '),
LTRIM(RTRIM(TO_CHAR(A.MODDATE,'YYYY-MM-DD') , ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(A.RID), ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(A.SOFTWAREVERSION), ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(B.IPINFO), ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(B.NUMBEROFRESETSSINCELASTSWDL) , ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(C.TOTALNUMOFCOMPLETEDDLS) , ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(C.TOTALNUMBEROFDOWNLOADSSTARTE D) , ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(C.DAILYDOWNLOADSIZE) , ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(C.DAILYDOWNLOADTIME) , ' ') ,' '),
LTRIM(RTRIM(TO_CHAR(CONCAT(A.MODELNUMBER,(CONCAT('-',A.MANUFACTURERID))) ), ' ') ,' ')
FROM
DMS.STBHEADER A
JOIN
DMS.STBSTATUS B
ON A.DMS_ID=B.DMS_ID
AND
A.CAMID NOT IN (-11,125,117)
LEFT JOIN
DMS.BBVODSTATS C
ON A.DMS_ID=C.DMS_ID;
数据输出是整个地方的一堆领先/尾随空格(添加R / LTRIMS没有效果):
1814861090|2013-08-27-08.05.17.000000 |2013-08-30|28883762982 |736 |null |0 |4 |4 |0 |0 |HR21-700
2072851526|2013-08-27-08.05.29.000000 |2013-08-30|33064562144 |736 |null |1 |42 |42 |0 |0 |HR24-500
这是DB2表的DDL
Data type Column
Column name schema Data type name Length Scale Nulls
------------------------------- --------- ------------------- ---------- ----- ------
CAMID SYSIBM BIGINT 8 0 No
RID SYSIBM BIGINT 8 0 No
SOFTWAREVERSION SYSIBM VARCHAR 25 0 Yes
MODELNUMBER SYSIBM VARCHAR 25 0 Yes
MANUFACTURERID SYSIBM VARCHAR 25 0 Yes
POSTTIME SYSIBM TIMESTAMP 10 6 Yes
MODDATE SYSIBM DATE 4 0 No
NUMBEROFRESETSSINCELASTSWDL SYSIBM INTEGER 4 0 Yes
IPINFO SYSIBM VARCHAR 100 0 Yes
TOTALNUMOFCOMPLETEDDLS SYSIBM BIGINT 8 0 Yes
TOTALNUMBEROFDOWNLOADSSTARTED SYSIBM BIGINT 8 0 Yes
DAILYDOWNLOADSIZE SYSIBM BIGINT 8 0 Yes
DAILYDOWNLOADTIME SYSIBM BIGINT 8 0 Yes
这是Oracle表的DDL
Name Null? Type
----------------------------------------- -------- ----------------------------
CAMID NOT NULL NUMBER
RID NOT NULL NUMBER
SOFTWAREVERSION VARCHAR2(25)
MODELNUMBER VARCHAR2(25)
MANUFACTURERID VARCHAR2(25)
POSTTIME TIMESTAMP(6)
MODDATE NOT NULL TIMESTAMP(0)
NUMBEROFRESETSSINCELASTSWDL NUMBER
IPINFO VARCHAR2(100)
TOTALNUMOFCOMPLETEDDLS NUMBER
TOTALNUMBEROFDOWNLOADSSTARTED NUMBER
DAILYDOWNLOADSIZE NUMBER
DAILYDOWNLOADTIME NUMBER
我在这里缺少什么?如何在Oracle中修复我的查询?
答案 0 :(得分:3)
输出仍在列中,而Oracle(或更确切地说,SQL * Plus)不会删除每行值内的空格,因此即使TRIM
字符串列的值不同,所有行都是将显示具有相同宽度的列。它还增加了列宽以允许隐藏的标题,这使事情变得更糟。例如,第二列的派生标题(如果已显示)将为LTRIM(RTRIM(TO_CHAR(A.POSTTIME,'YYYY-MM-DD-HH24.MI.SS.FF6'),''),'')
,因此即使所有值都短于此列,列也将显示为67个字符宽。您可以通过使用较短名称对列进行别名来部分阻止它,但您仍然会为空值设置空格。
我发现真正剥离所有内容的唯一方法就是手动将列与分隔符连接起来,这会产生一列输出:
SELECT DISTINCT
A.CAMID
||'|'|| TO_CHAR(A.POSTTIME,'YYYY-MM-DD-HH24.MI.SS.FF6')
||'|'|| TO_CHAR(A.MODDATE,'YYYY-MM-DD')
||'|'|| A.RID
||'|'|| A.SOFTWAREVERSION
||'|'|| B.IPINFO
||'|'|| B.NUMBEROFRESETSSINCELASTSWDL
||'|'|| C.TOTALNUMOFCOMPLETEDDLS
||'|'|| C.TOTALNUMBEROFDOWNLOADSSTARTED
||'|'|| C.DAILYDOWNLOADSIZE
||'|'|| C.DAILYDOWNLOADTIME
||'|'|| A.MODELNUMBER ||'-'|| A.MANUFACTURERID
FROM
STBHEADER A
JOIN
STBSTATUS B
ON A.DMS_ID=B.DMS_ID
AND
A.CAMID NOT IN (-11,125,117)
LEFT JOIN
BBVODSTATS C
ON A.DMS_ID=C.DMS_ID;
3030176931|2004-11-07-11.48.52.000000|2013-11-03|25167455119|797||15|0|4|0|0|HR44-700
3026464853|2004-11-07-12.40.54.000000|2013-11-03|25166398575|797||17|0|4|0|0|HR44-500
2925917748|2003-12-05-17.26.58.000000|2013-11-03|36816426252|740||0|||||H25-500
这不需要修改值,但如果您需要这样做,那么使用TRIM
而不是单独LTRIM
和RTRIM
调用会更简单,默认情况下是删除空格 - 因此您可以LTRIM(RTRIM(value, ' '), ' ')
代替TRIM(value)
而不是TO_CHAR
。 (但明确不会伤害)。我还省略了对FM
数字值的调用以简化操作,但您可能更愿意明确设置它们 - 在这种情况下,请注意SET
格式修饰符。
您的一些MAXD
命令,NEWP
,TRUNCATE
和COLSEP
,are obsolete以及其他一些命令不再需要了 - {特别是{1}},因为现在输出中只有一列。
如果你真的在输出中得到null
这个词,那么你可以在某个地方SET NULL null
,也许在登录脚本中;也不会出现在这个连接版本中,因为它应用于输出列(同样,只有一个,并且不能为null),而不是单个基础表列。