【问题标题】:How to programmatically set table name in PL/SQL?如何以编程方式在 PL/SQL 中设置表名?
【发布时间】:2021-01-05 17:23:18
【问题描述】:

我创建了以下简单的 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_??? 来做到这一点,所以只使用一行代码来插入?还是使用caseif/then/else 语句是最好的方法?

【问题讨论】:

  • 您的数据库模型已完全损坏。您应该只有一个表employee,其中有一列名为country。与其解决这个错误模型所带来的问题,不如立即重新设计它。
  • 是的,我同意——这只是一个示例,用于弄清楚如何将 IN 参数添加到 pl/sql 中的变量名上。
  • 那么这是一个非常不好的例子。
  • 请提供一个真实描述您要完成的工作的示例。
  • 好的,我在这里创建了一个新问题:stackoverflow.com/questions/9959799/…

标签: oracle plsql


【解决方案1】:

要回答您的问题,您必须使用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_name
                       || ' 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;

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-13
      • 2011-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多