【问题标题】:SQL query does not give the output when using variables使用变量时 SQL 查询不给出输出
【发布时间】:2021-06-20 08:12:29
【问题描述】:

我在 sql 表中插入了下面的查询。

select account_num,bill_seq,bill_version,
to_char(start_of_bill_dtm,'YYYYMM-DD') st_bill_dtm, 
to_char(bill_dtm - 1,'YYYYMM-DD') en_bill_dtm,
to_char(actual_bill_dtm,'YYYYMM-DD') act_bill_dtm, 
round((invoice_net_mny + invoice_tax_mny)/1000,0) mon_bill,
bill_type_id,bill_status
from billsummary
where to_char(bill_dtm - 1,'YYYYMM') between'||chr(32)||
startMonth ||chr(32)||'and'|| chr(32)||endMonth ||chr(32)||
'and cancellation_dtm is null

我尝试在下面的循环中执行该查询。

FOR a in 1 .. 17 LOOP 
 dbms_output.put_line(startmonth);
 dbms_output.put_line(endmonth);
 dbms_output.put_line('in the loop');
 sql_query:='select run_sql from table_1';
 Execute IMMEDIATE sql_query;
 Execute IMMEDIATE 'commit';
END LOOP;

但它没有给出任何输出。我尝试通过硬编码“startMonth”和“endMonth”来执行相同的查询,如下所示。

select account_num,bill_seq,bill_version,
to_char(start_of_bill_dtm,'YYYYMM-DD') st_bill_dtm, 
to_char(bill_dtm - 1,'YYYYMM-DD') en_bill_dtm,
to_char(actual_bill_dtm,'YYYYMM-DD') act_bill_dtm, 
round((invoice_net_mny + invoice_tax_mny)/1000,0) mon_bill,
bill_type_id,bill_status
from billsummary
where to_char(bill_dtm - 1,'YYYYMM') between'202011 'and'202104'and cancellation_dtm is null

然后它起作用并给了我一个输出。变量(startMonth 和 endMonth)的值在循环中也是可见的。有谁可以找出原因吗?

更新

我更新了查询以使用解决方案中提到的绑定变量。

这是我的程序。

CREATE OR REPLACE procedure schema.sixMonthAverage (startMonth varchar,endMonth varchar ,thirdMonth varchar )
IS
start_date varchar :=:startMonth;
end_date varchar :=:endMonth;

begin

for c_rec in(select run_sql from table_1)
 loop
      execute immediate c_rec.run_sql using start_date, end_date;
END LOOP;

EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Exception');
END;
/

这给了我“startMonth”和“endMonth”的错误“错误绑定变量”。

这就是我调用过程的方式。

Execute Schema.sixMonthAverage ('202011', '202104', '202001');
commit;

查询在 table_1 中。如下图所示。

create table tbl_six_mon_1
as
select account_num,bill_seq,bill_version,
to_char(start_of_bill_dtm,'YYYYMM-DD') st_bill_dtm, 
to_char(bill_dtm - 1,'YYYYMM-DD') en_bill_dtm,
to_char(actual_bill_dtm,'YYYYMM-DD') act_bill_dtm, 
round((invoice_net_mny + invoice_tax_mny)/1000,0) mon_bill,
bill_type_id,bill_status
from billsummary
where to_char(bill_dtm - 1,'YYYYMM') between :start_date and :end_date
and cancellation_dtm is null

谁能找出我方法中的错误?

【问题讨论】:

  • 1.你执行select run_sql from table_1,没有什么可提交的。尝试在控制台/IDE 中自己运行它。 PL/SQL 也是如此。 2. 您的过滤谓词包含字符串|| chr(32)||endMonth ||chr(32)||,它不是日期,并且在此条件下不会选择任何日期。 3. EXECUTE IMMEDIATE 使用自己的隔离上下文执行给定的语句,因此它不知道任何外部变量。这不是用dbms_output 打印的文本的执行。传递变量,需要使用using加法

标签: sql oracle


【解决方案1】:

已经有一段时间了,但是,

问题 1。

我假设您在 table_1 中插入第一个查询,并在从 table_1 中提取该查询后尝试执行该查询。引用看起来完全错误。

where to_char(bill_dtm - 1,'YYYYMM') between'||chr(32)||
startMonth ||chr(32)||'and'|| chr(32)||endMonth ||chr(32)||
'and cancellation_dtm is null

我希望它看起来像

where to_char(bill_dtm - 1,'YYYYMM') between startMonth and endMonth
and cancellation_dtm is null

问题 2。

我怀疑 startMonth 和 endMonth 不在插入到 table_1 中的 SQL 的上下文中 可能是这样的(我做这个sql已经好几年了,所以我的语法可能是错误的)

您可以使用绑定变量并假设 table_1 中的查询有 2 个绑定变量。

**your SQL query here.**
where to_char(bill_dtm - 1,'YYYYMM') between :1 and :2
and cancellation_dtm is null

当你执行语句时,建立那些绑定变量。

execute immediate sql_query using startMonth, endMonth,

问题 3。

您的最终查询,您在硬编码的“202011”中有一个尾随空格

正如我所说,我已经有好几年没有做这种事情了,所以我的语法可能有点不对劲,但它应该为您指明正确的方向。 :)

【讨论】:

    【解决方案2】:

    你不能期望输出直接显示在 PL/SQL 代码中

    FOR a in 1 .. 17 LOOP 
     dbms_output.put_line(startmonth);
     dbms_output.put_line(endmonth);
     dbms_output.put_line('in the loop');
     sql_query:='select run_sql from table_1';
     Execute IMMEDIATE sql_query;
     Execute IMMEDIATE 'commit';
    END LOOP;
    

    而不是使用EXECUTE IMMEDIATE 使用 select into 并将数据存储到 Collection 然后使用 DBMS_OUTPUT 包显示它。

    您使用带字符之间的关键字的第二件事 where to_char(bill_dtm - 1,'YYYYMM') between'202011 'and'202104'and cancellation_dtm is null 这使逻辑无效 直接使用日期列,不要隐蔽。

    where bill_dtm between to_date(202011, 'yyyymm') and to_date(202104, 'yyyymm')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 2022-08-15
      • 2016-07-31
      • 1970-01-01
      • 2017-12-12
      • 1970-01-01
      相关资源
      最近更新 更多