Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Suche nach NULL-Werten für verschiedene Oracle-Typen

Sie können Ihren Code folgendermaßen ändern:

   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;

Das prüft, ob die Spalte null oder ist stimmt mit dem angegebenen val überein , und verwendet eine Bind-Variable, um den zu prüfenden Wert bereitzustellen, um das Parsen ein wenig zu reduzieren.

Dies ist jedoch immer noch auf implizite Konvertierung angewiesen. Wenn Sie also beispielsweise einen Datumswert in der Tabelle hätten, würden Sie sich auf Ihre NLS-Einstellungen verlassen, um ihn so zu konvertieren, dass er mit dem Spaltentyp der Zieltabelle übereinstimmt.

Sie können die all_tab_columns verwenden view, um den Datentyp der Zielspalte zu finden und eine explizite Konvertierung von val durchzuführen zu diesem Typ vor dem Binden. Ein komplizierterer, aber möglicherweise robusterer Ansatz wäre die Verwendung von dbms_sql für das innere dynamische SQL statt execute immediate .

Die äußere Abfrage scheint jedoch nicht dynamisch sein zu müssen, Sie könnten Folgendes tun:

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;
/