【问题标题】:Execute Immediate in Oracle 11g在 Oracle 11g 中立即执行
【发布时间】:2017-02-06 16:08:23
【问题描述】:

我正在尝试在 oracle 中创建一个脚本来搜索多个表并插入到我正在创建的临时表中,但是在尝试执行除数字以外的任何操作时出现一些错误。

声明变量

    m_polCount NUMBER:= 0;
    m_product NUMBER:= 0;
    m_version NUMBER:= 0;
    m_plan NUMBER:= 0;
    m_policy NUMBER:= 0;
    m_pol_comm_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_pol_end_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_pol_status NUMBER:= 0;
    m_next_pre_renew_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_next_renew_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_last_renew_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_cover_no NUMBER:= 0;
    m_cover_name VARCHAR(240):= 'Test';
    m_cover_start_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_cover_end_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_sum_assured NUMBER:= 0;
    m_cover_layer NUMBER:= 0;
    m_cover_prem_layer NUMBER:= 0;
    m_premium NUMBER:= 0;
    m_loading_type NUMBER:= 0;
    m_loading_name VARCHAR(200):= 'Test';
    m_basic_prem_loading SMALLINT:= 0;
    m_loading_start_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_loading_end_date DATE:= TO_DATE('01-01-3000','DD-MM-YYYY');
    m_loading_perc NUMBER:= 0;
    m_loading_rate NUMBER:= 0;
    m_loading_prem NUMBER:= 0;
    m_calc_desc VARCHAR(240):= 'Test';
    m_inflation_rate NUMBER:= 0;
    m_agent_no NUMBER:= 0;

表已创建

EXECUTE IMMEDIATE '
        CREATE TABLE I233_ACTIVE_P4L_POLICY_DATA
        (
        PRODUCT NUMBER,
        VERSION NUMBER,
        PLAN_NUMBER NUMBER,
        POLICY_NUMBER NUMBER,
        POLICY_COMM_DATE DATE,
        POLICY_END_DATE DATE,
        POLICY_STATUS NUMBER,
        NEXT_PRE_RENEWAL_DATE DATE,
        NEXT_RENEWAL_DATE DATE,
        LAST_RENEWAL_DATE DATE, 
        COVER_NUMBER NUMBER,
        COVER_NAME VARCHAR(240),
        COVER_START_DATE DATE,
        COVER_END_DATE DATE,
        SUM_ASSURED NUMBER,
        COVER_LAYER NUMBER,
        COVER_PREMIUM_LAYER NUMBER,
        ANNUAL_PREMIUM NUMBER,
        LOADING_TYPE NUMBER,
        LOADING_NAME VARCHAR(200),
        BASIC_PREM_LOADING SMALLINT,
        LOADING_START_DATE DATE,
        LOADING_END_DATE DATE,
        LOADING_PERC NUMBER,
        LOADING_RATE NUMBER,
        LOADING_PREM NUMBER,
        PREMIUM_CALC_DESC VARCHAR(240),
        INFLATION_RATE NUMBER,
        AGENT_NUMBER NUMBER
        )';

插入语句

EXECUTE IMMEDIATE '
        INSERT INTO I233_ACTIVE_P4L_POLICY_DATA
        VALUES(
        '||m_product||',
        '||m_version||',
        '||m_plan||',
        '||policy_rec.policy_no||',
        '||m_pol_comm_date||', <----This field
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_pol_status||',
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_cover_no||',
        '''',
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''), 
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_sum_assured||',
        '||m_cover_layer||',
        '||m_cover_prem_layer||',
        '||m_premium||',
        '||m_loading_type||',
        ''TEST3'',
        '||m_basic_prem_loading||',
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_loading_perc||',
        '||m_loading_rate||',
        '||m_loading_prem||',
        ''TEST3'',
        '||m_inflation_rate||',
        '||m_agent_no||')';

错误

ORA-00917:缺少逗号

如果我尝试以相同的方式计算日期,则会出现差异错误

插入语句

EXECUTE IMMEDIATE '
        INSERT INTO I233_ACTIVE_P4L_POLICY_DATA
        VALUES(
        '||m_product||',
        '||m_version||',
        '||m_plan||',
        '||policy_rec.policy_no||',
        m_pol_comm_date, <----This field
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_pol_status||',
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_cover_no||',
        '''',
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''), 
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_sum_assured||',
        '||m_cover_layer||',
        '||m_cover_prem_layer||',
        '||m_premium||',
        '||m_loading_type||',
        ''TEST3'',
        '||m_basic_prem_loading||',
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
        '||m_loading_perc||',
        '||m_loading_rate||',
        '||m_loading_prem||',
        ''TEST3'',
        '||m_inflation_rate||',
        '||m_agent_no||')';

