Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL添加新的NOTNULL列并用insert语句中的ID填充_Sql_Postgresql - Fatal编程技术网

PostgreSQL添加新的NOTNULL列并用insert语句中的ID填充

PostgreSQL添加新的NOTNULL列并用insert语句中的ID填充,sql,postgresql,Sql,Postgresql,我有两张桌子 CREATE TABLE content ( id bigserial NOT NULL, name text ); CREATE TABLE data ( id bigserial NOT NULL, ... ); 表格中已经填入了大量数据。 现在我想向数据表添加一个新的列content_id(非NULL)。 它应该是内容表的外键 是否可以在内容表中自动创建条目以在数据表中设置内容id 比如说 **content** | id | name | |

我有两张桌子

CREATE TABLE content (
  id bigserial NOT NULL,
  name text
);


CREATE TABLE data (
    id bigserial NOT NULL,
    ...
);
表格中已经填入了大量数据。 现在我想向数据表添加一个新的列content_id(非NULL)。 它应该是内容表的外键

是否可以在内容表中自动创建条目以在数据表中设置内容id

比如说

**content**
| id | name |
|  1 | abc  | 
|  2 | cde  |
数据

| id |... |
| 1  |... |
| 2  |... |
| 3  |... |
| id |... | content_id |
| 1  |... | 3          |
| 2  |... | 4          |
| 3  |... | 5          |
现在,我需要一个update语句来创建3个(在本例中)内容条目,并将ID添加到数据表中以获得此结果:

内容

| id | name |
|  1 | abc  |
|  2 | cde  |
|  3 | ...  |
|  4 | ...  |
|  5 | ...  |
数据

| id |... |
| 1  |... |
| 2  |... |
| 3  |... |
| id |... | content_id |
| 1  |... | 3          |
| 2  |... | 4          |
| 3  |... | 5          |

根据这里给出的答案:,有几种方法可以添加新的
notnull
列并直接填充

基本上有3个步骤。选择最佳拟合(带或不带事务,先设置默认值,然后删除,先保留
非NULL
约束,然后添加,…)


步骤1:添加新列(无
非空
约束,因为此时新列值的值不可用)

步骤2:将数据插入一行中的两个表中:

WITH inserted AS (                -- 1
    INSERT INTO content
    SELECT
        generate_series(
            (SELECT MAX(id) + 1 FROM content),
            (SELECT MAX(id) FROM content) + (SELECT COUNT(*) FROM data)
        ),
        'dummy text'
    RETURNING id
), matched AS (                   -- 2
   SELECT
       d.id AS data_id,
       i.id AS content_id
   FROM (
       SELECT
           id,
           row_number() OVER ()
       FROM data
   ) d 
   JOIN (
      SELECT
          id,
          row_number() OVER ()
      FROM inserted
   ) i ON i.row_number = d.row_number
)                                 -- 3
UPDATE data d
SET content_id = s.content_id
FROM (
    SELECT * FROM matched
) s
WHERE d.id = s.data_id;
使用前一条语句的结果依次执行多条语句可以通过以下方法实现:

  • 将数据插入
    content
    表:这将生成一个整数序列,从当前
    内容的
    id
    值的
    MAX()+1
    值开始,并具有与
    数据
    表一样多的记录。然后返回新的
    id
    s
  • 现在我们需要将数据表的当前记录与新ID匹配。因此,对于两侧,我们使用为每个记录生成一个连续的行计数。因为插入结果和实际的
    数据
    表都有相同数量的记录,所以这可以用作联接条件。因此,我们可以将
    data
    表的
    id
    列与新的
    content
    id
    值相匹配
  • 此匹配数据可用于新
    内容\u id
    列的最终更新
  • 步骤3:添加
    非空
    约束

    ALTER TABLE data ALTER COLUMN content_id SET NOT NULL;
    

    内容id
    的值
    3,4,5
    来自何处?逻辑是什么?这能回答你的问题吗?这是一个自动生成的ID。答案不起作用,因为我在例句中间对语句进行了断言:一些工作(根据需要设置实际值)…您必须准确描述您想要做的事情。如何找到正确的内容id?还是只想添加随机数据?对于表数据中的每个现有条目,我需要向表内容添加新行,并将新内容条目中自动生成的id添加到现有数据条目中。