我有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中这样做的建议吗?我完全难过了。
答案 0 :(得分:0)
我有两个可能的解决方案。第一种方法用一些空间换一种稍微简单的方法,第二种方法更复杂但总体上可能更好。
使用OUTPUT
也是一种替代方法,但它需要将赋值写入临时表(因为接收表不能有约束),然后从那里写入tblAgentVisitAgents
。这是另一个问题,详细说明了如何做到这一点:
How can I INSERT data into two tables simultaneously in SQL Server?
首先,在创建每次访问时,向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;
我相信您也可以使用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
以仅包含新创建的访问。