SQL错误:ORA-00984:此处不允许在此列00984。00000-“此处不允许使用列”

时间:2019-12-06 18:17:36

标签: oracle plsql execute-immediate

我遇到错误: 命令行错误:45列:111 错误报告 - SQL错误:ORA-00984:此处不允许使用列 00984. 00000-“此处不允许使用列”

查询:

Insert into BL_DIFF_QUERY_ANL (TABLE_NAME,ISSUSE,ISSUE_CATEGORY,ISSUE_ID,DB_QUERY) 
values ('BILL','TOTAL_BILLED_ADJUST_MISMATCH','TOTAL_BILLED_ADJUST',2,
'DECLARE 
V_DIFF_AMT_chr varchar2(20);
V_DIFF_AMT NUMBER(9,2);
V_SUM_ACTV_AMT NUMBER(9,2);
V_SUM_ACTV_TAXES_AMT NUMBER(9,2);
V_COUNT NUMBER(1);
v_val_Done_by varchar(25) ;
v_ban number(10) := 339339856;
v_comments varchar(20);
v_success varchar(10) := ''SUCCESS'';
v_yesnoind varchar(1) := ''Y'';
v_immediate_Adj varchar (30) := ''IMMEDIATE_ADJUSTMENT'';
v_issue_Desc  varcahr(50) := ''TOTAL_BILLED_ADJUST_MISMATCH'';
BEGIN 
DBMS_OUTPUT.Put_line (''BAN: '' || :1 || ''  ACTV_BILL_SEQ_NO : '' || :2 || '' SUBSCRIBER: '' || :3 
|| ''COLUMN_NAME : '' || :4 || '' COLUMN_DATA: '' || :5 || ''DIFF_DATA : '' || :6 || '' SOC: '' || 
:7 || '' FEATURE_CODE: '' || :8 || '' FTR_REVENUE_CODE: '' || :9 || '' PRIOD_CVRG_ST_DATE: '' || :10 
|| '' PRIOD_CVRG_ND_DATE: '' || :11 || '' ACTV_REASON_CODE: '' || :12 || ''BALANCE_IMPACT_CODE: '' 
|| :13 || ''  SOURCE_APPL_CODE : '' || :14 || '' DISCOUNT_CD: '' || :15 || '' BILL_MEDIA : '' || :16 
|| '' BILL_FORMAT : '' || :17 || '' PRODUCT_TYPE: '' || :18 || '' FTR_TYPE '' || :19 || '' VAL_ID '' 
|| :20 );

select ''comments_''|| :20  into v_comments from dual;
select ''val_done_by_''|| :20  into  v_VAL_DONE_BY from dual;
SELECT COUNT (distinct tax_ind ) into V_COUNT FROM SERVICE_AGREEMENT WHERE BAN = :1 and SERVICE_TYPE 
= ''P'' and EXPIRATION_DATE is NULL and tax_ind = ''TI''; 
DBMS_OUTPUT.Put_line (V_COUNT);
if (V_COUNT = 0) 
then 
SELECT ABS ( (nvl(sum(t1.ACTV_AMT),0) - nvl(sum(t2.ACTV_AMT),0)) + (nvl(sum(t1.TAX_CITY_CUST_AMT),0) 
- nvl(sum(t2.TAX_CITY_CUST_AMT),0)) + (nvl(sum(t1.TAX_COUNTY_CUST_AMT),0) 
nvl(sum(t2.TAX_COUNTY_CUST_AMT),0)) + (nvl(sum(t1.TAX_STATE_CUST_AMT),0) - 
nvl(sum(t2.TAX_STATE_CUST_AMT),0)) + (nvl(sum(t1.TAX_FEDERAL_AMT),0) - 
nvl(sum(t2.TAX_FEDERAL_AMT),0)) + (nvl(sum(t1.TAX_ROAMING_AMT),0) - nvl(sum(t2.TAX_ROAMING_AMT),0)) 
) into V_SUM_ACTV_TAXES_AMT 
from QATAPP50.ADJUSTMENT t1 ,QATAPP55.ADJUSTMENT@abc_test t2 where t1.BAN = :1 and t2.ban=t1.ban and 
t1.ACTV_BILL_SEQ_NO = :2 and t2.ACTV_BILL_SEQ_NO = t1.ACTV_BILL_SEQ_NO 
and t1.balance_impact_code = ''I'' and t2.balance_impact_code = t1.balance_impact_code and 
nvl(t1.CHARGE_SEQ_NO,0) = nvl(t2.CHARGE_SEQ_NO,0);

else 
SELECT ABS( nvl(sum(t1.ACTV_AMT),0) - nvl(sum(t2.ACTV_AMT),0) ) into V_SUM_ACTV_AMT 
from QATAPP50.ADJUSTMENT t1 ,QATAPP55.ADJUSTMENT@abc_test t2 where t1.BAN = :1 
and t2.ban=t1.ban and t1.ACTV_BILL_SEQ_NO = :2 and t2.ACTV_BILL_SEQ_NO = t1.ACTV_BILL_SEQ_NO 
and t1.balance_impact_code = ''I'' and t2.balance_impact_code = t1.balance_impact_code 
and nvl(t1.CHARGE_SEQ_NO,0) = nvl(t2.CHARGE_SEQ_NO,0);
end if;
DBMS_OUTPUT.Put_line (V_SUM_ACTV_TAXES_AMT);
DBMS_OUTPUT.Put_line (V_SUM_ACTV_AMT);

if ( V_SUM_ACTV_AMT = V_DIFF_AMT or V_SUM_ACTV_TAXES_AMT = V_DIFF_AMT ) 
then 

execute immediate ''UPDATE BL_DIFF_CATEGORY SET VALIDATION_STS = :2' ||','|| v_VAL_DONE_BY || '='|| 
:3 ||','||  v_comments || '= :4  where BAN = :1 and  
DIFF_TYPE = :5
'' using v_issue_Desc,v_immediate_Adj,v_yesnoind,v_success,v_ban;

 COMMIT;
 END IF;
END;'
);

