sql:插入分布在多个表上的对象
例如,已经有文章指出,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
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是在输出之前使用的方法,这可能是在编写这些内容时使用的方法。除非您使用并行,否则它工作正常。但新的发展应该利用产出