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

时间:2012-03-31 17:14:23

标签: 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;

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

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

INSERT INTO employees_usa VALUES (emp_id, name, 1000);

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

INSERT INTO employees_germany VALUES (emp_id, name, 1000);

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

INSERT INTO employees_france VALUES (emp_id, name, 1000);

等...

有没有办法在PL / SQL中通过替换employee_???来代替这样做,所以只使用了一行INSERT代码?或者以最佳方式使用caseif/then/else语句?

2 个答案:

答案 0 :(得分: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;

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

正确规范化数据库并将国家/地区添加到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 )
    );

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

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;

答案 1 :(得分:1)

您可以使用动态SQL和EXECUTE IMMEDIATE构造。在此,您将查询构造为字符串,然后执行它。一个很好的例子是http://docs.oracle.com/cd/B10500_01/appdev.920/a96590/adg09dyn.htm