使用游标从动态视图中获取动态列的数据

时间:2015-02-23 13:17:59

标签: oracle plsql cursor

要求是检查视图的数据一致性。这有点复杂,所以让我们一步步走。

  1. 表check_data_column基本上有5个imp。 columns:ViewName,ColumnName,Mandatory,MaxLength,DataType。
  2. 它将包含有关特定视图的每个字段的信息。例如:

    ViewName: Employee_V
    ColumnName: EmployeeNo
    Mandatory: 1 (True)
    MaxLength: 10
    DataType: Number
    
    ViewName: Employee_V
    ColumnName: EmployeeName
    Mandatory: 1 (True)
    MaxLength: 20
    DataType: String
    
    1. 现在我必须编写一个函数来获取此check_data_column中的所有条目,并检查每个提到的列的相应视图中的数据。
    2. 从上面的例子中,它将检查Employee_V中的数据。 EmployeNo列中的每个条目都不应为null,max length应为10,它应该是一个数值。 同样,EmployeeName列中的每个条目都不应为null,max length应为20,它应该是一个字符串。

      1. 观看次数未知且无。每个视图中的列都是未知的。
      2. 为了解决上述问题,我编写了以下代码:

        FUNCTION CheckData(viewname VARCHAR2)
        RETURN VARCHAR2
        Is
        
          return_v      VARCHAR2(1000);
          query_v       VARCHAR2(200);
          column_c      SYS_REFCURSOR;
          column_v      column_c%ROWTYPE;
        
          CURSOR ddc_c IS
          SELECT *
          FROM check_data_column;
        
        BEGIN
          return_v := null;
        
          FOR ddc_v IN ddc_c LOOP
        
            query_v := 'SELECT' || ddc_v.column_name || 'FROM anc_sap.' || ddc_v.viewname;
        
            OPEN column_c FOR query_v;
            LOOP
               FETCH column_c INTO column_v;
               EXIT WHEN column_c%NOTFOUND;
        
               IF LENGTH(column_v) > ddc_v.max_length THEN
                   return_v := 'Max. length exceeded';
               END IF;
        
               ----Other validations (on mandatory and data type)
        
            END LOOP; 
            CLOSE column_c;
        
          END LOOP;
        
          RETURN return_v;
        
        END CheckData;
        

        问题:

        我在这里面临的问题是为sys_refcursor column_c声明column_v变量。因为在这个时候我无法想到替换sys_refcursor,我还能做什么呢?

1 个答案:

答案 0 :(得分:1)

此功能适用于简单测试。它检查空值和长度,你必须添加其余的验证。

create or replace function CheckData(i_viewname VARCHAR2)
RETURN VARCHAR2
Is
  query_v       VARCHAR2(2000);
  v_cnt number := 0;

  CURSOR ddc_c IS 
    SELECT * FROM check_data_column where viewname = i_viewname;

BEGIN
  FOR ddc_v IN ddc_c LOOP

    -- check nulls
    if ddc_v.mandatory = 1 then
      query_v := 'select count(1) from '|| ddc_v.viewname 
        ||' where '||ddc_v.columnname||' is null';
      execute immediate query_v into v_cnt;
      if v_cnt > 0 then
        return 'null values for mandatory column '
          ||ddc_v.viewname ||'.'||ddc_v.columnname||' exists';
      end if;
    end if;

    -- check column length
    query_v := 'select count(1) from '|| ddc_v.viewname 
      ||' where length('||ddc_v.columnname||') > '||ddc_v.maxlength;
    execute immediate query_v into v_cnt;
    if v_cnt > 0 then
      return 'max length in column '||ddc_v.viewname
        ||'.'||ddc_v.columnname||' exceeded';
    end if;

    -- other validations

  END LOOP;

  RETURN 'OK';

END CheckData;