sql server实现copy data功能的存储过程(公共代码)
目标:
源表到目标表数据的复制(copy data)
在用adf的时候中间有个pipeline是做upsert工作。
这里需要调用一个存储过程,因为有很多表,所以需要写一个公用的存储过程。
参考:https://www.taygan.co/blog/2018/04/20/upsert-to-azure-sql-db-with-azure-data-factory
1 CREATE PROCEDURE proc_update //需要传入目标表的名字 2 @target_table_name varchar(200) 3 AS 4 BEGIN 5 6 DECLARE @primary_key_name varchar(50) //表主键的名字 7 DECLARE @source_table_name varchar(220) //源表的名字 8 DECLARE @upsert_sql nvarchar(max) //sql字符串 9 10 SET @source_table_name = 'shadow_' + @target_table_name //源表的名字由目标表名拼写出来 11 SET @primary_key_name = ( 12 SELECT COLUMN_NAME 13 FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 14 WHERE TABLE_NAME = @target_table_name 15 ) //获取主键名字 16 17 DECLARE @column_name_str nvarchar(max) 18 DECLARE @column_name_str_values nvarchar(max) 19 DECLARE @column_name_without_pri_key_str nvarchar(max) 20 //获取目标表列名集合并用逗号分隔。比如(id,name,age) 21 SELECT @column_name_str = name FROM ( 22 SELECT stuff( 23 ( 24 SELECT ',' + name 25 FROM sys.columns 26 WHERE object_id = object_id(@target_table_name) 27 for xml path('') 28 ), 1, 1, '') as name 29 ) as n 30 //获取源表的列集合并用逗号(,)分隔。比如(S.id,S.name,S.age) 31 SELECT @column_name_str_values = name FROM ( 32 SELECT stuff( 33 ( 34 SELECT ',S.' + name 35 FROM sys.columns 36 WHERE object_id = object_id(@target_table_name) 37 for xml path('') 38 ), 1, 1, '') as name 39 ) as n 40 //更新的时候不需要更新主键,获取update set 语句的字符串拼接(比如 T.name = S.name, T.age = S.age) 41 SELECT @column_name_without_pri_key_str = name FROM ( 42 SELECT stuff( 43 ( 44 SELECT ',T.' + name + '=' + 'S.' + name 45 FROM sys.columns 46 WHERE object_id = object_id(@target_table_name) and columns.name <> @primary_key_name 47 for xml path('') 48 ), 1, 1, '') as name 49 ) as n 50 // 这里是主要逻辑 用到了merge方法(自行查阅用法) 51 SET @upsert_sql = ' MERGE INTO ' + @target_table_name + ' AS T' + 52 ' USING (SELECT * FROM ' + @source_table_name + ' ) AS S' + 53 ' ON T.'+ @primary_key_name + ' = S.' + @primary_key_name + 54 ' WHEN MATCHED THEN' + 55 ' UPDATE SET ' + @column_name_without_pri_key_str + 56 ' WHEN NOT MATCHED THEN' + 57 ' INSERT (' + @column_name_str + ')' + 58 ' VALUES (' + @column_name_str_values + ');' + 59 ' TRUNCATE TABLE ' + @source_table_name + ';' 60 exec(@upsert_sql) 61 62 END 63 go