我该如何运行该程序

时间:2014-11-25 06:16:39

标签: oracle stored-procedures

exec home_lending_cus('9999999999', 'HOME LENDING', '11111111')

我正在尝试运行上面的语句,但它引发了下面提到的错误。

ORA-00933: SQL Command not properly ended.
ORA-06512: at 'HOME_LENDING_CUS', line 6
ORA-06512: at line1

varchar2

类型的所有变量
CREATE OR REPLACE PROCEDURE home_lending_cus(
    id_no    VARCHAR2,
    prod_nme VARCHAR2,
    rpt_dte  NUMBER) authid current_user
AS
BEGIN
  EXECUTE immediate 
  ' CREATE TABLE abc AS
  SELECT bt.id,
    ct.cus_id
  FROM bnkr_tbl bt ,
    cus_tbl ct ,
    base_tbl bt
  WHERE bt.id  =ct.id
  AND ct.id    =bt.c_id
  AND bt.pr_nme='||prod_nme|| '
  AND bt.dte   ='||rpt_dte|| '
  AND bt.id    ='||id_no|| '
  GROUP BY bt.id,
    ct.cus_id';
END home_lending_cus; 

1 个答案:

答案 0 :(得分:2)

正如@Aramillo指出的那样,字符串变量周围的引号是错误的,这使得动态SQL不起作用。但是,我强烈建议转换为绑定变量,而不是连接。这不仅可以防止出现这种错误,还可以保护您免受SQL注入:

CREATE OR REPLACE PROCEDURE home_lending_cus(
    id_no    VARCHAR2,
    prod_nme VARCHAR2,
    rpt_dte  NUMBER) authid current_user
AS
BEGIN
  EXECUTE immediate 
  ' CREATE TABLE abc AS
  SELECT bt.id,
    ct.cus_id
  FROM bnkr_tbl bt ,
    cus_tbl ct ,
    base_tbl bt
  WHERE bt.id  =ct.id
  AND ct.id    =bt.c_id
  AND bt.pr_nme= :1
  AND bt.dte   = :2
  AND bt.id    = :3
  GROUP BY bt.id,
    ct.cus_id' using prod_nme, rpt_dte, id_no;
END home_lending_cus; 

或者更确切地说,如果允许您在DDL中使用绑定变量。鉴于这种限制,我倾向于将其分为两个命令。

CREATE OR REPLACE PROCEDURE home_lending_cus(
    id_no    VARCHAR2,
    prod_nme VARCHAR2,
    rpt_dte  NUMBER) authid current_user
AS
BEGIN
  EXECUTE immediate 
  ' CREATE TABLE abc (bt_id number, cus_id number)'
  EXECUTE IMMEDIATE 
  'INSERT INTO abc (bt_id, cus_id)
  SELECT bt.id,
    ct.cus_id
  FROM bnkr_tbl bt ,
    cus_tbl ct ,
    base_tbl bt
  WHERE bt.id  =ct.id
  AND ct.id    =bt.c_id
  AND bt.pr_nme= :1
  AND bt.dte   = :2
  AND bt.id    = :3
  GROUP BY bt.id,
    ct.cus_id' using prod_nme, rpt_dte, id_no;
END home_lending_cus;

您可能需要考虑此代码的其他几个问题:

  1. 您的查询也无效,因为您在同一bt条款中使用了别名FROM两次。
  2. 我建议使用SQL-99样式连接,而不是以逗号分隔的表格列表。
  3. 动态创建表的Oracle代码总是有点怀疑。你真的需要创建一个表,还是可以使用全局临时表?后者几乎总是更好的选择。