Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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
使用Npgsql的PostgreSQL主数据详细事务处理_Sql_Postgresql_Npgsql - Fatal编程技术网

使用Npgsql的PostgreSQL主数据详细事务处理

使用Npgsql的PostgreSQL主数据详细事务处理,sql,postgresql,npgsql,Sql,Postgresql,Npgsql,假设我有这些桌子: CREATE TABLE master master_id serial, master_desc character varying CREATE TABLE details details_masterrefid int, details_desc character varying CONSTRAINT master_detail_fkey(details_masterrefid) REFERENCES master(master_id) MATCH SIMPLE

假设我有这些桌子:

CREATE TABLE master 
master_id serial, 
master_desc character varying

CREATE TABLE details
details_masterrefid int,
details_desc character varying
CONSTRAINT master_detail_fkey(details_masterrefid)
REFERENCES master(master_id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION
然后我在C#中有一个代码,它基本上会首先将头插入主表,然后循环遍历细节并将其插入细节表

通过这样做,我必须先插入到主表,然后提交事务,如果事务成功,则获取ID并使用它在细节表中插入。现在,问题是,如果细节中出现了错误,并且插入没有成功,我想回滚插入到主表上的数据。但既然已经承诺了,我就不能收回。要么全是,要么什么都不是。主表和明细表


我能想到的唯一解决方案是允许详细信息中的外键字段为空,然后如果一切都成功,则将外键字段更新为其各自的值。有没有关于如何做得更好的建议?我不知道这是否是一个有效的解决方案。

您可以使用单语句
CTE

WITH ins1 AS (
  INSERT INTO master (cols...)
  VALUES (..)                            -- insert into master
  RETURNING master_id                    -- get generated id
)
INSERT INTO details (...)
SELECT master_id, ...                    -- insert into child table
FROM ins1;


另一种方法是使用单个事务包装所有内容:

BEGIN TRAN

INSERT INTO master ...

INSERT INTO child ...

COMMIT;

这样,您将获得全部或无行为。

您可以使用单个语句
CTE

WITH ins1 AS (
  INSERT INTO master (cols...)
  VALUES (..)                            -- insert into master
  RETURNING master_id                    -- get generated id
)
INSERT INTO details (...)
SELECT master_id, ...                    -- insert into child table
FROM ins1;


另一种方法是使用单个事务包装所有内容:

BEGIN TRAN

INSERT INTO master ...

INSERT INTO child ...

COMMIT;

这样,您将获得要么全有,要么全无的行为。

是否有什么东西阻止您在一个事务中包装两个表上的所有插入内容?问题是,我不能。由于外键问题,在详细信息中插入数据时将发生错误。由于标头的ID尚未提交。是否有什么东西阻止您在一个事务中包装两个表上的所有插入?问题是,我不能。由于外键问题,在详细信息中插入数据时将发生错误。因为标头的ID还没有提交。正如我所说的。我正在使用NPGSQL。因此,控制事务是在C#@Bigboss中完成的,所以请使用第一种方法。正如我所说的一个声明(全部或全部)。我正在使用NPGSQL。因此,控制事务是在C#@Bigboss中完成的,所以请使用第一种方法。一个语句(全部或无)