我的SQL语句将是什么?插入“Arnold Schwarzenegger”并且“Hasta la vista baby”进入这两个空的SQL表?

我的声明是将“Arnold Schwarzenegger”和“Hasta la vista baby”插入以下空SQL表中? 这个问题的标题最初是“如何将第一条记录插入到具有双向关联和自动生成的整数PK的SQL表中?”但我不确定我是否正确地说这个......基本上,我有两张桌子
Actors
CatchPhrases
Actors
看起来像:
  ActorId                  int             NOT NULL  PK (autogenerated by db)
  FavoriteCatchPhraseId    int             NOT NULL  FK
  Name                     varchar(200)    NOT NULL
CatchPhrases
看起来像:
  CatchPhraseId            int             NOT NULL  PK (autogenerated by db)
  ActorId                  int             NOT NULL  FK
  PhraseText               varchar(500)    NOT NULL
因此,演员可以有多个短语,但必须至少有一个。一个口号与一个演员相关联。两个表中目前都没有数据。     
已邀请:
我会以不同的方式对其进行建模以避免双向关系(这很难做到)。只需在CatchPhrases表中添加一列(IsFavorite)即可。在代码中使用约束或业务规则来将标记为每个actor的最爱的catch短语的数量限制为一个。 演员:
ActorId                  int             NOT NULL  PK (autogenerated by db)
Name                     varchar(200)    NOT NULL
口头禅:
CatchPhraseId            int             NOT NULL  PK (autogenerated by db)
ActorId                  int             NOT NULL  FK
PhraseText               varchar(500)    NOT NULL
IsFavorite               bit             NOT NULL
确保你在CatchPhrases表的ActorId上有一个索引,这样你就可以快速找到actor的catch短语。 或者,使用连接表 - 这将允许多个actor具有相同的口号。 演员:
ActorId                  int             NOT NULL PK (autogenerated by db)
Name                     varchar(200)    NOT NULL
ActorCatchPhrases
ActorId                  int             NOT NULL PK (FK to Actors)
CatchPhraseId            int             NOT NULL PK (FK to CatchPhrases)
IsFavorite               bit             NOT NULL
口头禅
PhraseId                 int             NOT NULL PK (autogenerated by db)  
PhraseText               varchar(500)    NOT NULL
    
规则,即父记录必须至少有一个子记录,不能使用声明性参照完整性来强制执行。 “收藏夹”是单数,因此FavoriteCatchPhrase可以简单地是Actor实体的属性,即Actors表中的列。您可以存储短语的文本。但是如果你想强制执行这样的规则,即最喜欢的口号必须来自一组真正的捕捉短语,经过审查并被承认真正“吸引人”的短语,而不仅仅是一些不那么令人难忘的说法,那么你有一个CatchPhrases表,你可以让Actor.FavoriteCatchPhrase存储短语id和引用CatchPhrases表作为外键,虽然多个actor可以使用相同的标语,除非你在Actor.FavoriteCatchPhrase上放置一个唯一的索引。     
我认为你可以通过使用'脏读'(读取未提交)在事务中执行此操作。 但即使可能,它也不是很好。 正如@tvanfosson建议最干净的方法是关闭CatchPhrases表的ActorId列上的FK。 首先创建一个虚拟CatchPhrases(设置标识插入)行,如: 0 - 0 - '没有最喜欢的标语',0 然后,当您要插入Actors行时,默认使用: (身份) - 0 - '阿诺德·施瓦辛格' 然后将变量设置为Actors插入将生成的@@ identity值 然后是标语: (身份) - (变量) - 'Hasta la vista baby' 然后将变量设置为CatchPhrases插件将生成的@@ identity值,并使用它来更新actors行中的catchphrase id。 ......嗯,你确定这个设计是对的吗? 编辑 好吧,如果我们可以改变设计...... 看看这些关系,Actors可以有很多Catchphrases和Catchphrases可以有很多Actors。所以有一个多对多的设计 - 通常使用链接实体重构(MSDN称之为联结表):
Actors   
  |
-----
| | |
ActorsCatchphrases
| | |
-----
  |
Catchphrases
Actors有Actor Name和Actor的详细信息(没有引用catchphrases) ActorsCatchphrases有ActorId和CatchphraseId以及它是否是该演员最喜欢的布尔值 Catchphrases有标语的细节(没有参考演员)     
我可能会这样做:
USE     tempdb
;
CREATE  TABLE
        dbo.Actors
        (
        ActorId         INTEGER IDENTITY PRIMARY KEY,
        Name            VARCHAR(200) NOT NULL UNIQUE
        )
;
CREATE  TABLE 
        dbo.CatchPhrases
        (
        CatchPhraseId   INTEGER IDENTITY UNIQUE,
        ActorId         INTEGER NOT NULL REFERENCES dbo.Actors,
        PhraseText      VARCHAR(500) NOT NULL,

        PRIMARY KEY (CatchPhraseId, ActorId)
        )
;
CREATE  TABLE 
        dbo.ActorFavouritePhrase
        (
        ActorId         INTEGER NOT NULL REFERENCES dbo.Actors,
        CatchPhraseId   INTEGER NOT NULL,

        FOREIGN KEY (CatchPhraseId, ActorId) 
            REFERENCES dbo.CatchPhrases (CatchPhraseId, ActorId),

        PRIMARY KEY (ActorId, CatchPhraseId),
        UNIQUE (CatchPhraseId, ActorId)
        )
GO
CREATE  INDEX [dbo.CatchPhrases ActorId]
ON      dbo.CatchPhrases (ActorId)
GO
DECLARE @ActorId    TABLE (Id INTEGER NOT NULL);
DECLARE @PhraseId   TABLE (Id INTEGER NOT NULL)
;
BEGIN   TRANSACTION
;
INSERT  dbo.Actors 
        (Name)
OUTPUT  inserted.ActorId
INTO    @ActorId (Id)
VALUES  ('Arnold Schwarzenegger')
;
DECLARE @AID INTEGER = (SELECT Id FROM @ActorId)
;
INSERT  dbo.CatchPhrases
        (ActorId, PhraseText)
OUTPUT  inserted.CatchPhraseId
INTO    @PhraseId (Id)
VALUES  (@AID, 'Hasta la vista, baby')
;
DECLARE @PID INTEGER = (SELECT Id FROM @PhraseId)
;
INSERT  dbo.ActorFavouritePhrase
        (ActorId, CatchPhraseId)
VALUES  (@AID, @PID)
;
COMMIT  TRANSACTION
GO
DROP    TABLE
        dbo.ActorFavouritePhrase,
        dbo.CatchPhrases,
        dbo.Actors
;
    

要回复问题请先登录注册