Sab*_*lfy 4 postgresql database-design
我有foo一个表中命名的列。我在脚本中构建了查询,使用这个名称。
我现在想将表中的列重命名为bar. 这将破坏脚本(有几个,但如有必要,可以更改它们)。该表被其他表引用。我想重命名,因为该列中存储的内容的上下文已更改。
一个列可以有两个名称吗?
我将假设您的表已命名baz并在架构中public
create table baz (
foo text primary key
);
insert into baz (foo) values ('hello');
select foo from baz;
Run Code Online (Sandbox Code Playgroud)
现在您要重命名该列:
alter table baz rename column foo to bar;
Run Code Online (Sandbox Code Playgroud)
但是现在您的脚本已损坏:
select foo from baz; -- nope!
Run Code Online (Sandbox Code Playgroud)
因此,创建一个新模式,在其中放置一个视图,然后更改您search_path以隐藏视图“后面”的表。
create schema qux;
create or replace view qux.baz as
select
bar as foo
from public.baz;
set search_path to qux, public;
select foo from baz; -- works!
Run Code Online (Sandbox Code Playgroud)
这是一种 postgres 的方式 create synonym
根据您在脚本中具体执行的操作,有多种方法可以解决该问题。我将SELECT仅出于此答案的目的而假设。但是INSERT, UPDATE,DELETE也是可能的...
VIEWAVIEW将是一个选项,就像@Andriy 评论的那样。如果您需要将当前表保持原样,事情会变得更加复杂,但仍有可能。您可以在 schema 中表的 schema 之前列出的另一个 schema 中使用同名的aVIEW屏蔽该表search_path。实际上,我曾多次这样做以保留更新数据库模式后无法适应的接口。
基本示例代码:
CREATE SCHEMA override;
CREATE VIEW override.tbl AS
SELECT *, foo AS bar -- to add the column a second time
-- tbl_id, foo AS bar -- to replace the column
FROM tbl;
Run Code Online (Sandbox Code Playgroud)
仅授予USAGE架构上的权限public以避免滥用:
GRANT USAGE ON SCHEMA override TO public;
Run Code Online (Sandbox Code Playgroud)
将override作为第一个模式放入您search_path的原始查询中,“神奇地”包含另一列。如果您不想弄乱人们的search_path,您可以在每个会话开始时在脚本中动态执行此操作:
DO
$$BEGIN
EXECUTE (SELECT 'SET search_path = override,' || setting
FROM pg_catalog.pg_settings WHERE name = 'search_path');
END$$;
Run Code Online (Sandbox Code Playgroud)
这对于 SQL 注入是安全的,因为子查询返回一个有效的搜索路径。
屏蔽函数的类似用例:
TEMPORARY VIEW或者您可以创建一个临时视图来屏蔽表:
CREATE TEMP VIEW tbl AS
SELECT *, foo AS bar FROM tbl;
Run Code Online (Sandbox Code Playgroud)
临时对象仅在同一个会话中可见并随之消亡。
您可能需要为INSERT, UPDATE,做更多的事情DELETE。大多数实用程序命令 (DML) 不能像那样被愚弄。
Postgres没有生成列本身,但可以使用的功能,看起来和作品就像一个:
CREATE TABLE tbl (tbl_id int, foo text);
INSERT INTO tbl VALUES (1, 'hello');
CREATE FUNCTION bar(tbl) RETURNS text LANGUAGE sql STABLE AS 'SELECT $1.foo';
SELECT *, t.bar
FROM tbl t;
Run Code Online (Sandbox Code Playgroud)
详细解释:
| 归档时间: |
|
| 查看次数: |
1829 次 |
| 最近记录: |