17

PROC SQLを使用して、何億ものレコードを含むDB2テーブルをクエリしようとしています。開発段階では、これらのレコードの任意の小さなサブセット(たとえば、1000)に対してクエリを実行したいと思います。INOBSを使用して観測を制限しようとしましたが、このパラメーターは、SASが処理しているレコードの数を制限しているだけだと思います。SASがデータベースから任意の数のレコードのみをフェッチする(そしてそれらすべてを処理する)ようにしたい。

自分でSQLクエリを作成する場合は、単純に( SQL ServerSELECT * FROM x FETCH FIRST 1000 ROWS ONLY ...と同等)を使用します。SELECT TOP 1000 * FROM xしかし、PROCSQLにはこのようなオプションはないようです。レコードの取得には非常に長い時間がかかります。

質問:データベースから返すレコードの数を任意に制限するようにSASに指示するにはどうすればよいですか。

PROCSQLがANSISQLを使用していることを読みましたが、これには行制限キーワードの指定がありません。おそらく、SASはSQL構文をベンダー固有のキーワードに変換する努力をしたいとは思わなかったのでしょうか。回避策はありませんか?

4

2 に答える 2

30

outobsでオプションを使用してみましたproc sqlか?

例えば、

proc sql outobs=10; create table test
    as
    select * from schema.HUGE_TABLE
    order by n;
quit;

または、SQLパススルーを使用してDB2構文()を使用してクエリを作成することもできますがFETCH FIRST 10 ROWS ONLY、これには、少なくとも一時的にすべてのデータをデータベースに保存する必要があります。

パススルーは次のようになります。

proc sql;
    connect to db2 (user=&userid. password=&userpw.  database=MY_DB);

    create table test as
    select * from connection to db2 (
        select * from schema.HUGE_TABLE
        order by n
        FETCH FIRST 10 ROWS ONLY
    );
quit;

より多くの構文が必要であり、sasデータセットにアクセスできないため、outobsうまくいく場合は、それをお勧めします。

于 2012-07-31T19:12:10.937 に答える
8

SASがSAS構文を介してデータベースと通信している場合、クエリの一部を同等のDBMS言語に変換できます。これは暗黙的なパススルーと呼ばれます。クエリの残りの部分は、SASによって「後処理」され、最終結果が生成されます。SASのバージョン、DBMSベンダー、DBMSのバージョン、場合によっては接続/ libnameオプションに応じて、SAS構文のさまざまな部分がSASとDBMSの間で翻訳可能/互換性があると見なされるため、SASではなくDBMSによって実行されるように送信されます。

SAS SQLオプション(INOBSとOUTOBS)を使用して、さまざまなバージョンのSASを介してMS SQLとOracleで多くの作業を行いましたが、TOP xxxタイプのクエリに変換されたものを見たことがないため、これはおそらくまだサポートされていません。ただし、クエリがDMBSデータのみにアクセスする場合(SASデータへの結合などはありません)、かなり実行可能である必要があります。

したがって、データベースに接続するための、いわゆる明示的なパススルー(特定のSAS SQL構文)が残っていると思います。このタイプのクエリは次のようになります。

proc sql;
    connect to oracle as db1 (user=user1 pw=pasw1 path=DB1);
    create table test_table as
    select *
    from connection to db1
        ( /* here we're in oracle */
                  select * from test.table1 where rownum <20 
                )
    ;
    disconnect from db1;
quit;

SAS 9.3では、構文を簡略化できます。すでにLIBNAME接続が存在する場合は、明示的なパススルーに再利用できます。

LIBNAME ORALIB ORACLE user=...;

PROC SQL;
connect to oracle using ORALIB;
create table work.test_table as
        select *
        from connection to ORALIB (
....

libnameを使用して接続する場合は、データベースをロードするときに必ずREADBUFF(通常は5000程度を設定します)またはINSERTBUFFオプション(1000以上)を使用してください。

暗黙のパススルーが行われるかどうかを確認するには、sastraceオプションを設定します。

option sastrace=',,,ds' sastraceloc=saslog nostsuffix;
于 2012-07-31T19:46:03.493 に答える