Svůj kód můžete změnit na:
v_lstmt := 'SELECT count(*) FROM userB.tableB WHERE id = '''||v_ret (i).id||''''
|| ' and ('||v_ret (i).col||' is null or '||v_ret (i).col||' = :val)';
EXECUTE IMMEDIATE v_lstmt INTO cDel using v_ret (i).val;
To zkontroluje, zda je sloupec prázdný nebo odpovídá zadanému val
a používá proměnnou vazby k dodání hodnoty ke kontrole, aby se trochu omezila analýza.
To však stále závisí na implicitní konverzi, takže pokud byste například měli v tabulce hodnotu data, spoléhali byste na to, že ji převedete na nastavení NLS, aby odpovídala typu sloupce cílové tabulky.
Můžete použít all_tab_columns
zobrazení, abyste našli datový typ cílového sloupce a provedli explicitní konverzi val
na tento typ před vázáním. Složitější, ale možná robustnější přístup by bylo použití dbms_sql
pro vnitřní dynamický SQL namísto execute immediate
.
Zdá se však, že vnější dotaz nemusí být dynamický, můžete to udělat:
declare
v_lstmt VARCHAR2(32000);
cDel number;
begin
for rec in (SELECT id, col, val FROM tableA) loop
v_lstmt := 'SELECT count(*) FROM tableB WHERE id = '''||rec.id||''''
|| ' and ('||rec.col||' is null or '||rec.col||' = :val)';
dbms_output.put_line(v_lstmt);
EXECUTE IMMEDIATE v_lstmt INTO cDel using rec.val;
If cDel > 0 Then
--some code
cDel := 0;
end if;
end loop;
end;
/