【问题标题】:SQL Error: ORA-00984: column not allowed here 00984. 00000 - "column not allowed here"SQL 错误:ORA-00984:此处不允许列 00984。00000 -“此处不允许列”
【发布时间】:2020-03-31 18:08:51
【问题描述】:

我收到错误: 命令行错误: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_cmets。 基本上我想要 v_VAL_DONE_BY 和 v_Comments 的动态列名。 相同的立即执行在独立的 pl sql 块中工作。在执行语句中使用引号似乎有些问题 你能帮忙吗?

【问题讨论】:

  • 在第 57 行,您是否打算在字符串中包含 :3?即应该是':3' ||',' ... 吗?
  • @BJones:我正要提到它,但我打字很慢 :-) 但这不会引发错误,对吗?

标签: oracle plsql execute-immediate


【解决方案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 看到它现在可以插入到表中的单个字符串。 (您可以从突出显示的语法中看到现在这是一个字符串。)

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

【讨论】:

  • Thnaks Thorsten Kettner :-)。就像魅力一样。但我不明白它为什么起作用。
  • 你的意思是INSERT语句现在成功了,还是动态代码运行成功了?
  • @Ankit Kumar:我已经添加了解释。我希望这可以为您澄清一些事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2013-06-07
相关资源
最近更新 更多