J'essaie d'utiliser PROC SQL pour interroger une table DB2 avec des centaines de millions d'enregistrements. Pendant la phase de développement, je souhaite exécuter ma requête sur un sous-ensemble arbitrairement petit de ces enregistrements (disons, 1000). J'ai essayé d'utiliser INOBS pour limiter les observations, mais je crois que ce paramètre limite simplement le nombre d'enregistrements que SAS est en cours de traitement. Je veux SAS pour extraire uniquement un nombre arbitraire d'enregistrements de la base de données (puis les traiter tous).
Si j'écrivais moi-même une requête SQL, j'utiliserais simplement SELECT * FROM x FETCH FIRST 1000 ROWS ONLY ...
(l'équivalent de SELECT TOP 1000 * FROM x
dans SQL Server). Mais PROC SQL ne semble pas avoir une telle option. Il faut un temps extrêmement long pour récupérer les enregistrements.
La question: Comment puis-je demander à SAS de limiter arbitrairement le nombre d'enregistrements à retour de la base de données.
J'ai lu que PROC SQL utilise ANSI SQL, qui n'a pas de spécification pour un mot clé de limitation de ligne. Peut-être que SAS n'avait pas envie de faire l'effort de traduire sa syntaxe SQL en mots clés spécifiques au fournisseur? N'y a-t-il pas de solution?
Lorsque SAS parle à une base de données via la syntaxe SAS, une partie de la requête peut être traduite en équivalent de langage SGBD - c'est ce qu'on appelle un transfert implicite. Le reste de la requête est "post-traitée" par SAS pour produire le résultat final. Selon SAS, fournisseur de SGBD et version de SGBD, et dans certains cas, même certaines options de connexion/libname, différentes parties de la syntaxe SAS sont traduisibles/considérées comme compatibles entre SAS et DBMS et sont donc envoyées pour être exécutées par DBMS au lieu de SAS).
Avec SAS Options SQL - INOBS et OUTOBS - j'ai beaucoup travaillé avec MS SQL et Oracle via différentes versions de SAS, mais je n'ai jamais vu celles-ci jamais traduites en TOP xxx type de requêtes , donc ce n'est probablement pas encore pris en charge, bien que lorsque la requête ne touche que les données DMBS (aucune jointure à SAS, etc.), cela devrait être tout à fait faisable.
Je pense donc que vous vous retrouvez avec la soi-disant explicite pass-through - spécifique SAS syntaxe SQL pour se connecter à la base de données. Ce type de requêtes ressemble à ceci:
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;
Dans SAS 9.3 la syntaxe peut être simplifiée - s'il existe déjà une connexion LIBNAME, vous pouvez la réutiliser pour une transmission explicite:
LIBNAME ORALIB Oracle user=...;
PROC SQL;
connect to Oracle using ORALIB;
create table work.test_table as
select *
from connection to ORALIB (
....
Lors de la connexion à l'aide de libname, assurez-vous d'utiliser les options READBUFF (j'ai généralement défini environ 5000) ou INSERTBUFF (1000 ou plus) lors du chargement de la base de données.
Pour voir si une transmission implicite a lieu, définissez l'option sastrace:
option sastrace=',,,ds' sastraceloc=saslog nostsuffix;
Avez-vous essayé d'utiliser l'option outobs
dans votre proc sql
?
Par exemple,
proc sql outobs=10; create table test
as
select * from schema.HUGE_TABLE
order by n;
quit;
Vous pouvez également utiliser le passthrough SQL pour écrire une requête à l'aide de la syntaxe DB2 (FETCH FIRST 10 ROWS ONLY
), bien que cela vous oblige à stocker toutes vos données dans la base de données, au moins temporairement.
Passthrough ressemble à ceci:
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;
Il nécessite plus de syntaxe et ne peut pas accéder à vos ensembles de données sas, donc si outobs
fonctionne pour vous, je le recommanderais.