[PL/SQL] [ORACLE] Problème champs = NULL

Fermé
p3kk4 - 21 mars 2007 à 10:25
 ftao - 25 oct. 2007 à 11:04
Bonjour,

Je developpe sur Oracle 10.1
Je voudrais supprimer des lignes dans une tables dont certains champs peuvent être NULL.

EX :
DELETE T_NOTIFICATION
   WHERE  DOMAIN_SEQ=p_domain_seq
  AND DATASET_SEQ = p_dataset_seq
   AND COUNTRY_SEQ = p_country_seq


Les paramètres (p_...) peuvent être NULL ou pas, si ils le sont il faut les tester. Malheureusement, le test pour la valeur NULL doit être monchps IS NULL et ca ne va pas si il y a une valeur....

Avez vous une solution?

J'en ai trouvée une mais qui est "sale":
   DELETE (SELECT NVL(DOMAIN_SEQ,0) DOMAIN_SEQ
   		  		  ,NVL(COUNTRY_SEQ,0) COUNTRY_SEQ
				  ,NVL(DATASET_SEQ,0) DATASET_SEQ
				   FROM  T_NOTIFICATION) N
   WHERE  DOMAIN_SEQ= NVL(p_domain_seq,0)
  AND (DATASET_SEQ = NVL(p_dataset_seq, 0))
   AND (COUNTRY_SEQ = NVL(p_country_seq, 0))


Cette solution consite à remplacer les valeurs NULL par 0 dans les données à tester et dans le paramètres.

1 réponse

Si c'est en pl,
pourquoi ne pas tester lors de la construction dynamique de ta requete?

Voici un exemple:

--Retrieval of alarm data
if (0 = getAlarmOrEvent) then
l_alarmorevent_name := 'alarm';
l_alarmorevent_fields := 'al.ae_alarm_key,alarm_date, al.is_set, al.alarm_message, al.ae_alarm_type_key, al.equipment_key, al.module_key, al.recipe_key, al.ae_process_key, al.ae_auxiliary_key';
End If;
--Retrieval of event data
if (1 = getAlarmOrEvent) then
l_alarmorevent_name := 'event';
--Conditional concaténation of fields list
l_alarmorevent_fields := 'al.ae_event_key, al.event_date, NULL, NULL, al.ae_event_type_key, al.equipment_key, al.module_key, al.recipe_key, al.ae_process_key, al.ae_auxiliary_key';
End if;
--Test of module value

-- Dynamic query construction
l_query := l_query || ' SELECT '||l_alarmorevent_fields;
l_query := l_query || ' FROM ae_'||l_alarmorevent_name||' al';
l_query := l_query || ' WHERE al.equipment_key = :1 ' ;
l_query := l_query || ' AND al.'||l_alarmorevent_name||'_date BETWEEN TO_DATE(:2,''YYYYMMDDHH24MISS'') AND TO_DATE(:3,''YYYYMMDDHH24MISS'') ';
if (p_ae_module is null) then
dbms_output.put_line('FSM_EQUIP_TRANGE p_ae_module est null:'||p_ae_module);
l_query := l_query || ' AND al.module_key IS NULL ' ;
if (p_ae_AlarmOrEventTypeKey is not null) then
l_query := l_query || ' AND al.ae_'||l_alarmorevent_name||'_type_key = :4 ';
end if;
else
l_query := l_query || ' AND al.module_key = :4 ' ;
if (p_ae_AlarmOrEventTypeKey is not null) then
l_query := l_query || ' AND al.ae_'||l_alarmorevent_name||'_type_key = :5 ';
end if;
end if;


If ( DEBUG_MODE ) Then
dbms_output.put_line('Query : '||l_query);
End If;


-- Returns indicator value regarding the given keys in list parameters
if (p_ae_module is null) then
if (p_ae_AlarmOrEventTypeKey is not null) then
OPEN v_cur FOR l_query USING p_ae_equipment, p_ae_starttime, p_ae_stoptime, p_ae_AlarmOrEventTypeKey ;
else
OPEN v_cur FOR l_query USING p_ae_equipment, p_ae_starttime, p_ae_stoptime ;
end if;
else
if (p_ae_AlarmOrEventTypeKey is not null) then
OPEN v_cur FOR l_query USING p_ae_equipment, p_ae_starttime, p_ae_stoptime, p_ae_module, p_ae_AlarmOrEventTypeKey ;
else
OPEN v_cur FOR l_query USING p_ae_equipment, p_ae_starttime, p_ae_stoptime, p_ae_module ;
end if;

--OPEN v_cur FOR l_query USING p_ae_equipment, p_ae_starttime, p_ae_stoptime, p_ae_module, p_ae_AlarmOrEventTypeKey;
end if;
LOOP
FETCH v_cur into rec_ALARM;
exit when v_cur%NOTFOUND;
pipe row(rec_ALARM);
END LOOP;

CLOSE v_cur;
-- Returns the created data table type
return;

Bon, dans le cas ou tes parametres sont stockés dans une autre table, j'avoue avoir utilisé ta solution:
l_query_lst := l_query_lst || ' AND nvl(al.module_key,0) = nvl(LOV_Tab.p_module_NumValue,0)';

Bonne journee

Ftao
0