SQL插入使用另一个插入的记录

时间:2015-01-21 22:57:18

标签: sql sql-server tsql sql-server-2005

我有3个表,如下:

tblAgentVisit (VisitID auto-increments)
VisitID (PK) | StatusID | A bunch of other columns
--------------------------------------------------
1            | 1        | etc.
2            | 1        | etc.

tblAgentVisitAgents
VisitID | AgtID | Prime
-----------------------
1       | 8507  | 1
2       | 56    | 1

tblAgentVisitLoad
AgtID
-----
2077
3068
432

每个季度,我们都会占据代理商的前20%,并将其ID加载到tblAgentVisitLoad

我需要为表中的每个代理创建一个新的,唯一的访问。我需要INSERT我的StatusID和其他列到tblAgentVisit,获取自动递增的VisitID(使用OUTPUT?),然后INSERT VisitID,AgtID和Prime = 1进入{{ 1}}。同样,每次访问都必须对每个代理都是唯一的。

理想情况下,这就是我完成表格后的表格:

tblAgentVisitAgents

任何人都有在MS SQL Server 2005中这样做的建议吗?我完全难过了。

1 个答案:

答案 0 :(得分:0)

我有两个可能的解决方案。第一种方法用一些空间换一种稍微简单的方法,第二种方法更复杂但总体上可能更好。

使用OUTPUT也是一种替代方法,但它需要将赋值写入临时表(因为接收表不能有约束),然后从那里写入tblAgentVisitAgents。这是另一个问题,详细说明了如何做到这一点:

How can I INSERT data into two tables simultaneously in SQL Server?

解决方案1:为第一个业务代表分配使用临时字段。

首先,在创建每次访问时,向FirstAgentID添加一列(例如tblAgentVisit),以暂时存储指定的代理:

ALTER TABLE tblAgentVisit ADD FirstAgentID int NULL;

如果您使用的是MSSQL 2008或更高版本,则可以使此列为SPARSE,因此任何NULL记录都不占用空间,但这在2005年不可用。但是,希望额外的NULL int列不会成为问题对你而言。

接下来,创建新的访问记录,临时存储您要为每次访问分配的代理:

INSERT INTO tblAgentVisit(Status, ..., FirstAgentID)
SELECT ..., AgtId FROM tblAgentVisitLoad;

现在,使用新的访问记录(及其临时FirstAgentID)来创建为每次新访问分配相应代理的子记录:

INSERT INTO tblAgentVisitAgents(VisitID, AgtID, Prime)
SELECT VisitID, FirstAgentID, 1
FROM tblAgentVisit
WHERE FirstAgentID IS NOT NULL;

最后,将临时字段置空,这样就不会产生任何潜在的混淆或重复数据:

UPDATE tblAgentVisit
SET FirstAgentID=NULL
WHERE FirstAgentID IS NOT NULL;

解决方案#2:使用CTE和ROW_NUMBER()按顺序位置分配对座席的新访问。

我相信您也可以使用CTE和ROW_NUMBER()在两个语句中执行此操作,而无需上述临时字段:

INSERT INTO tblAgentVisit(Status, ...) blah;

WITH a AS (
   SELECT AgtId, ROW_NUMBER() OVER(ORDER BY AgtId ASC) AS row
   FROM tblAgentVisitLoad
), b AS (
   SELECT VisitID, ROW_NUMBER() OVER(ORDER BY VisitID ASC) AS row
   FROM tblAgentVisit
   WHERE NOT EXISTS(SELECT NULL FROM tblAgentVisitAgents c WHERE
      c.VisitID = tblAgentVisit.VisitID
)
INSERT INTO tblAgentVisitAgents(VisitID, AgtID, Prime)
SELECT b.VisitID, a.AgtID, 1
FROM a, b
WHERE a.row = b.row;

这将利用以下事实:INSERT之后没有分配代理的唯一访问是新访问。如果在其他情况下访问可能没有任何相应的tblAgentVisitAgents记录,则您需要以某种方式过滤CTE b以仅包含新创建的访问。