8

デフォルトでは、sqlplus は列名を基になるデータ型の長さに切り捨てます。私たちのデータベースの列名の多くは、テーブル名の前に付いているため、切り詰めると同じように見えます。

ロックダウンされた本番環境で select * クエリをリモート DBA に指定し、スプールされた結果を診断のためにドラッグする必要があります。個々の列の書式設定を指定するには、列が多すぎます。sqlplus は、列名の切り捨てを均一に無効にするオプションを提供していますか?

(省略されていない出力が得られる限り、他のモダリティ、csvなどを使用できますが、SET MARKUP HTML ONを使用しています。)

4

6 に答える 6

3

試すことができることの 1 つは、「column x format a20」コマンドを動的に生成することです。次のようなもの:

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

このサンプルは VARCHAR2 でのみ機能することに注意してください。たとえば、DATE または NUMBER に対して生成された「列」コマンドを変更するには、デコードを追加する必要があります。

更新: 元の SQL は実際には SQL*Plus の動作を変更していないことがわかりました。私が考えることができる唯一のことは、次の方法で、フィールド名を1文字の値A、B、Cなどに名前変更することです。

select 'column ' || column_name ||
       ' heading "' ||
       chr(ascii('A') - 1 + column_id) ||
       '"'
from all_tab_cols
where table_name='YOUR_TAB_NAME'

次のような出力が生成されます。

column DEPT_NO heading "A"
column NAME heading "B"
column SUPERVIS_ID heading "C"
column ADD_DATE heading "D"
column REPORT_TYPE heading "E"
于 2008-12-09T22:56:52.560 に答える
1

sqlplus があなたが要求している機能を提供しているとは思いません。Perl や Python などのスクリプト言語を使用して、書式設定を自動化できる場合があります。ALL_TAB_COLSつまり、スキーマとテーブルのビューをクエリしてから、フォーマット列属性を使用してスクリプトを動的に作成します。もちろん、これは ALL_TAB_COLS ビュー (または他の同等のもの) を照会する権限がある場合にのみ機能します。

これは、私がまとめた簡単な概念実証です。

#!/usr/bin/python

import sys
import cx_Oracle

response=raw_input("Enter schema.table_name:  ")
(schema, table) = response.split('.')
schema = schema.upper()
table = table.upper()
sqlstr = """select column_name,
                   data_type,
                   data_length
              from all_tab_cols
             where owner      = '%s'
               and table_name = '%s'""" % ( schema, table )

## open a connection to databases...
try:
    oracle = cx_Oracle.Connection( oracleLogin )
    oracle_cursor = oracle.cursor()

except cx_Oracle.DatabaseError, exc:
    print "Cannot connect to Oracle database as", oracleLogin
    print "Oracle Error %d:  %s" % ( exc.args[0].code, exc.args[0].message )
    sys.exit(1)

try:
    oracle_cursor.execute( sqlstr )

    # fetch resultset from cursor
    for column_name, data_type, data_length in oracle_cursor.fetchmany(256):
        data_length = data_length + 0
        if data_length < len(column_name):
            if data_type == "CHAR" or data_type == "VARCHAR2":
                print "column %s format a%d" % ( column_name.upper(), len(column_name) )
            else:
                print "-- Handle %s, %s, %d" % (column_name, data_type, data_length)

except cx_Oracle.DatabaseError, e:
    print "[Oracle Error %d: %s]:  %s" % (e.args[0].code, e.args[0].message, sqlstr)
    sys.exit(1)

try:
    oracle_cursor.close()
    oracle.close()
except cx_Oracle.DatabaseError, exc:
    print "Warning: Oracle Error %d:  %s" % ( exc.args[0].code, exc.args[0].message )

print "select *"
print "from %s.%s" % ( schema, table )
于 2008-12-09T16:18:17.717 に答える
1

XML フォーマットを必要としない、または必要としない場合は、ちょっと面倒ですが、 DBMS_XMLGEN パッケージを使用できるはずです。このスクリプトは、タグ名として完全な列名を持つ任意のクエリの XML ファイルを提供する必要があります。

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
于 2011-04-19T21:02:26.980 に答える
0

この機能をVoraXに実装しようとすると、同じ問題が発生しました。次のバージョンでは、次の解決策を念頭に置いています。

set feedback off 
set serveroutput on
declare
  l_c number;
  l_col_cnt number;
  l_rec_tab DBMS_SQL.DESC_TAB2;
  l_col_metadata DBMS_SQL.DESC_REC2;
  l_col_num number;
begin
  l_c := dbms_sql.open_cursor;
  dbms_sql.parse(l_c, '<YOUR QUERY HERE>', DBMS_SQL.NATIVE);
  DBMS_SQL.DESCRIBE_COLUMNS2(l_c, l_col_cnt, l_rec_tab);
  for colidx in l_rec_tab.first .. l_rec_tab.last loop
    l_col_metadata := l_rec_tab(colidx);
    dbms_output.put_line('column ' || l_col_metadata.col_name || ' heading ' || l_col_metadata.col_name);
  end loop;
  DBMS_SQL.CLOSE_CURSOR(l_c);
end;

列のサイズ、書式設定などを微調整する代わりに、必要な列名で列見出しを強制するだけです。同じアプローチが DBA_TAB_COLUMNS ソリューションでも機能すると思いますが、エイリアスも考慮され、クエリした列のみを取得するため、DBMS_SQL の方が好みです。

編集:「列見出し」だけを使用しても機能しません。「列フォーマット」ステートメントを使用する必要があります。だから、私の前の答えを無視してください。

于 2011-05-18T09:23:59.523 に答える