简体   繁体   English

Oracle:单个列的 2 个列名

[英]Oracle : 2 column names for a single column

There is a requirement to rename the DB tables and column names, so all the tools/application taking data from the source will have to change their queries.需要重命名数据库表和列名称,因此所有从源获取数据的工具/应用程序都必须更改它们的查询。 The solution we are planning to implement is that for every table name change we will create a VIEW with the original table name.我们计划实施的解决方案是,对于每个表名更改,我们将使用原始表名创建一个 VIEW。 Easy and simple to implement.易于实施。 No query change required, but there are cases where a table name remains the same but a column name changes within the table, so we can't create another view (any object with the same object name).不需要更改查询,但在某些情况下,表名保持不变,但表内的列名发生变化,因此我们无法创建另一个视图(具有相同对象名的任何对象)。

Is there a Column Synonym kind of thing which we can propose here?有没有我们可以在这里提出的列同义词? Any solutions/ideas are welcome.欢迎任何解决方案/想法。 Requirement is to have queries containing original column names referring to the new columns in the same tables.要求是查询包含引用相同表中新列的原始列名。

For example:例如:

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

Existing Query select pm_Date_time from Data_Table; Existing Query select pm_Date_time from Data_Table; should refer to new column pm_Datetime应参考新列pm_Datetime

You could consider renaming your original table, and then create a View in its place providing both the old and the new column-names:您可以考虑重命名原始表,然后在其位置创建一个视图,提供旧列名和新列名:

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;

There are things that won't work the same way as before:有些事情不会像以前一样工作:

-- 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

Once you are done with your changes drop the view and rename the table and the columns.完成更改后,删除视图并重命名表和列。

You'll want to add virtual columns:您需要添加虚拟列:

ALTER TABLE Data_Table ADD pm_Date_time as (pm_Datetime);

UPDATE: Oracle (11g at least) doesn't accept this and raises "ORA-54016: Invalid column expression was specified".更新: Oracle(至少 11g)不接受这一点并引发“ORA-54016:指定了无效的列表达式”。 Please use Peter Lang's solution, where he pseudo-adds zero days:请使用 Peter Lang 的解决方案,他在其中伪添加了零天:

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

This works like a view;这就像一个视图; when accessing pm_Date_time you are really accessing pm_Datetime .访问pm_Date_time您实际上是在访问pm_Datetime

Rextester demo: http://rextester.com/NPWFEW17776 Reextester 演示: http ://rextester.com/NPWFEW17776

And Peter is also right in this point that you can use it in queries, but not in INSERT/columns or UPDATE/SET clauses. Peter 在这一点上也是正确的,您可以在查询中使用它,但不能在 INSERT/columns 或 UPDATE/SET 子句中使用它。

This was basically touched on in the answer by Thorsten Kettner, but what your looking for is a pseudocolumn.这基本上在 Thorsten Kettner 的回答中有所涉及,但是您要寻找的是伪列。

This solution looks a little hacky because the syntax for a pseudocolumn requires an expression.这个解决方案看起来有点老套,因为伪列的语法需要一个表达式。 The simplest expression I can think of is the case statement below.我能想到的最简单的表达方式是下面的 case 语句。 Let me know if you can make it more simple.如果你能让它更简单,请告诉我。

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

This strategy basically creates a new column on the fly by evaluating the case statement and copying the value of <old_column_name> to <new_column_name> .该策略基本上通过评估 case 语句并将<old_column_name>的值复制到<old_column_name><new_column_name>创建一个新列。 Because you are dynamically interpolating this column there is a performance penalty vs just selecting the original column.因为您正在动态插入此列,所以与仅选择原始列相比,性能会有所下降。

One gotcha here is that this will only work if you are duplicating a column once.这里的一个问题是,这仅在您复制一列时才有效。 Multiple pseudocolumns cannot contain duplicate expressions in Oracle. Oracle 中的多个伪列不能包含重复的表达式。

we cant create a another view (any object with the same object name).我们不能创建另一个视图(具有相同对象名称的任何对象)。

That's true within a schema.在模式中确实如此。 Another somewhat messy approach is to create a new user/schema with appropriate privileges and create all your views in that, with those querying the modified tables in the original schema.另一种有点混乱的方法是创建一个具有适当权限的新用户/模式,并在其中创建所有视图,并在原始模式中查询修改后的表。 You could include instead-of triggers if you need to do more than query.如果您需要做的不仅仅是查询,您可以包含替代触发器。 They would only need the old columns names (as aliases), not the new ones, so inserts that don't specify the columns (which is bad, of course) would still work too.他们只需要旧的列名(作为别名),而不是新的列名,所以不指定列的插入(当然这是不好的)仍然可以工作。

You could also create synonyms to packages etc. in the original schema if the applications/tools call any and their specifications haven't changed.如果应用程序/工具调用 any 并且它们的规范没有改变,您还可以在原始模式中创建包等的同义词。 And if they have changed you can create wrapper packages in your new schema.如果它们发生了变化,您可以在新模式中创建包装器包。

Then your legacy tools/applications can connect to that new schema and if it's all set up right will see things apparently as they were before.然后,您的旧工具/应用程序可以连接到该新模式,如果一切设置正确,将会看到看起来像以前一样的东西。 That could potentially be done by setting current_schema , perhaps through a login trigger, if the way they connect or the account they connect to can't be modified.如果无法修改连接方式或连接到的帐户,则可能通过设置current_schema来完成,可能是通过登录触发器。

As the tools and applications are upgraded to work with the new table/column names they can switch back to the original schema.随着工具和应用程序升级以使用新的表/列名称,它们可以切换回原始模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM