需要重命名数据库表和列名, 因此,从源中获取数据的所有工具/应用程序都必须更改其查询。我们计划实现的解决方案是,对于每个表名更改,我们都将使用原始表名创建一个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
答案 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中,多个伪列不能包含重复的表达式。