【问题标题】:Need assistance in declaring the variable as rowtype without knowing the table name在不知道表名的情况下将变量声明为行类型时需要帮助
【发布时间】:2018-07-04 05:46:51
【问题描述】:
Create table t1_Fact ( Cur_date Date, Name varchar2(10), Event varchar2(50), Price Number(10,0), TAX Number(10,0), Flag Number );
Create table App_Fact ( Application_ID Number, Application_Name varchar2(100), Application_Price Number, Appliation_Tax Number, Flag Number );
Create table t2 ( Table_Name Varchar2(100), Table_Columns Varchar(100), Table_Measure varchar2(100), t3_columns varchar2(100), t3_measures varchar2(100), t3_Where_Clause varchar2(100) );
Create table t3 ( Cur_date Date, Name varchar2(10), Event varchar2(50), Application_ID Number, Application_Name varchar2(100), Application_Price Number, Appliation_Tax Number, Price Number(10,0), TAX Number(10,0), Flag Number );

table t2 包含所有的表名、每个源表和目标表的列名以及where 子句条件。

这里我需要通过将事实表名称作为参数传递事实表的列名、度量和 where 子句使用 group 将数据从 t3 插入到特定的事实表中。

就像我们在过程中传递 t1_Fact 表一样,我们必须从 t2 获取所有详细信息,从 t3 获取详细信息并插入 t1_Fact 并将它们保存到 CSV 文件中

我已经尝试了以下过程,但是我无法将数据插入到 csv 文件中。

注意:在以下过程中,我需要将表(表名)数据提取到 q2 中,我已将变量声明为 recordsFetched VARCHAR2(3000 BYTE);。 需要知道我们如何在不知道表名的情况下将 recordsFetched 声明为%rowtype,因为我们从游标中获取表名。 我也可以知道如何在UTL_FILE.PUT_Line()中使用立即执行@

Create or Replace Procedure CommonProcedure(sourceTableName IN VARCHAR2) Is
  tablename t2.Table_Name%TYPE;
  destcolumns t2.Table_Columns%TYPE;
  destMeasures t2.Table_Measure%TYPE;
  whereClause t2.t3_Where_Clause%TYPE;
  sourceColumns t2.t3_columns%TYPE;
  sourceMeasures t2.t3_measures%TYPE;
  q1 VARCHAR2(3000 BYTE);
q2 VARCHAR2(3000 BYTE);
 recordsFetched VARCHAR2(3000 BYTE);
  pathInfo VARCHAR2(3000 BYTE);

   v_file  UTL_FILE.FILE_TYPE;

 Cursor TableName Is  SELECT Table_Name FROM t2;

Begin


 Open c1;
 Loop
   Fetch TableName Into tablename;
   Exit When TableName%notfound;

    SELECT Table_Columns, Table_Measure, t3_columns, t3_measures INTO destcolumns,destMeasures,sourceColumns,sourceMeasures FROM t2 where Table_Name = tablename;

    q1 := 'INSERT INTO '||tablename||'('||destColumns||','||destMeasures||')'||
        ' ( SELECT '||sourceColumns||','||sourceMeasures||','||sourceTableName
          ||' FROM '||sourceTableName||' GROUP BY '||sourceColumns||')';

    Execute Immediate q1;

q2 := 'SELECT ' || destColumns || ',' || destMeasures ||' FROM ' || tablename || '';
           dbms_output.put_line(q2);
           EXECUTE IMMEDIATE  q2 into recordsfetched; --Getting an error here


         v_file := UTL_FILE.FOPEN('USER_DIR', destinationTableName ||'.csv', 'W');  
           UTL_FILE.PUT_Line(v_file, recordsfetched);
           UTL_FILE.FCLOSE(v_file);

 End Loop;

 Close TableName;

End;

当我执行上述程序时出现以下错误

Error report -
ORA-00932: inconsistent datatypes: expected - got -
ORA-06512: at "GENERATECSV", line 47
ORA-06512: at line 1
00932. 00000 -  "inconsistent datatypes: expected %s got %s"
*Cause:    
*Action:

请进一步帮助我。

提前致谢。

【问题讨论】:

  • @APC 请检查我现在已做出更改的问题,并在这种情况下帮助我。提前致谢

标签: oracle plsql plsqldeveloper utl-file


【解决方案1】:

您正在将两个值(destColumns 和 destMeasures)选择到一个变量(recordsfetched)中。

  q2 := 'SELECT ' || destColumns || ',' || destMeasures ||' FROM ' || tablename || '';
  EXECUTE IMMEDIATE  q2 into recordsfetched;

应该是这样的:

q2 := 'SELECT ' || destColumns || ',' || destMeasures ||' FROM ' || tablename || '';
EXECUTE IMMEDIATE  q2 into Columnsfetched,MeasuresFetched;

【讨论】:

  • 我正在选择总表,不仅有两个值...在 destColumns 我有 n 列数据并且同样反映到 destMeasures 例如:q2:=consider select * from tablename;立即执行 q2 到获取的记录中;在这里我收到一个错误
  • 很可能 destColumns 和 destMeasures 本身包含逗号,因此将选择列表扩展为 2 个以上的值。尽管如此,它永远不会进入一个变量。也许您想在整个内容周围加上引号,以便结果是一个字符串?
  • 根据您的建议尝试了相同的方法,但仍然出现错误。这里的错误可能是由于变量声明错误,因为我已将变量声明为 recordsFetched VARCHAR2(3000 BYTE);我可以知道我们如何在不知道表名的情况下将 recordsFetched 声明为 %rowtype,因为我们从游标中获取表名。我也可以知道如何在 UTL_FILE.PUT_Line() 中使用立即执行
  • 我对您的代码进行了一些更改,现在它仅在表格有一行时才有效,如果我有多行,我们如何导出数据。请告诉我你的建议。得到如下错误 01422. 00000 - “精确提取返回的行数超过请求的行数” *原因:精确提取中指定的数量小于返回的行数。 *操作:重写查询或更改请求的行数
  • 您需要一个循环来逐个获取记录。 blogs.oracle.com/oraclemagazine/working-with-cursors
【解决方案2】:

这是一个复杂的过程。但可惜不够复杂。要使第二个动态查询起作用,您需要选择一个与组装查询的投影相匹配的记录集。所以你需要生成一些动态代码来做到这一点。

或者你可以试试这样的:

....
Execute Immediate q1;

destColumns := replace( destColumns, ',', q'[||','||]');
destMeasures := replace( destMeasures, ',', q'[||','||]');

q2 := 'SELECT ' || destColumns || ',' || destMeasures ||' FROM ' || tablename || '';
dbms_output.put_line(q2);
EXECUTE IMMEDIATE  q2 into recordsfetched;
....

这会将投影变成一个宽列,可以写入文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    相关资源
    最近更新 更多