set termout off
set feedback off
spool t1.sql
select 'column ' || column_name || ' format a' || data_length
from all_tab_cols
where table_name='YOUR_TABLE'
/
spool off
@t1.sql
set pagesize 24
set heading on
spool result.txt
select *
from YOUR_TABLE;
and rownum < 30;
spool off
SET ECHO OFF
SET PAGESIZE 32766
SET LINESIZE 32766
SET NUMW 20
SET VERIFY OFF
SET TERM OFF
SET UNDERLINE OFF
SET MARKUP HTML ON
SET PREFORMAT ON
SET WORD_WRAP ON
SET WRAP ON
SET ENTMAP ON
spool '/tmp/Example.html'
select
(s.ID||' ') AS ID,
(s.ORDER_ID||' ') AS ORDER_ID,
(s.ORDER_NUMBER||' ') AS ORDER_NUMBER,
(s.CONTRACT_ID||' ') AS CONTRACT_ID,
(s.CONTRACT_NUMBER||' ') AS CONTRACT_NUMBER,
(s.CONTRACT_START_DATE||' ') AS CONTRACT_START_DATE,
(s.CONTRACT_END_DATE||' ') AS CONTRACT_END_DATE,
(s.CURRENCY_ISO_CODE||' ') AS CURRENCY_ISO_CODE,
from Example s
order by s.order_number, s.contract_number;
spool off;
SET ECHO OFF
SET TERMOUT OFF
SET FEEDBACK OFF
SET PAGESIZE 32766
SET LINESIZE 32766
SET MARKUP HTML OFF
SET HEADING OFF
spool /tmp/columns_EXAMPLE.sql
select 'column ' || column_name || ' format A32766'
from all_tab_cols
where data_type = 'VARCHAR2' and table_name = 'EXAMPLE'
/
spool off
SET HEADING ON
SET NUMW 40
SET VERIFY OFF
SET TERM OFF
SET UNDERLINE OFF
SET MARKUP HTML ON
SET PREFORMAT ON
SET WORD_WRAP ON
SET WRAP ON
SET ENTMAP ON
@/tmp/columns_EXAMPLE.sql
spool '/tmp/Example.html'
select *
from Example s
order by s.order_number, s.contract_number;
spool off;
SELECT 'COLUMN ' || column_name || ' FORMAT ' ||
CASE
WHEN data_type = 'DATE' THEN
'A9'
WHEN data_type LIKE '%CHAR%' THEN
'A' ||
TRIM(TO_CHAR(LEAST(GREATEST(LENGTH(column_name),
data_length), 40))) ||
CASE
WHEN data_length > 40 THEN
' TRUNC'
ELSE
NULL
END
WHEN data_type = 'NUMBER' THEN
LPAD('0', GREATEST(LENGTH(column_name),
NVL(data_precision, data_length)), '9') ||
DECODE(data_scale, 0, NULL, NULL, NULL, '.' ||
LPAD('0', data_scale, '0'))
WHEN data_type IN ('RAW', 'LONG') THEN
'A1 NOPRINT'
WHEN data_type LIKE '%LOB' THEN
'A1 NOPRINT'
ELSE
'A' || TRIM(TO_CHAR(GREATEST(LENGTH(column_name), data_length)))
END AS format_cols
FROM dba_tab_columns
WHERE owner = 'SYS'
AND table_name = 'DBA_TAB_COLUMNS';
VARIABLE resultXML clob;
SET LONG 100000; -- Set to the maximum size of the XML you want to display (in bytes)
SET PAGESIZE 0;
DECLARE
qryCtx DBMS_XMLGEN.ctxHandle;
BEGIN
qryCtx := dbms_xmlgen.newContext('SELECT * from scott.emp');
-- now get the result
:resultXML := DBMS_XMLGEN.getXML(qryCtx);
--close context
DBMS_XMLGEN.closeContext(qryCtx);
END;
/
print resultXML
/*google "sqlplus OPTION" to get the meaning */
set colsep ' ' --literal TAB; can alter to taste
set HEADING OFF
set UNDERLINE OFF
set PAGESIZE 50000
set LINESIZE 32767
set TERMOUT OFF
set TRIMSPOOL ON
set FEEDBACK OFF
set WRAP OFF
set NEWPAGE none
/*first, write the column names to the file*/
spool "C:\yourPath\output.txt"
select listagg(column_name, chr(9) ) within group (order by column_id)
FROM dba_tab_columns
WHERE owner = 'SomeOwner'
AND table_name = upper('ViewOrTable_Name')
;
/*now append the data*/
spool "C:\yourPath\output.txt" append
select * from SomeOwner.ViewOrTable_Name
where 1 = 1
;
/*stop spooling*/
spool OFF
7条答案
按热度按时间dy2hfwbg1#
您可以尝试动态生成“column x format a20”命令,如下所示:
请注意,此示例仅适用于VARCHAR2。例如,您需要添加decode,以更改为DATE或NUMBER生成的“column”命令。
UPDATE:原来的SQL并没有真正改变SQL*Plus的行为。我唯一能想到的是将字段名重命名为一个字符值A、B、C等,方法如下:
它将生成类似于以下内容的输出:
dwbf0jvd2#
没有一个建议的解决方案可以显示原始的列名,所以我不知道为什么人们会投票支持它们......我确实有一个“技巧”可以满足原始请求,但我真的不喜欢它......那就是实际上在每个列的查询上附加或前缀一个字符串,这样它们总是足够长,可以作为列标题。如果您是在HTML模式下,就像海报上说的那样,有一点额外的白色间隔几乎没有伤害...它当然会放慢你的查询有点...
例如:
当然,您可以编写一个存储过程来做一些更好的事情,但对于这个简单的场景来说,这似乎有点大材小用。
这仍然不能满足最初的海报要求。因为它需要手动列在列上,而不使用select *。但至少当你愿意详细说明字段时,它是一个有效的解决方案。
然而,由于HTML中的字段太长并不存在问题,因此有一个相当简单的方法来修正Chris的解决方案,使其在本例中工作。那就是选择一个oracle允许的最大值。遗憾的是,这仍然不能真正适用于每个表的每个字段,除非您显式地为每个数据类型添加格式。该解决方案也不能适用于连接。因为不同的表可以使用相同的列名但不同的数据类型。
vsaztqbk3#
这应该提供了一些合理的格式。当然,您可以自由地用自己的首选项替换char列的最大宽度,以及如何处理LONG、RAW和LOB列。
iibxawm44#
我不认为sqlplus提供了您所要求的功能。您可以使用某种脚本语言(如Perl或Python)自动格式化。换句话说,查询
ALL_TAB_COLS
视图以获得架构和表,然后使用format列属性动态创建脚本。当然,如果您有查询ALL_TAB_COLS视图(或其他等效视图)的权限。这是我拼凑的一个快速概念验证:
pqwbnv8z5#
如果您不需要或不想使用XML格式,那么这可能有点麻烦,但是您应该能够使用DBMS_XMLGEN包。该脚本应该为您提供一个XML文件,用于任意查询,并将完整的列名作为标记名。
ulmd4ohb6#
我在VoraX中尝试实现这个特性时遇到了同样的问题。在下一个版本中,我考虑了以下解决方案:
不用调整列的大小,只需要用你想要的列名来强制列标题的格式和其他东西。我认为同样的方法也适用于DBA_TAB_COLUMNS解决方案,但是我更喜欢DBMS_SQL,因为它也考虑别名,并且只得到你查询的列。
**EDIT:**只使用“列标题”是不行的,还需要使用“列格式”语句,所以请忽略我之前的回答。
vh0rcniy7#
如果你从一个表或视图中选择所有的列,这将是有效的a a归结为先写列,然后写数据。
下面假设使用制表符分隔。如果您需要逗号或其他分隔符,则需要在两个位置进行更改:colsep和下面的listagg线;逗号分隔符示例:新的COLSEP行将是:
set colsep ','
,新的列表行调整将用chr(44)
替换chr(9)