sql:插入分布在多个表上的对象

sql:插入分布在多个表上的对象,sql,Sql,例如,已经有文章指出,SQL中的“幼稚”继承,即每个类级别使用一个表,是一件常见的事情。范例 create table parent ( id integer primary key , more-parent-attributes ); create table child ( id integer primary key references parent(id) on delete cascade , more-child-attributes ); 我的问题只是如何以惯用的ANSI

例如,已经有文章指出,SQL中的“幼稚”继承,即每个类级别使用一个表,是一件常见的事情。范例

create table parent
( id integer primary key
, more-parent-attributes
);

create table child
( id integer primary key references parent(id) on delete cascade
, more-child-attributes
);
我的问题只是如何以惯用的ANSI SQL方式插入一个子对象 坐到桌子上。外键约束要求我们首先 使用id将新行插入父级
中,然后将新行插入子级

父行
的。我不知道如何安全、便携地完成(获取此id),以及 只使用一个请求。 提示:我是一个初学者,不懂命令式SQL编程——只是简单而已
案例中有一个明显的强制解决方案。

您必须执行两个insert

父表中的第一个insert add行,子表中的第二个insert add行

两个插入操作可以在同一事务中分组

要在父表中获取正确的插入id,必须从父表中获取select id

显示如下:

步骤1:

INSERT INTO parent (id, more att) values (your ID, other values)
注意ID值,可以使用newid()(Sql server)uuid()(mySql)或自动增量整数字段

步骤2:

您可以使用功能键查询父表来检索键

SELECT id FROM parent where functional_key satisfacted
例如,如果我在父表中存储员工列表,则功能键可以是register number

因此,您的查询变成:

SELECT id FROM parent WHERE register_no = 'YOUR_REGISTER_NUMBER'
步骤3:

INSERT INTO child (id, fk_parent, other fields) values(id, fk_parent, other fields)
fk_父字段的值必须与步骤2的结果一致

在此步骤中,您可以:

值fk_parent与一个变量,或者您可以在insert语句中使用子查询(步骤2)。

Scope_Identity()是您需要的:

DECLARE @Id INT

INSERT INTO parent (more-parent-attributes) values (.....)
SET @Id = Scope_Identity()

INSERT INTO child (parent(id), more-child-attributes) SELECT @Id, ....more-child-attributes
Scope_Identity()返回同一作用域中的标识列。这意味着父项应为标识列:

id  int IDENTITY(1,1)PRIMARY KEY

我认为这种情况就像你决定什么是父密钥id一样,你会在子插入中使用相同的id。

我最后做了类似的事情。您需要有一些可插入父项的标识数据,以便获得
Id
。如果您在某种应用程序中使用它,那么您可以使用
GUID
。在我的应用程序中,我使用了源列的串联,我知道这些列将产生唯一的值

CREATE TABLE Parent
(
     Id INT IDENTITY NOT NULL PRIMARY KEY
    ,SourceId VARCHAR(50) NOT NULL
);

CREATE TABLE Child
(
     ParentId INT NOT NULL REFERENCES Parent (Id)
    ,Data VARCHAR(20)
);

-- Some procedure inserts the unique value
INSERT INTO Parent (SourceId) VALUES ('UNIQUE VALUE');

-- Another procedure inserts data using the unique value
DECLARE @Id INT;

SELECT @Id = Id FROM Parent WHERE SourceId = 'UNIQUE VALUE';

INSERT INTO Child (ParentId, Data) VALUES (@Id, 'Some Data');

您可能需要在单个事务中包装多个SQL语句。2插入同一事务(1为父事务,1为子事务)如何可靠地获取插入的
父行的id?你能提供具体的代码吗?如果这是一个愚蠢的问题,很抱歉。如果在最后一个insert语句中附加
输出
-子句,则可以从该语句中获取插入的值。请参见此处的一些示例:在一个数据库上开发并打算稍后移动到另一个数据库,这是一个非常糟糕的想法。ANSII sql不能很好地处理许多对数据库性能至关重要的任务。如果您正在创建一个必须支持多个后端的COTS产品,那么您就别无选择(这就是为什么我曾经不喜欢支持的所有COTS数据库都非常慢的原因之一)。您要做的是一件特定于数据库的事情,并且始终只特定于数据库。您不能编写ansii代码来实现这一点,因为没有标准的实现。您能提供具体的代码吗?有没有一种安全的方法可以准确地获取插入的
父行的id?如果我没有弄错(?),那么这与@Romoku提出的方法是一样的(并且受到同样的限制)。@Jo So:是的,同样。我也有这个想法,但我并不特别喜欢它,因为:这是一种黑客行为。可能不容易产生唯一的值。它占用空间的唯一原因就是让黑客成为可能。我以前见过多次使用这种模式。它可能感觉不真实,但在大多数情况下它都能完成任务,尤其是当应用程序不带状态时。正如您所知,在较新版本的SQL Server中,output子句是比scope_identity更好的选择。Scope_identity有一个关于并行性的bug,他们不打算修复(因为我怀疑他们希望您使用相反的输出)。谢谢@HLGEM知道这一点很好。我不知道这件事。我使用Scope_Identity()处理带有许多触发器的数据库,从来没有遇到过问题,但在谷歌搜索之后,我发现输出是更好的选择,正如您所建议的。Scope_Identity是在输出之前使用的方法,这可能是在编写这些内容时使用的方法。除非您使用并行,否则它工作正常。但新的发展应该利用产出