2010-07-02 5 views
1

Lorsque j'ai exécuté les requêtes ci-dessous, il échoue dans la deuxième requête car la variable prev_test_ref1 n'est pas définie. Si je supprime l'instruction d'insertion dans la première requête, exécutez à nouveau, puis cela fonctionne et en utilisant la valeur prev_test_ref1 de la première requête SQL dans la deuxième requête. Est-ce à cause de la portée variable? Comment puis-je résoudre ceci avec l'instruction d'insertion.En ce qui concerne la substitution sql

QUERY1

column prev_test_ref1 new_value prev_test_ref1 ; 

insert into testing.test_ref_details(TEST_TYPE,TEST_REF_NO) 
select '1',max(test_ref_no) as prev_test_ref1 
from testing.test_runs_status 
where test_type = 1 
and run_status = 1 
and test_end_dt = (select last_day(add_months(trunc(sysdate),-6))+2 from dual) 
group by test_end_dt 
; 

QUERY2

column last_test_end_dt new_value last_test_end_dt; 

select to_char(test_completion_dt,'DD-MON-YYYY HH24:MI:SS') as last_test_end_dt 
from testing.test_runs_status 
where test_ref_no = '&prev_test_ref1'; 
+0

juste remarqué que votre deuxième requête a "&" (où test_ref_no = '& prev_test_ref1';) - Je ne suis pas sûr de ce que cela fait? – VoodooChild

Répondre

1

Dans SQL plus variables de substitution ne seront définis avec les commandes SELECT. Votre premier insert ne retourne pas les lignes il ne fonctionnera pas (y penser: il ne retourne que 1 row inserted., SQL plus n'a aucun moyen de connaître la valeur insérée.)

Je vous suggère d'ajouter une étape pour sauver la valeur dans la variable (ou utiliser un bloc PL/SQL):

column prev_test_ref1 new_value prev_test_ref1 ; 

SELECT MAX(test_ref_no) AS prev_test_ref1 
    FROM testing.test_runs_status 
WHERE test_type = 1 
    AND run_status = 1 
    AND test_end_dt = (SELECT last_day(add_months(trunc(SYSDATE), -6)) + 2 
         FROM dual) 
GROUP BY test_end_dt; 

INSERT INTO testing.test_ref_details(TEST_TYPE,TEST_REF_NO) 
    VALUES ('1', &prev_test_ref1); 

SELECT ... 
+0

Ceci est un exemple de sélection qui renvoie 1 ligne par groupe. Mais j'ai une requête SQL similaire qui renvoie plusieurs lignes. Dans ce cas, je ne peux pas avoir une instruction d'insertion séparée. Existe-t-il d'autres alternatives ou besoin d'utiliser des scripts PL/SQL. Dans le cas où c'est un script PL/SQL comment je dois changer celui-ci pour fonctionner. – Arav

+0

@Arav: le paramètre 'COLUMN ... NEW_VALUE ... 'synthax ne sauvegarde la valeur ** last ** que si la sélection renvoie plus d'une ligne. Je vous suggère d'utiliser PL/SQL si vos exigences sont plus complexes (pour que vous puissiez utiliser des boucles de curseur par exemple) –

+0

Merci beaucoup pour l'info – Arav

0
declare 
prev_test_ref1 number(10); 
begin 
    insert into ...select ...; 
    select ... into prev_test_ref1 from ...; 
end; 
/
+0

merci beaucoup pour l'info – Arav

0

L'instruction INSERT a une clause RETURNING. Nous pouvons l'utiliser pour avoir accès aux valeurs "inconnues" de la table. Les exemples ci-dessous utilise REVIENNENT pour obtenir le nextval affecté d'une séquence, mais nous pourrions retourner une colonne de la ligne:

SQL> var prev_id number 
SQL> insert into t23 (id, name) values (my_seq.nextval, 'MAISIE') 
    2 returning id into :prev_id 
    3/

1 row created. 

SQL> select * from t23 
    2 where id = :prev_id 
    3/

NAME    ID 
---------- ---------- 
MAISIE   122 

SQL> 

Malheureusement, la clause RETURNING ne fonctionne qu'avec une seule ligne SQL.

0

Il n'est pas vraiment clair quel est le but de l'ensemble du script, en particulier à la lumière du commentaire "J'ai une requête sql similaire qui renvoie plusieurs lignes.Au cas, je ne peux pas avoir une instruction d'insertion séparée."

Si vous souhaitez utiliser les résultats d'une sélection, voir si Multi-Table Inserts correspond à la facture. Votre instruction select peut être insérée dans la table primaire et également dans une seconde table (par exemple, une table temporaire globale). Vous pouvez ensuite interroger la table temporaire globale pour voir quelles lignes ont été insérées.