2012-03-31 47 views
1

我创建了以下简单的PL/SQL存储过程示例来询问具体问题。此过程将员工姓名和身份证号码插入名为employees_???的表格中。该???在下面解释。如何以编程方式在PL/SQL中设置表名称?

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设置表名。例如,

如果国家= '美国',我想INSERT行改为:

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

如果国家= '德国',我想INSERT行改为:

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

如果国家= '法国',我想INSERT行改为:

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

等等

有没有办法在地方employee_???的INSERT的代码,所以只有一行代的东西做在PL/SQL使用?或者正在使用caseif/then/else声明的最佳方式?

+2

你的DB模式是完全打破。你应该只有一个名为'country'的列表'employee'。你应该立即重新设计它,而不是去解决你用这个错误模型得到的问题。 – 2012-03-31 17:24:01

+1

是的,我同意 - 这只是一个创建例子,想知道如何将IN参数放到pl/sql中的变量名上。 – ggkmath 2012-03-31 17:27:54

+3

然后这是一个非常糟糕的例子。 – 2012-03-31 17:29:25

回答

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; 
相关问题