如何以编程方式在PL/SQL中设置表名?

ggk*_*ath 1 oracle plsql

我创建了以下简单的PL/SQL存储过程示例来询问特定问题.此过程将员工姓名和ID号插入到名为的表中employees_???.??? 解释如下.

PROCEDURE hire_employee (emp_id IN INTEGER, name IN VARCHAR2, country IN VARCHAR2) 
AS
BEGIN
    INSERT INTO employees_??? VALUES (emp_id, name, 1000);
END hire_employee;
Run Code Online (Sandbox Code Playgroud)

我需要的是根据IN变量设置表名country.例如,

如果country ='usa',我希望INSERT行读取:

INSERT INTO employees_usa VALUES (emp_id, name, 1000);
Run Code Online (Sandbox Code Playgroud)

如果country ='germany',我希望INSERT行读取:

INSERT INTO employees_germany VALUES (emp_id, name, 1000);
Run Code Online (Sandbox Code Playgroud)

如果country ='france',我希望INSERT行读取:

INSERT INTO employees_france VALUES (emp_id, name, 1000);
Run Code Online (Sandbox Code Playgroud)

等等...

有没有办法在PL/SQL中通过替换代替一些东西来执行此操作,employee_???因此只使用一行INSERT代码?或者使用caseif/then/else声明最好的方式?

Ben*_*Ben 7

要回答您的问题,您必须execute immediate动态使用和创建语句.

create or replace procedure hire_employee (
        emp_id IN INTEGER
      , name IN VARCHAR2
      , country IN VARCHAR2 ) is

   -- maximum length of an object name in Oracle is 30
   l_table_name varchar2(30) := 'employees_' || country;

begin
    execute immediate 'insert into ' || l_table
                       || ' values (:1, :2, 1000)'
      using emp_id, name;
end hire_employee;
Run Code Online (Sandbox Code Playgroud)

然而,这是一种大规模过于复杂的数据存储方式.如果要选择所有数据,则必须合并大量表.

将数据库正确规范化并将国家/地区添加到employees表中会好得多.

类似于以下内容:

create table employees (
    emp_id number(16)
  , country varchar2(3) -- ISO codes
  , name varchar2(4000) -- maximum who knows what name people might have
  , < other_columns >
  , constraint pk_employees primary key ( emp_id )
    );
Run Code Online (Sandbox Code Playgroud)

然后您的过程变成一个非常简单的插入语句:

create or replace procedure hire_employee (
       emp_id in integer
     , name in varchar2
     , country in varchar2 ) is

    insert into employees
    values ( emp_id, country, name, 1000 );

end hire_employee;
Run Code Online (Sandbox Code Playgroud)