Oracle:单个列有2个列名

时间:2018-08-16 04:20:07

标签: sql database oracle

需要重命名数据库表和列名, 因此,从源中获取数据的所有工具/应用程序都必须更改其查询。我们计划实现的解决方案是,对于每个表名更改,我们都将使用原始表名创建一个VIEW。易于实现。不需要查询更改,但是在某些情况下,表名称保持不变,但表中的列名称却更改了,因此我们无法创建另一个视图(任何具有相同对象名称的对象)。

我们可以在这里提出一种列同义词吗? 欢迎任何解决方案/想法。要求具有包含原始列名称的查询,这些查询引用相同表中的新列。

例如:

Table Name:            DATA_TABLE
Existing Column Name:  PM_DATE_TIME
New Column Name:       PM_DATETIME

现有查询select pm_Date_time from Data_Table;应该引用新列pm_Datetime

4 个答案:

答案 0 :(得分:2)

您可以考虑重命名原始表,然后在其位置创建一个提供旧列名和新列名的视图:

CREATE TABLE Data_Table ( pm_Date_time DATE );

ALTER TABLE Data_Table RENAME TO Data_Table_;

CREATE VIEW Data_Table AS
(
  SELECT pm_Date_time,
         pm_Date_time AS pm_Datetime  -- Alias to provide the new column name
  FROM Data_table_
);

-- You can use both the old columnn-name...
INSERT INTO Data_Table( pm_Date_time ) VALUES ( SYSDATE );

-- ... or the new one
UPDATE Data_Table SET pm_Datetime = SYSDATE;

有些事情不能像以前那样起作用:

-- INSERT without stating column-names will fail.
INSERT INTO Data_Table VALUES ( SYSDATE );

-- SELECT * will return both columns (should not do this anyway)
SELECT * FROM Data_Table

完成更改后,将删除视图并重命名表和列。

答案 1 :(得分:1)

您将要添加虚拟列:

ALTER TABLE Data_Table ADD pm_Date_time as (pm_Datetime);

更新:Oracle(至少11g)不接受它,并引发“ ORA-54016:指定了无效的列表达式”。请使用彼得朗(Peter Lang)的解决方案,在该解决方案中,他会伪加零天:

ALTER TABLE Data_Table ADD (pm_Datetime + 0) AS pm_Date_time;

这就像一个视图;当访问pm_Date_time时,您实际上是在访问pm_Datetime

上个月的演示:http://rextester.com/NPWFEW17776

在这一点上,彼得也很对,您可以在查询中使用它,但不能在INSERT /列或UPDATE / SET子句中使用它。

答案 2 :(得分:1)

  

我们无法创建另一个视图(任何具有相同对象名称的对象)。

在架构中确实如此。另一个有点混乱的方法是使用适当的权限创建一个新的用户/模式,并在其中创建所有视图,并在原始模式中查询已修改的表。如果您需要做的不仅仅是查询,则可以包含触发器。他们只需要使用旧的列名(作为别名),而不需要新的列名,因此未指定列的插入(当然是不好的)仍然可以使用。

如果应用程序/工具调用any并且它们的规范未更改,那么您还可以在原始模式中为包等创建同义词。如果它们已更改,则可以在新架构中创建包装程序包。

然后,您的旧版工具/应用程序可以连接到该新模式,并且如果一切都正确设置,则看起来将像以前一样。如果无法更改current_schema的连接方式或连接的帐户,则可以通过登录触发器来设置{{1}}。

随着工具和应用程序的升级以使用新的表/列名称,它们可以切换回原始模式。

答案 3 :(得分:0)

Thorsten Kettner的回答基本上提到了这一点,但是您要寻找的是伪列。

此解决方案看起来有些怪异,因为伪列的语法需要一个表达式。我能想到的最简单的表达式是下面的case语句。让我知道您是否可以使其更简单。

  ALTER TABLE <<tablename>> ADD (
   <<new_column_name>> AS (
    CASE
      WHEN 1=1 THEN <<tablename>>.<<old_column_name>>
    END)
  );

该策略基本上是通过评估case语句并将<old_column_name>的值复制到<new_column_name>来动态地创建新的列。由于您是动态插补此列,因此与选择原始列相比,性能会受到影响。

这里的一个陷阱是,仅当您重复一次列时,这才起作用。在Oracle中,多个伪列不能包含重复的表达式。