是否可以使用同一个表中其他列组合的列来创建表?

时间:2015-03-09 15:58:39

标签: sql database postgresql

我知道问题很长,我知道如果有人没有时间阅读,但我真的希望有办法做到这一点。

我正在编写一个程序,它将从数据库目录表中读取数据库模式,并使用从系统目录中提取的信息自动构建一个基本应用程序。

数据库中的许多表只能是表单项的列表

CREATE TABLE tablename (id INTEGER PRIMARY KEY, description VARCHAR NOT NULL);

所以当一个表有一个引用id tablename的列时,我只需通过description表中的查询解析tablename,然后显示一个列表中包含可用选项的组合框。

但有些表不能直接有description列,因为它们的描述是其他列的组合,让我们以第一个应用程序中最重要的那些表为例

CREATE TABLE bankaccount (
    bankid INTEGER NOT NULL REFERENCES bank,
    officeid INTEGER NOT NULL REFERENCES bankoffice,
    crc INTEGER NOT NULL,
    number BIGINT NOT NULL
);
很多人都知道,这将是一个银行账户的完整账号,在我的国家,它的组成如下

[XXXX][XXXX][XX][XXXXXXXXXX]
  ^      ^    ^    ^
bank id  |   crc   account number 
         |
         |_ bank office id 

这就是我的bankaccount表的结构方式的原因。

现在,我希望将完整的银行帐号放在description列中,以便我可以在应用程序中显示它而不对此情况进行特殊处理,因为还有其他一些类似情况的表,就像是

CREATE TABLE bankaccount (
    bankid INTEGER NOT NULL REFERENCES bank,
    officeid INTEGER NOT NULL REFERENCES bankoffice,
    crc INTEGER NOT NULL,
    number BIGINT NOT NULL, 
    description VARCHAR DEFAULT bankid || '-' || officeid || '-' || crc || '-' || number
);

由于引发了以下错误 1 ,这当然不起作用

ERROR:  cannot use column references in default expression

如果有人可以提出任何不同的方法,请随时将其作为答案。


1 这是PostgreSQL给出的错误信息。

2 个答案:

答案 0 :(得分:3)

您想要的是在桌面上创建视图。我对MySQL和SQLite比较熟悉,请原谅这些差异。但基本上,如果您有表'AccountInfo',您可以拥有一个视图'AccountInfoView',它有点像'存储查询',但可以像表一样使用。您可以使用

之类的东西创建它
CREATE VIEW AccountInfoView AS 
SELECT *, CONCATENATE(bankid,officeid,crc,number) AS FullAccountNumber 
FROM AccountInfo

另一种方法是在原始表中包含一个实际的FullAccountNumber列,并创建一个触发器,在您对表执行插入或更新时设置它。但这通常效率较低,因为它会复制存储并在写入数据而不是检索数据时降低性能。但有时候这种方法才有意义。

答案 1 :(得分:2)

实际上有什么用,我相信这是一个非常优雅的解决方案,就是使用像这样的功能

CREATE FUNCTION description(bankaccount) RETURNS VARCHAR AS $$   
    SELECT
        CONCAT(bankid, '-', officeid, '-', crc, '-', number)
    FROM
        bankaccount this
    WHERE
        $1.bankid = this.bankid AND
        $1.officeid = this.officeid AND
        $1.crc = this.crc AND
        $1.number = this.number
$$ LANGUAGE SQL STABLE;

然后将像这样使用

SELECT bankaccount.description FROM bankaccount;

因此,我的目标已实现。

注意:此解决方案仅适用于PostgreSQL AFAIK。