Нужна помощь в объявлении переменной как типа строки, не зная имени таблицы

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 );

таблица t2 содержит все имена таблиц, имена столбцов каждой исходной и целевой таблиц и условия предложения where.

Здесь мне нужно вставить данные из t3 в конкретную таблицу фактов, используя группу по именам столбцов таблицы фактов, меры и предложение where, передав имя таблицы фактов в качестве параметра.

Например, если мы передаем таблицу t1_Fact в процедуре, мы должны получить все детали из t2 и получить детали из t3 и вставить их в t1_Fact, а также сохранить их в файл CSV.

Я пробовал следующую процедуру, но не могу вставить данные в CSV-файл.

Примечание. В следующей процедуре мне нужно получить данные таблицы (имя таблицы) в q2, я объявил переменную как recordsFetched VARCHAR2(3000 BYTE);. Нужно знать, как мы объявляем RecordFetched как %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:

Пожалуйста, помогите мне дальше.

Заранее спасибо.


person Ram    schedule 04.07.2018    source источник
comment
@APC Пожалуйста, проверьте вопрос, который я внес сейчас, и помогите мне в этом случае. заранее спасибо   -  person Ram    schedule 04.07.2018


Ответы (2)


Вы выбираете два значения (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;
person Rene    schedule 04.07.2018
comment
я выбираю общую таблицу там не только два значения ... в destColumns у меня есть n данных о количестве столбцов, и то же самое отражается на destMeasures Ex: q2: = рассмотрите выбор * из имени таблицы; выполнить немедленный q2 в Recordsfetched; вот у меня ошибка - person Ram; 04.07.2018
comment
Вполне возможно, что сами destColumns и destMeasures содержат запятые, таким образом расширяя список выбора до более чем 2 значений. Тем не менее, он никогда не войдет в одну переменную. Может быть, вы хотите заключить все это в кавычки, чтобы результатом была одна строка? - person Rene; 04.07.2018
comment
по вашему предложению попробовал то же самое, все равно получаю ошибку. Здесь ошибка может быть связана с неправильным объявлением переменной, так как я объявил переменную как recordsFetched VARCHAR2(3000 BYTE); Могу ли я узнать, как мы можем объявить RecordFetched как% rowtype, не зная имени таблицы, поскольку мы получаем имя таблицы из курсора. Также могу ли я знать, как использовать немедленное выполнение в UTL_FILE.PUT_Line() - person Ram; 04.07.2018
comment
Я внес несколько изменений в ваш код, и теперь он работает, только если в таблице есть одна строка, если у меня несколько строк, как мы можем экспортировать данные. Могу ли я узнать ваши предложения, пожалуйста. получение следующей ошибки 01422. 00000 - точная выборка возвращает больше запрошенного количества строк. * Причина: число, указанное в точной выборке, меньше, чем возвращенные строки. *Действие: перепишите запрос или измените количество запрошенных строк. - person Ram; 04.07.2018
comment
Вам нужен цикл для выборки записей по одной. blogs.oracle.com/oraclemagazine/working-with-cursors - person Rene; 04.07.2018

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

Или вы можете попробовать что-то вроде этого:

....
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;
....

Это превращает проекцию в один широкий столбец, который можно записать в файл.

person APC    schedule 04.07.2018