【问题标题】:are there any ways to create an insert statement dynamically in Oracle?有什么方法可以在 Oracle 中动态创建插入语句?
【发布时间】:2021-07-13 08:23:18
【问题描述】:

我想创建一个可以自定义列的插入语句。 首先,我为从自定义表中选择列的名称创建了一个 curosr。效果很好。

create or replace procedure PROC_TEST_DATA_INSERT
(tableNameT in varchar2)
as
columnName varchar2(30);
CURSOR C_Columns IS
  select
     COLUMN_NAME from user_tab_columns
      where table_name = tableNameT;
begin
end PROC_TEST_DATA_INSERT;

然后,我想打开游标并插入到表中,其中列的名称来自游标。但它不起作用

create or replace procedure PROC_TEST_DATA_INSERT
(tableNameT in varchar2)
as
columnName varchar2(30);
CURSOR C_Columns IS
  select
     COLUMN_NAME from user_tab_columns
      where table_name = tableNameT;
begin
open C_Columns;
   LOOP
    fetch C_Columns into
          columnName;

    insert into
    output(columnName)
    values(columnName);

    if  C_Columns%notfound then
        exit;
    end if;
  end LOOP;
  close C_Columns;
end PROC_TEST_DATA_INSERT;
call PROC_TEST_DATA_INSERT('aTableName')

然后我得到了 ORA-01732: 在此视图上的数据操作操作不合法

显然,问题出在插入语句中,因为如果我将变量更改为具体列,如名称、现有列,它可以工作。

insert into
    output(name)
    values(columnName);

有没有办法在Oracle中创建动态插入语句,还是不可能?

感谢您的回答!

【问题讨论】:

  • 您需要动态 SQL。但是,我不明白这一点。 组合 INSERT 语句没有问题,但是 - 您将在这些列中插入哪些值?所有的NULL?主键/NOT NULL 列是什么?还有什么?什么?
  • 一种更常见的方法是为每个表设置一个单独的过程,或者在过程中使用 case 语句为每个表设置一个单独的插入语句,并对主键和非空约束进行适当的测试.
  • 20 多年来,Oracle PL/SQL 有一个游标 FOR LOOP,它可以摆脱 OPEN / FETCH / IF %NOT_FOUND ... / CLOSE。我不明白为什么人们继续使用旧的、冗长且容易出错的循环。
  • @Code 也许也许我们使用相同的旧教科书 XD。我将尝试用新的 for 循环替换所有旧循环。感谢您的帮助!

标签: oracle oracle10g


【解决方案1】:

为此使用动态查询。动态查询可以通过两种方式执行。

  1. 立即执行
  2. DBMS_SQL.EXECUTE (dynamic_sql_string) - 它提供了更多的功能和对 EXECUTE IMMEDIATE 的控制,我们可以解析传入的表名和列名。
create or replace procedure PROC_TEST_DATA_INSERT (tableNameT in varchar2)
as
begin
    if(tableNameT='table1')then
          EXECUTE IMMEDIATE 'Insert Into '|| tableNameT ||' (col1,col2) values(123,''abc'')';
    end if;
    
    if(tableNameT='table2')then
          EXECUTE IMMEDIATE 'Insert Into '|| tableNameT ||' (col1,col2,col3) values(123,''abc'',456)';
    end if;
end;

【讨论】:

  • 非常感谢,我试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2015-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-04
  • 1970-01-01
相关资源
最近更新 更多