【问题标题】:Query for particular integer value from multiple columns with number datatype从具有数字数据类型的多列中查询特定整数值
【发布时间】:2015-11-18 01:00:38
【问题描述】:

我尝试从多个列(数据类型编号)中搜索一个数字,但得到ORA-01722: invalid number 错误。

我的查询:

SELECT *
 FROM CAMPAIGN
WHERE 1481125 IN (select column_name
                    from all_tab_columns
                   where table_name = 'CAMPAIGN'
                     AND data_type = 'NUMBER');

这有什么问题?

【问题讨论】:

  • WHERE 1481125 IN (select column_name 问题就在这里。 Oracle 尝试将column_name 转换为数字。

标签: sql oracle ora-01722


【解决方案1】:

您的查询是:

SELECT * FROM CAMPAIGN WHERE 1481125 IN 
(select column_name from all_tab_columns where table_name = 'CAMPAIGN' AND data_type='NUMBER')

我们将其分解:

SELECT * FROM CAMPAIGN WHERE 1481125 IN (<a set of numbers>)

和子查询:

select column_name from all_tab_columns
where table_name = 'CAMPAIGN' 
AND data_type='NUMBER'

该子查询将返回列名列表,例如

CAMPAIGN_COUNT
CAMPAIGN_ID
CAMPAIGN_NUMBER_OF_SOMETHINGS

因此,您的查询相当于:

SELECT * FROM CAMPAIGN WHERE 1481125 IN 
   ('CAMPAIGN_COUNT', 'CAMPAIGN_ID', 'CAMPAIGN_NUMBER_OF_SOMETHINGS')

您可以看到为什么会出现 ORA-01722 错误吗?

您需要编写动态 SQL 来实现您的目标。

【讨论】:

    【解决方案2】:

    您将数字 1481125 与每一列的名称进行比较,而不是表中每一列的值。

    要从列名(从 dba_tab_columns)到该列中的值,您需要使用某种形式的动态 SQL。下面是一个比较简单的例子:

    DECLARE
      -- Since I don't have your CAMPAIGN table or data, I'm using DBA_OBJECTS in it's place.
      l_table_name      VARCHAR2 (30) := 'DBA_OBJECTS';
      l_search_number   NUMBER := 20;                                                             -- 1481125 in your example
      l_record          dba_objects%ROWTYPE;
      l_sql             VARCHAR2 (32000);
      l_column_number   NUMBER := 0;
      l_cur             SYS_REFCURSOR;
    BEGIN
      -- First: build dynamic SQL statement of the form:
      -- SELECT * FROM table_name WHERE
      -- ( ( col_name_a = 20 ) OR ( col_name_b = 20 ) OR ... )
      l_sql   := 'SELECT * FROM dba_objects WHERE ( ';
    
      FOR r_number_column IN (SELECT column_name
                              FROM   dba_tab_columns
                              WHERE  table_name = l_table_name
                              AND    data_type = 'NUMBER'
                              ORDER BY column_id) LOOP
        IF l_column_number > 0 THEN
          l_sql   := l_sql || ' OR ';
        END IF;
    
        l_column_number   := l_column_number + 1;
        l_sql             := l_sql || '(' || r_number_column.column_name || ' = ' || l_search_number || ')';
      END LOOP;
    
      IF l_column_number = 0 THEN
        -- No number columns in table, so there should be no matches
        l_sql   := l_sql || ' 1=0';
      END IF;
    
      l_sql   := l_sql || ')';
    
      DBMS_OUTPUT.put_line (l_sql);
    
      OPEN l_cur FOR l_sql;
    
      LOOP
        FETCH l_cur INTO   l_record;
    
        EXIT WHEN l_cur%NOTFOUND;
        DBMS_OUTPUT.put_line ('Object Name ' || l_record.object_name || ' has search number ' || l_search_number);
      END LOOP;
    END;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-05
      • 2015-11-17
      相关资源
      最近更新 更多