概述我的任务是将Oracle数据库中的数据提取作为管道分隔的输出文本文件提供。我将使用SQLPlus在数据所在的服务器上执行此操作。通常,这项任务并不是我的经验,但这次,业务需要列标题存在。
考虑我需要输出的以下五列:
SELECT
a.USER_NAME || '|'
|| a.LAST_NAME || '|'
|| a.FIRST_NAME || '|'
|| b.PRODUCT_PURCHASED || '|'
|| c.DATEPURCHASED
FROM ...
WHERE ... ;
此SQL工作正常,输出如下:
omnusruthius|ruthius|omnus|stackoverflow_prod|19-APR-16
但是,企业希望它看起来像:
USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE
omnusruthius|ruthius|omnus|stackoverflow_prod|19-APR-16
问题:所以这里的目标主要是输出带有自定义列标题(别名)的第一行,如上所示。所以我的第一个方法是尝试类似的东西:
SELECT
a.USER_NAME AS USER_NM || '|'
|| a.LAST_NAME AS LAST || '|'
|| a.FIRST_NAME AS FIRST || '|'
|| b.PRODUCT_PURCHASED AS PROD || '|'
|| c.DATEPURCHASED AS EFFECTIVE_DATE
FROM ...
WHERE ...
不幸的是,我收到了:
ORA-00923:未找到FROM关键字
我不确定这会有什么帮助,因为没有别名的原始SQL输出无论如何都不会在第一行显示列标题。请记住,这是通过命令行(SQLPlus),而不是Toad或其他一些RDMS。
然后我尝试了:
SELECT
'USER_NM', 'LAST', 'FIRST', 'PROD', 'EFFECTIVE_DATE' FROM DUAL
UNION ALL
SELECT
a.USER_NAME || '|'
|| a.LAST_NAME || '|'
|| a.FIRST_NAME || '|'
|| b.PRODUCT_PURCHASED || '|'
|| c.DATEPURCHASED
FROM ...
WHERE ...
出现以下错误:
ORA-01789:查询块的结果列数不正确
我觉得这个解决方案非常接近,我在这里错过了什么?任何帮助将不胜感激!
编辑:只是给未来读者的一个注释,这里的两个答案都可以帮助您解决这个问题,但经过进一步的调整,我发现我们都在过度思考解决方案。我不打算提出新的解决方案,因为改变是微不足道的,但请考虑采取以下措施:
SELECT 'USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE' FROM DUAL;
SELECT a.USER_NAME AS USER_NM || '|'
|| a.LAST_NAME AS LAST || '|'
|| a.FIRST_NAME AS FIRST || '|'
|| b.PRODUCT_PURCHASED AS PROD || '|'
|| c.DATEPURCHASED AS EFFECTIVE_DATE
FROM ...
WHERE ...
ORDER BY ... ;
这里的关键是在SQL * Plus中使用分号。第一个SELECT语句完全独立于第二个;不需要UNION,因为第一个查询的输出会在第二个查询的输出之前立即自动显示。两者都可以有自己的规则,如果后一个查询要复杂得多,这一点尤其方便。我可以确认上述查询是否有效,我很惊讶我花了很长时间才实现这一目标...
答案 0 :(得分:3)
连接时请确保标头是单个字符串。因为您将列中的值连接在一行上。
如果使用逗号分隔,正如您在问题中所做的那样,结果块也应该有5列,但情况并非如此。
SELECT
'USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE' FROM DUAL
UNION ALL
SELECT
a.USER_NAME || '|'
|| a.LAST_NAME || '|'
|| a.FIRST_NAME || '|'
|| b.PRODUCT_PURCHASED || '|'
|| c.DATEPURCHASED
FROM ...
WHERE ...
编辑:列也可以排序。
SELECT 'USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE' FROM DUAL
UNION ALL
SELECT * FROM (
SELECT
a.USER_NAME || '|'
|| a.LAST_NAME || '|'
|| a.FIRST_NAME || '|'
|| b.PRODUCT_PURCHASED || '|'
|| c.DATEPURCHASED
FROM ...
WHERE ...
ORDER BY DATEPURCHASED) --add any other columns needed
答案 1 :(得分:1)
由于您使用SQL * Plus标记了问题,因此您可以使用the PROMPT command生成标题,这样可以避免使用联合对结果进行排序的并发症:
PROMPT USER_NM|LAST|FIRST|PROD|EFFECTIVE_DATE
SELECT
a.USER_NAME AS USER_NM || '|'
|| a.LAST_NAME AS LAST || '|'
|| a.FIRST_NAME AS FIRST || '|'
|| b.PRODUCT_PURCHASED AS PROD || '|'
|| c.DATEPURCHASED AS EFFECTIVE_DATE
FROM ...
WHERE ...
ORDER BY ...
将标题从SQL中移出并进入客户端领域,它可以说属于它。这也适用于SQL Developer,其他客户端也可以做类似的事情。如果您从另一个客户端或JDBC或其他任何方面运行查询,它将无法工作;但是无论运行什么,查询都可以(也许应该)在这种情况下提供标题。
如果您还没有,您还可以考虑执行SET HEADING OFF
或SET PAGESIZE 0
来抑制查询本身的列标题(尽管您已经说过你已经做过的事情了那);可能SET EMBED OFF
,但我不认为除非你单独进行查询以生成标题行,否则需要这样做。