【问题标题】:Query Returning value as 0查询返回值为0
【发布时间】:2012-11-20 21:56:29
【问题描述】:

我正在尝试在 SQL Developer 中执行以下 PL/SQL 脚本。循环应该返回空值计数,但每次它返回 0。 设置服务器输出

DECLARE

--v_count number;
v_count_null number;

BEGIN
execute immediate 'select count(*) from SP_MOSAIX' into v_count;

FOR  i in (select column_name from all_tab_COLUMNS where table_name = 'SP_MOSAIX')
LOOP
select count(*) into v_count_null from SP_MOSAIX  where i.column_name IS NULL ;
dbms_output.put_line(v_count_null);

END LOOP;

END;

所以当我运行它时,我得到以下输出:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

但如果我手动执行替换 column_name 的查询,我会得到结果。

select count(*) into v_count_null from SP_MOSAIX  where i.column_name IS NULL; 

有人可以帮忙吗?

【问题讨论】:

  • 它返回 0 因为 i.column_name 被视为变量而不是列。现在的问题是我怎样才能使它成为实际的列值而不是变量
  • 在第二个 select 语句中,表 SP_MOSAIX 没有别名“i”。请参阅 SQL 别名:w3schools.com/sql/sql_alias.asp

标签: sql oracle oracle10g oracle11g


【解决方案1】:

您需要注意这里发生的几件事。首先,正如您所提到的,您的 COUNT 查询正在使用 i.column_name 的值执行,该值永远不会为 NULL。

其次,COUNT(*) 返回与您的WHERE 子句条件匹配的行数,而不管NULL 的值如何。如果要计算特定列中有多少 NOT NULL 值,则必须在该列中显式地 COUNT 值。

请看下面的例子 (SQL Fiddle):

Oracle 11g R2 架构设置

CREATE TABLE null_col_vals (
  col_without_nulls INTEGER NOT NULL
, col_with_nulls INTEGER
, col_with_mix INTEGER  
)
/

INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, NULL)
/

INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, 1)
/

INSERT INTO null_col_vals (col_without_nulls, col_with_nulls, col_with_mix)
VALUES (1, NULL, NULL)
/

查询 1

SELECT 
  COUNT(col_without_nulls) col_without_nulls
, COUNT(col_with_nulls) col_with_nulls
, COUNT(col_with_mix) col_with_mix
, COUNT(*) all_rows
FROM null_col_vals

结果

| COL_WITHOUT_NULLS | COL_WITH_NULLS | COL_WITH_MIX | ALL_ROWS |
----------------------------------------------------------------
|                 3 |              0 |            1 |        3 |

如您所见,COUNT(*) 始终返回存在的行数,但其他的结果会有所不同,具体取决于指定列中是否存在NULL 值。

您需要使用EXECUTE IMMEDIATE 将您的列名转换为查询的一部分。像这样的东西可能会完成这项工作:

查询 2

DECLARE

  l_count INTEGER;

BEGIN

  FOR r_col IN (
    SELECT *
    FROM all_tab_columns atc
    WHERE atc.table_name = 'NULL_COL_VALS'
  )
  LOOP

    dbms_output.put_line(r_col.column_name);

    EXECUTE IMMEDIATE 'SELECT COUNT(' || r_col.column_name || ') FROM null_col_vals' 
    INTO l_count;

    dbms_output.put_line(l_count);

  END LOOP;

END;

【讨论】:

  • 感谢您的精彩解释和帮助...我的问题得到了解决... thnx..
【解决方案2】:

您需要使用动态 SQL,这将允许您引用每一列:

FOR  i in (select column_name from all_tab_COLUMNS where table_name = 'SP_MOSAIX')
LOOP
    execute immediate 'select count(*) from SP_MOSAIX  where '||i.column_name||' IS NULL'
     into v_count_null ;
    dbms_output.put_line(i.column_name||' = '||v_count_null);

END LOOP;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多