- он завершен - нет ошибки
SET SERVEROUTPUT ON SIZE 100000
DECLARE
v_match_count INTEGER;
v_counter INTEGER;
v_owner VARCHAR2 (255) := 'VASOA';
v_search_string VARCHAR2 (4000) := '99999';
v_data_type VARCHAR2 (255) := 'CHAR';
v_sql CLOB := '';
BEGIN
FOR cur_tables
IN ( SELECT owner, table_name
FROM all_tables
WHERE owner = v_owner
AND table_name IN (SELECT table_name
FROM all_tab_columns
WHERE owner = all_tables.owner
AND data_type LIKE
'%'
|| UPPER (v_data_type)
|| '%')
ORDER BY table_name)
LOOP
v_counter := 0;
v_sql := '';
FOR cur_columns
IN (SELECT column_name, table_name
FROM all_tab_columns
WHERE owner = v_owner
AND table_name = cur_tables.table_name
AND data_type LIKE '%' || UPPER (v_data_type) || '%')
LOOP
IF v_counter > 0
THEN
v_sql := v_sql || ' or ';
END IF;
IF cur_columns.column_name is not null
THEN
v_sql :=
v_sql
|| 'upper('
|| cur_columns.column_name
|| ') ='''
|| UPPER (v_search_string)||'''';
v_counter := v_counter + 1;
END IF;
END LOOP;
IF v_sql is null
THEN
v_sql :=
'select count(*) from '
|| v_owner
|| '.'
|| cur_tables.table_name;
END IF;
IF v_sql is not null
THEN
v_sql :=
'select count(*) from '
|| v_owner
|| '.'
|| cur_tables.table_name
|| ' where '
|| v_sql;
END IF;
--v_sql := 'select count(*) from ' ||v_owner||'.'|| cur_tables.table_name ||' where '|| v_sql;
--dbms_output.put_line(v_sql);
--DBMS_OUTPUT.put_line (v_sql);
EXECUTE IMMEDIATE v_sql INTO v_match_count;
IF v_match_count > 0
THEN
DBMS_OUTPUT.put_line (v_sql);
dbms_output.put_line('Match in ' || cur_tables.owner || ': ' || cur_tables.table_name || ' - ' || v_match_count || ' records');
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (
'Error when executing the following: '
|| DBMS_LOB.SUBSTR (v_sql, 32600));
END;
/
Я никогда не использовал это на практике, но вы можете себе представить, как использовать это для безопасности типов. Рассмотрим следующий метод:
<T> void method(T... items) {
List<T> list = new ArrayList<T>();
for (T item : items)
list.add(item);
System.out.println(list);
}
Вы можете назвать это следующим образом:
o.<Object>method("Blah", new Long(0));
o.<Number>method(new Integer(100), new Long(0));
Но это вызовет ошибку компилятора:
o.<Number>method("String", new Long(0));
Таким образом, у вас есть общий метод, который является типичным и может использоваться для каждого объекта, не ограничиваясь парикулярным интерфейсом или классом.
Например, когда вам нужен какой-то метод universal для сравнения:
public static <T extends Comparable> T max(T one, T two) {
if (one.compareTo(two) > 0) {
return one;
} else {
return two;
}
}
Это, вероятно, наиболее полезно, когда вы берете коллекцию некоторого типа и возвращаете некоторое подмножество этой коллекции.
<T> List<T> filter(Collection<? extends T> coll, Predicate<? super T> pred) {
List<T> returnList = new ArrayList<T>();
for(T t : coll) {
if(pred.matches(t)){
returnList.add(t);
}
}
return returnList;
}
Edit:
В более общем плане , это полезно, когда вы хотите вернуть определенный тип, или хотите связать типы двух или более параметров в общем виде.
Параметрированные вызовы методов полезны, если вы хотите разрешить разные типы без кастования. Например, вспомогательный класс Collections широко использует вызовы параметризованных методов. Если вы хотите создать новую общую коллекцию, используя один из своих вспомогательных методов, несколько примеров:
List<String> anEmptyStringList = Collections.<String>emptyList();
Set<Integer> unmodifiableCopy = Collections.<Integer>unmodifiableSet(originalSet);
Итак, если вы хотите использовать общий тип в другом месте, вы хотите использовать эти вызовы методов. Они предотвращают предупреждения компилятора при использовании дженериков.
List<String> anEmptyStringList = Collections.emptyList()
без параметра в вызове. Фактически, я впервые узнал об этом от коллеги, который показывал мне, как избавиться от предупреждения.
– justkt
6 May 2010 в 15:35