Параметризация значений для Oracle sql

Я использую Oracle - разработчик SQL

Хотите проверить количество нулевых значений для каждого столбца.

В настоящее время я использую нижеприведенные для достижения результатов.

выберите COLUMN_NAME из all_tab_columns, где table_name = 'EMPLOYEE'

    SELECT COUNT (*) FROM EMPLOYEE WHERE <Column_name1> IS NULL
    UNION ALL
    SELECT COUNT (*) FROM EMPLOYEE WHERE <Column_name2> NULL
    UNION ALL
    SELECT COUNT (*) FROM EMPLOYEE WHERE <Column_name3> IS NULL
    UNION ALL ......................

Как мы можем использовать значение привязки для выполнения следующего запроса, например

   DEFINE Column_name = Column_name1
   SELECT COUNT (*) FROM EMPLOYEE WHERE &&Column_name IS NULL .

person Awknewbie    schedule 27.08.2014    source источник
comment
для этого вам нужно использовать динамический sql-путь.   -  person Sathyajith Bhat    schedule 27.08.2014
comment
NUM_NULLS в all_tab_columns будет иметь количество NULL значений в этой таблице. При условии, что в таблице обновлена ​​статистика !! Любые данные, вставленные / обновленные без сбора статистики, приведут к неправильному ответу. Чтобы узнать о статистике, обратитесь к Oracle Docs.   -  person Maheswaran Ravisankar    schedule 27.08.2014


Ответы (3)


Вы не можете использовать переменные связывания при построении оператора select, вы можете передавать значения через переменные связывания, но сам оператор select не может быть создан. Вам необходимо использовать способ динамического SQL, используя EXECUTE IMMEDIATE < / а>.

Вот пример:

DECLARE
    v_sql_statement VARCHAR2(2000);
    n_null_count    NUMBER;
BEGIN
    FOR cn IN (SELECT column_name
               FROM   user_tab_cols
               WHERE  table_name = 'EMPLOYEE') LOOP
        v_sql_statement := 'SELECT COUNT(1) FROM EMPLOYEE where '
                           || cn.column_name
                           || ' IS null';

        EXECUTE IMMEDIATE v_sql_statement INTO n_null_count;

        dbms_output.Put_line('Count of nulls for column: '
                             || cn.column_name
                             || ' is: '
                             || n_null_count);
    END LOOP;
END; 

Это то, что даст приведенный выше запрос

Количество нулей для столбца: EMPNO: 0
Количество нулей для столбца: NAME: 0
Количество нулей для столбца: JOB равно: 0
Количество нулей для столбца: BOSS: 1 < br> Количество нулей для столбца: HIREDATE равно: 0
Количество нулей для столбца: SALARY равно: 0
Количество нулей для столбца: COMM равно: 20
Количество нулей для столбца: DEPTNO равно: 0

person Sathyajith Bhat    schedule 27.08.2014
comment
Почему ни один EXECUTE IMMEDIATE не использует all_tab_columns? COUNT(COLUMN_NAME1),COUNT(COLUMN_NAME2) FROM TABLE? - person Maheswaran Ravisankar; 27.08.2014
comment
@MaheswaranRavisankar COLUMN_NAME1, COLUMN_NAME2 ... COLUMN_NAMEn - это строки во all_tab_columns, вам нужно перебрать все строки и не найти нулевых значений для каждого column_name - person Sathyajith Bhat; 27.08.2014
comment
Спасибо, Сатья, за руководство - person Awknewbie; 27.08.2014

Нет, вы не можете сделать это с помощью переменных связывания. Это связано с тем, что запрос выполняется, и он должен знать имя поля во время компиляции. Чтобы добиться того, чего вы хотите, вы можете создать нужный запрос в VARCHAR2 и использовать немедленное выполнение.

person Robert3452    schedule 27.08.2014

Почему бы просто не использовать NUM_NULLS? Но вам следует собрать статистику раньше

exec dbms_stats.gather_table_stats('user','TBL');

select num_nulls from user_tab_columns where table_name='TBL';

Вы также можете использовать coalesce для более быстрого выполнения, чем IS NULL

SELECT COUNT(COALESCE( _COLUMN, 1)) AS CNT FROM _TABLE;

Если вы хотите, чтобы количество столбцов было мудрым, я бы повторил ответ Сати, но с COALESCE вместо IS NULL

person SriniV    schedule 27.08.2014