J'ai un paquet Oracle contenant une fonction. Cette fonction a 3 entrées. J'ai besoin de passer de multiples valeurs à chaque entrée. Je pourrais automatiser un processus qui l'exécute plusieurs fois avec chaque combinaison de variables, mais je voudrais uniquement faire un appel à la base de données.
Code simplifié p>
declare ln_ret number; begin ln_ret := dbo.pkg_rpa.mis_run_script ( '%2020%', '111','222','333','444', '1234','2345','6192','1204' ); dbms_output.put_line('ln_ret=' || t.t (ln_ret)); end; CREATE OR REPLACE package dbo.pkg_rpa IS function mis_run_script ( p_input_dt in varchar2, p_hospital_id in varchar2, p_procedure_code in varchar2) RETURN number; end PKG_RPA; / CREATE OR REPLACE PACKAGE BODY dbo.pkg_rpa IS function mis_run_claim_assessment_script ( p_input_dt in varchar2, p_hospital_id in varchar2, p_procedure_code in varchar2 ) Begin for i in (select table_name from user_tables where lower(table_name) = 'temp_rpa') loop execute immediate 'drop table temp_rpa'; end loop; execute immediate ' create table temp_rpa as select distinct ci.claim_id, count(ci.receipt_id) as count_receipts, sum(ci.billed_amount) as total_billed_amount, count(*) as claim_items from claim_item ci left join claim_header ch on ch.claim_id = ci.claim_id left join cd_hos ho on ho.hospital_id = ci.hospital_id left join claim_type_header cl on cl.claim_id = ci.claim_id where cl.claim_status is null and ch.deleted_flag is null and ch.input_dt like p_input_dt and ci.hospital_id in (p_hospital_id) and (ci.claim_id, NVL(ci.claim_item_id,0)) in (select claim_id, NVL(claim_item_id,0) from cd_roc_claim_item where procedure_code in (p_procedure_code)) and (ci.claim_id, NVL(ci.claim_item_id,0)) not in (select claim_id, NVL(claim_item_id,0) from cd_roc_claim_item where procedure_code not in (p_procedure_code)) group by ci.claim_id having sum(case when ci.service_type_id is null then 1 end) = 1)'; End; end mis_run_script; end PKG_RPA; /
4 Réponses :
Ce que vous pouvez faire est d'utiliser un tableau associatif comme type d'entrée. Au lieu de Varchar2, utilisez dbms_sql.varcharsa2a comme type de date pour les 2e et 3ème arguments.
Mais si les arguments sont liés les uns aux autres, disons p>
Je pense que vous souhaitez créer un type d'enregistrement personnalisé, créez un type de table du type d'enregistrement et utilisez-le comme paramètre. p>
Vos arguments deviennent dans votre code, vous devriez en faire la boucle et au lieu de laisser tomber la table et de le recréer à chaque fois, vous le laissez tomber une fois. Au début et ajoutez des données dans la boucle; p> p_hospital_ids dans dbms_sql .varcha2a code> dans la spécification de l'emballage et le corps de l'emballage. P>
J'ai essayé de changer le type de données dans les entrées et dans le corps, mais d'obtenir [1]: ORA-24344: succès avec une erreur de compilation
transmettez-le avec chaîne cité ( Q '
begin
ln_ret := dbo.pkg_rpa.mis_run_script (
'%2020%',
Q'#'111','222','333','444'#',
Q'#'1234','2345','6192','1204'#'
);
dbms_output.put_line('ln_ret=' || t.t (ln_ret));
end;
Pouvez-vous modifier le numéro de déclaration Ln_ret; Commencez ln_ret: = dbo.pkg_rpa.mis_run_script ('% 2020%', '111', '222', '333', '444', '1234', '2345', '6192', '1204', '1204'); dbms_output.put_line ('ln_ret =' || t.t (ln_ret)); finir;
Vous voudrez peut-être vous référer à l'exemple ci-dessous qui est extrait de Site web Oracle . J'espère que cela aide.
CREATE OR REPLACE TYPE nt_type IS TABLE OF NUMBER; / CREATE OR REPLACE PROCEDURE print_nt (nt nt_type) AUTHID DEFINER IS i NUMBER; BEGIN i := nt.FIRST; IF i IS NULL THEN DBMS_OUTPUT.PUT_LINE('nt is empty'); ELSE WHILE i IS NOT NULL LOOP DBMS_OUTPUT.PUT('nt.(' || i || ') = '); DBMS_OUTPUT.PUT_LINE(NVL(TO_CHAR(nt(i)), 'NULL')); i := nt.NEXT(i); END LOOP; END IF; DBMS_OUTPUT.PUT_LINE('---'); END print_nt; / DECLARE nt nt_type := nt_type(); -- nested table variable initialized to empty BEGIN print_nt(nt); nt := nt_type(90, 9, 29, 58); print_nt(nt); END; /
Vous n'avez pas besoin de SQL dynamique du tout.
CREATE OR REPLACE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER; CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF VARCHAR2(1000); function mis_run_claim_assessment_script ( p_input_dt in varchar2, p_hospital_id in NUMBER_TABLE_TYPE, -- why on earth do you put numbers as strings? p_procedure_code in VARCHAR_TABLE_TYPE ) RETURN ??? AS INSERT INTO temp_rpa (...) SELECT ... FROM ... WHERE ch.input_dt like p_input_dt AND ci.hospital_id MEMBER OF p_hospital_id AND procedure_code MEMBER OF p_procedure_code ; RETURN ??? END; ln_ret := mis_run_claim_assessment_script( '%2020%', NUMBER_TABLE_TYPE(111, 222, 333, 444), VARCHAR_TABLE_TYPE('not','clear','in','your','question') );
Comme il se trouve, on dirait que si vous appelez cette fonction plusieurs fois en série, il tombera et recréez
TEMP_RPA CODE>. Vous devez sûrement faire quelque chose d'autre entre les créations de cette table? (Ou peut-être qu'il n'y a aucune raison de créer la table du tout? Votre fonction est déclarée comme retourner
numéro code> mais il n'y a pas de
retour code> instruction.)
Habituellement, il s'agit d'une mauvaise conception de déposer et de créer une table de manière dynamique dans une procédure PL / SQL. Mieux vaut utiliser un
Table temporaire global Code>.
@Davecosta Je travaille avec RPA, je peux extraire des résultats entre chaque course et combiner de mon côté. Toutes mes excuses supprimées là-bas (simplifié le véritable paquet)
Si ces paramètres ne sont utilisés que dans les clauses code> dans code>, vous pouvez utiliser des chaînes citées telles que `Q '[' 111 ',' 222 ',' 333 ',' 444 ']'`. Court Demo .
@Pondersttibbbons Voulez-vous poster cela comme une réponse? Par beau et vous avez donné une meilleure explication du début