【发布时间】:2019-01-27 11:06:17
【问题描述】:
以前在发帖时我错过了包含 urn 和 org_ref 的表 b。我有三张桌子。表a,b和c,我必须根据表a中的URN键更新表c的“total Emp”列。表 B 没有 URN 列,但它有 Org_ref,因此要连接表 a 和表 c,我们需要在 a.urn=b.urn 上连接表 b。我已经编写了一个查询来遍历记录并执行插入或更新,但它不工作并且不更新。只需在表 b 中插入空白的“员工总数”即可。
表一个
|urn |total employee
|333 |25
|123 |26
|21 |2
|11 |23
表 B
|urn |org_ref
|333 |1234
|123 |343
|21 |2
|11 |23
表 C
org_ref total employe
1234 0 --should update from table a
343 0 --should update from table a
--add record from table a org_ref 21
--add record from table a org_ref 11
这是我的脚本
Create table #orgs(
iorgrowid int identity (1,1),
ORG_REF varchar(255),
Total_Leader int,
urn int
)
insert into #orgs
select ORG.organisation_ref,s.[TOTAL_LEADERSHIP_ROLE],s.urn
from DiTestDatabase.dbo.organisation org
JOIN DataConversion.dbo.School_plus_download_NI s on org.total_headcount=s.urn
DECLARE
@iReturnCode int,
@iNextcodeRowId int,
@icodeRowId int,
@iCurrentcodeRowId int,
@iNextattRowId int,
@iCurrentattRowId int,
@icodeLoopControl int,
@ORGREF INT,
@counter int,
@Ly_employees int,
@orgnamecount int,
@add1count int,
@urn int
SELECT @iCodeLoopControl = 1
SELECT @iNextCodeRowId = MIN(iorgrowId)
FROM #orgs
IF ISNULL(@iNextCodeRowId,0) = 0
BEGIN
SELECT 'No data in found in table!'
RETURN
END
SELECT
@iCurrentcodeRowId = iorgrowId,
@ORGREF=ORG_REF,
@Ly_employees=Total_Leader,
@urn=urn
FROM #orgs
WHERE iorgRowId = @iNextcodeRowId
set @counter = 0
set @orgnamecount=0
set @add1count=0
--Start the main processing loop.
WHILE @iCodeLoopControl = 1
BEGIN
begin
set @counter = @counter + 1
print 'The counter is ' + cast(@counter as char) + cast(@ORGREF as char)
end
IF EXISTS (SELECT OG.ORGANISATION_REF
FROM ORG_ACCOUNT OG WHERE OG.ORGANISATION_REF= @ORGREF
)
BEGIN
UPDATE ORG_ACCOUNT
SET LY_EMPLOYEES= (SELECT SP.TOTAL_LEADERSHIP_ROLE
FROM DataConversion.dbo.School_plus_download_NI SP
JOIN ORGANISATION ORG ON ORG.TOTAL_HEADCOUNT=SP.URN
JOIN ORG_ACCOUNT OA ON OA.ORGANISATION_REF=ORG.ORGANISATION_REF
WHERE OA.ORGANISATION_REF=@ORGREF)
FROM DataConversion.dbo.School_plus_download_NI SP WHERE SP.URN=@urn
END
ELSE
BEGIN
alter table ditestdatabase.dbo.org_account disable trigger all
INSERT INTO ORG_ACCOUNT
(ORGANISATION_REF,LY_TURNOVER,LY_PROFIT,LY_REMUN,LY_EMPLOYEES,PY_TURNOVER,PY_PROFIT,PY_REMUN,PY_EMPLOYEES,UK_TURNOVER,UK_PROFIT,UK_REMUN,UK_EMPLOYEES,CREATED_BY,
CREATE_TIMESTAMP,UPDATED_BY,UPDATE_TIMESTAMP,PY_POT_SUB,LY_POT_SUB,LY_DATE,PY_DATE,UK_DATE)
VALUES(@ORGREF,NULL,NULL,NULL,@Ly_employees,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,null,GETDATE(),null,null,null,null,null,null,null)
set @orgref=(select organisation_ref from DiTestDatabase.dbo.ORG_ACCOUNT where ORGANISATION_REF=@ORGREF)
end
alter table ditestdatabase.dbo.org_account enable trigger all
SELECT @iNextCodeRowId = NULL
--Get the next iRowId.
SELECT @iNextcodeRowId = MIN(iorgrowId)
FROM #orgs
WHERE iorgrowId > @iCurrentcodeRowId
--Did we get a valid next row id?
IF ISNULL(@iNextCodeRowId,0) = 0
BEGIN
BREAK
END
SELECT @iCurrentcodeRowId = iorgrowId,
@ORGREF=ORG_REF,
@Ly_employees=Total_Leader
FROM #orgs
WHERE iorgRowId = @iNextcodeRowId
END
DROP TABLE #orgs
RETURN
解决方案:- 由于表 a 和 c 之间没有任何共同点,因此我必须借助表 b,其中 a 和 b 之间唯一的共同点是 URN 列,b 和 c 之间唯一共同的列是 Org_ref。我已将我的更新更改为
SET LY_EMPLOYEES= (SELECT SP.TOTAL_LEADERSHIP_ROLE
FROM DataConversion.dbo.School_plus_download_NI SP
JOIN ORGANISATION ORG ON ORG.TOTAL_HEADCOUNT=SP.URN
JOIN ORG_ACCOUNT OA ON OA.ORGANISATION_REF=ORG.ORGANISATION_REF
WHERE sp.URN = @urn) --@ORGREF)
FROM ORG_ACCOUNT WHERE ORGANISATION_REF=@ORG_REF
解决了这个问题。
谢谢大家
【问题讨论】:
-
阅读
Merge -
这是我的查询。
-
代码是以非常程序化的编程方式编写的,而不是更适合数据库的基于集合的方式。 Abhishek 将您指向
Merge声明是正确的。此外,我认为您需要解释/考虑那些 BEGIN TRANSACTION 行,以及您打算何时/何地提交?在插入之前禁用触发器然后启用触发器似乎也很可疑。 -
@Andrew 是的,我的背景是核心 C#,作为反映我的查询的应用程序开发人员。我不得不禁用触发器以加快进程,每个表包含超过 3 个触发器。
-
我忘记了我有 3 张桌子而不是 2 张。我已经更新了我的问题,请查看我的朋友们。
标签: sql sql-server database sql-server-2008 tsql