通過子查詢進行UPDATE
目的:更新父表的欄位值,且要更新其子表的相關欄位值(備註:沒有在子表上建外來鍵)。
方法:先建個臨時表(和父表的資料一模一樣,也可以看成是父表的備份表),然後根據子查詢進行UPDATE。
示例:
父表:test.dbo.dept
子表:test.dbo.emp
父表,子表查詢結果:
步驟:
1:檢視哪些子表用到了test.dbo.dept的deptno
可以通過這個儲存過程:
--儲存過程建立語句(這是我同事寫的)
USE [DBA]
GO
/****** Object: StoredProcedure [JCW].[Find_Column_Data] Script Date: 2014/2/19 14:04:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
/*
查詢全伺服器中使用到此列名的表及是否有表值的資訊
20130716
江成威
*/
CREATE PROC [JCW].[Find_Column_Data]
(
@ColumnName nvarchar(200),
@Data nvarchar(max)=NULL
)
AS
begin
CREATE TABLE #NCTables
(
Num INT IDENTITY(1,1),
TableFullName NVARCHAR(500),
HasColumnData BIT DEFAULT 0
)
DECLARE @SS nvarchar(max)='
use ?;
INSERT INTO #NCTables
( TableFullName, HasColumnData )
SELECT ''[?].[''+S.name+''].[''+T.name+'']'',0 FROM sys.columns C INNER JOIN sys.tables T ON C.object_id=T.object_id INNER JOIN sys.schemas S ON S.schema_id=T.schema_id WHERE C.name='''[email protected]+''';
'
EXEC sys.sp_MSforeachdb @SS
--SELECT * FROM #NCTables
--DROP TABLE #NCTables
DECLARE @Num int =(SELECT MAX(Num) from #NCTables)
DECLARE @TBName NVARCHAR(500)
DECLARE @SQL NVARCHAR(max)
DECLARE @where NVARCHAR(max) = (CASE WHEN @Data IS NULL THEN '' ELSE ' where '[email protected]+'='''[email protected]+'''' END)
WHILE @Num>0
BEGIN
SELECT @TBName=TableFullName FROM #NCTables WHERE [email protected]
SET @SQL='if (select count(0) from '[email protected]+' '[email protected]+')>=1
begin
update #NCTables set HasColumnData=1 where Num='''+cast(@Num AS nvarchar(20))+'''
end
'
PRINT @sql
EXEC (@sql)
SET @[email protected]
END
SELECT * FROM #NCTables
END
GO
--執行儲存過程EXEC DBA.JCW.Find_Column_Data @ColumnName = N'deptno', -- nvarchar(200) 欄位名稱
@Data = N'' -- nvarchar(max) 欄位值
--結果:
test.dbo.emp
--2 對這兩個表進行備份:
USE dba;
SELECT *
INTO dept_bak_bdd_201402191726
FROM TEST.DBO.DEPT;
SELECT *
INTO emp_bak_bdd_201402191726
FROM TEST.DBO.EMP
--3 更新dept表
UPDATE dept
SET deptno=40
WHERE deptno=30;
--4 根據子查詢更新emp
UPDATE TEST.DBO.EMP
SET deptno=c.deptno
--SELECT A.deptno,c.deptno,B.dNAME
FROM TEST.DBO.EMP A
INNER JOIN DBA.dbo.dept_bak_bdd_201402191726 B ON B.deptno=A.deptno
INNER JOIN TEST.DBO.DEPT C ON B.dName=C.dNAME
--5 驗證
SELECT *
FROM test.dbo.EMP;
所有deptno為30的現都已改成了40.