按行号和列号,错误在执行即时语句中的v_comments处。 基本上我想要v_VAL_DONE_BY和v_Comments的动态列名。 同一执行立即在独立的pl sql块中工作。在execute语句中使用引号似乎有些问题 你能帮忙吗?

1 个答案:

答案 0 :(得分:1)

您是否在PL / SQL块中运行此插入语句?您在查询中使用的变量是SQL用来获取列名(不存在)并引发错误的变量。如果您正在PL / SQL中运行此代码,那么您当然必须声明变量并对绑定变量:3进行某些操作,如BJones在您的请求注释中提到的那样。

SQL:

Insert into BL_DIFF_QUERY_ANL (TABLE_NAME,ISSUSE,ISSUE_CATEGORY,ISSUE_ID,DB_QUERY)
values ('BILL','TOTAL_BILLED_ADJUST_MISMATCH','TOTAL_BILLED_ADJUST',2,
...
execute immediate ''UPDATE BL_DIFF_CATEGORY SET VALIDATION_STS = :2,' ||
:v_VAL_DONE_BY ||
'='||
:3 ||
','||
:v_comments ||
'= :4  where BAN = :1 and
...
);

PL / SQL

declare
  v_VAL_DONE_BY varchar2(4000);
  v_comments varchar2(4000);
begin
  Insert into BL_DIFF_QUERY_ANL (TABLE_NAME,ISSUSE,ISSUE_CATEGORY,ISSUE_ID,DB_QUERY)
  values ('BILL','TOTAL_BILLED_ADJUST_MISMATCH','TOTAL_BILLED_ADJUST',2,
  ...
  execute immediate ''UPDATE BL_DIFF_CATEGORY SET VALIDATION_STS = :2,' ||
  v_VAL_DONE_BY ||
  '= :3 ,'||
  v_comments ||
  '= :4  where BAN = :1 and
  ...
  );
end;

更新:再次输入SQL

仔细观察一下您使用的变量名,我得出的结论是,这些变量应该是您要插入的SQL字符串的一部分:

  ...
  execute immediate ''UPDATE BL_DIFF_CATEGORY SET VALIDATION_STS = :2, '' ||
  v_VAL_DONE_BY || '' = :3, '' || v_comments || '' = :4  where BAN = :1 and DIFF_TYPE = :5''
  using v_issue_Desc,v_immediate_Adj,v_yesnoind,v_success,v_ban;

 COMMIT;
 END IF;
END;'
);

外植

您要在表中插入代码。此代码是带有变量和字符串的PL / SQL脚本。这是此类PL / SQL代码的一个小示例:

declare
  v_number integer := 5;
begin
  dbms_output.put_line('The number is: ' || v_number);
end;

您要将其作为字符串插入。但是,如果您仅将单引号放在开头和结尾,例如

insert into mytable (mycode) values
(
  'declare
     v_number integer := 5;
   begin
     dbms_output.put_line('Number ' || v_number);
   end;'
);

这不起作用,因为代码本身包含单引号。 DBMS读取字符串,从开始的引号到找到的下一个引号,在此示例中,该字符串恰好位于Number之前。因此,DBMS看到一个字符串,后接单词Number,并且不知道该怎么做。 Number看起来像列名,但列名不属于该列名。 (您可以从突出显示的语法中看到,DBMS看到两个字符串,中间是woprd Number。)

解决方案是用另一个单引号屏蔽所有单引号(即在编辑器中将'替换为''

insert into mytable (mycode) values
(
  'declare
     v_number integer := 5;
   begin
     dbms_output.put_line(''Number '' || v_number);
   end;'
);

所有单引号对都被视为字符串的一部分,现在表示其中的单引号。 DBMS看到一个可以立即插入表中的字符串。 (您可以从突出显示的语法中看到,现在这是一个字符串。)

在您的代码中,某些情况下使用单引号对,但并非全部使用。也许您只是手动执行此操作,而不是在编辑器中进行搜索和替换,因此错过了一些情况。

相关问题