给我以下错误

ORA-00984:此处不允许列

在尝试使用相同的方法插入任何 VARCHAR 字段时,我也遇到了同样的问题。

有什么方法可以使用立即执行将日期/varchar 字段插入到上面创建的临时表中?

以上所有语句都包含在一个 BEGIN , END 块中

谢谢

【问题讨论】:

  • 你为什么使用动态sql而不是静态sql语句?为什么要动态创建表,而不是使用永久表(如果您只需要保留会话的结果然后将其丢弃,则可能是全局临时表 (GTT))?
  • 要诊断您的问题,您应该使用 dbms_output.put_line(或您喜欢的任何调试方法)来找出动态执行的字符串是什么。这将有助于诊断问题。但是如果我是你并且我必须使用动态 sql,我会使用绑定变量。 (您收到错误的原因可能是因为您没有在将日期连接到可执行语句之前将日期显式转换为字符串,然后将它们重新转换回语句中的日期。)

标签: oracle execute-immediate


【解决方案1】:

假设您无法避免动态 sql,请使用绑定变量。这样,您就不必担心数据类型转换等问题。

类似:

execute immediate '
    INSERT INTO I233_ACTIVE_P4L_POLICY_DATA
    VALUES(:m_product,
           :m_version,
           :m_plan,
           :policy_rec.policy_no,
           :m_pol_comm_date, <----This field
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
           :m_pol_status,
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
           :m_cover_no,
           '''',
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''), 
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
           :m_sum_assured,
           :m_cover_layer,
           :m_cover_prem_layer,
           :m_premium,
           :m_loading_type,
           ''TEST3'',
           :m_basic_prem_loading,
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
           TO_DATE(''01-01-3000'',''DD-MM-YYYY''),
           :m_loading_perc,
           :m_loading_rate,
           :m_loading_prem,
           ''TEST3'',
           :m_inflation_rate,
           :m_agent_no)'
  USING :m_product,
        :m_version,
        :m_plan,
        :policy_rec.policy_no,
        :m_pol_comm_date,
        :m_pol_status,
        :m_cover_no,
        :m_sum_assured,
        :m_cover_layer,
        :m_cover_prem_layer,
        :m_premium,
        :m_loading_type,
        :m_basic_prem_loading,
        :m_loading_perc,
        :m_loading_rate,
        :m_loading_prem,
        :m_inflation_rate,
        :m_agent_no;

【讨论】:

  • 这项工作做得很好,非常感谢我把头发拉出来
  • 这是我建议使用 q-quote 语法的第三篇文章,因为它简化了转义引号等的需要。基本上你会做类似 q'[ Your string ]'
  • @BobC 绑定变量在这种情况下甚至比引号语法更好。没有 SQL 注入的危险,自动处理不同的数据类型等
  • @Boneist 确实,假设它是面向客户的 SQL。我的评论更多的是仅供参考,您仍然可以在解决方案的第一部分使用它,这样您就可以避免转义引号。
  • 这确实是面向客户和动态的,这就是为什么我采用这种方法这只是它的基本原理,并且在变量的填充和插入之间将有很多逻辑和处理进入临时表
猜你喜欢
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-19
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
相关资源
最近更新 更多