gpt4 book ai didi

sql-server - SQL Server 2008 中不指定列名的 MERGE

转载 作者:行者123 更新时间:2023-12-02 07:26:28 24 4
gpt4 key购买 nike

我正在查看 MERGE 命令,它看起来很酷,但仍然需要指定列。我正在寻找类似的东西:

MERGE INTO target AS t
USING source AS s
WHEN MATCHED THEN
UPDATE SET
[all t.fields = s.fields]
WHEN NOT MATCHED THEN
INSERT ([all fields])
VALUES ([all s.fields])

可能吗?

最佳答案

我很懒...这是我编写的一个便宜的过程,它将吐出表的通用 MERGE 命令。它查询 information_schema.columns 中的列名。我撕掉了我的源数据库名称 - 所以,你必须更新过程才能使用你的数据库(寻找@SourceDB ...我说它很便宜。)无论如何,我知道其他人可以写得更好 - 它为我服务目的很好。 (它做了几个假设,您可以将逻辑放入处理中 - 即关闭 IDENTITY_INSERT - 即使表没有标识列。)它会在当前上下文中更新表。它是针对 sql server 2008 编写的,用于同步一些表。当然,使用风险由您自行承担。

    CREATE PROCEDURE [dbo].[GenerateMergeSQL]
@TableName varchar(100)
AS
BEGIN
SET NOCOUNT ON

declare @sql varchar(5000),@SourceInsertColumns varchar(5000),@DestInsertColumns varchar(5000),@UpdateClause varchar(5000)
declare @ColumnName varchar(100), @identityColName varchar(100)
declare @IsIdentity int,@IsComputed int, @Data_Type varchar(50)

declare @SourceDB as varchar(200)


-- source/dest i.e. 'instance.catalog.owner.' - table names will be appended to this
-- the destination is your current db context
set @SourceDB = '[mylinkedserver].catalog.myDBOwner.'

set @sql = ''
set @SourceInsertColumns = ''
set @DestInsertColumns = ''
set @UpdateClause = ''
set @ColumnName = ''
set @isIdentity = 0
set @IsComputed = 0
set @identityColName = ''
set @Data_Type = ''


DECLARE @ColNames CURSOR
SET @ColNames = CURSOR FOR
select column_name, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IsIdentity ,
COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsComputed') as IsComputed , DATA_TYPE
from information_schema.columns where table_name = @TableName order by ordinal_position

OPEN @ColNames
FETCH NEXT FROM @ColNames INTO @ColumnName, @isIdentity, @IsComputed, @DATA_TYPE

WHILE @@FETCH_STATUS = 0
BEGIN
if @IsComputed = 0 and @DATA_TYPE <> 'timestamp'
BEGIN
set @SourceInsertColumns = @SourceInsertColumns +
case when @SourceInsertColumns = '' THEN '' ELSE ',' end +
'S.' + @ColumnName

set @DestInsertColumns = @DestInsertColumns +
case when @DestInsertColumns = '' THEN '' ELSE ',' end +
@ColumnName

if @isIdentity = 0
BEGIN
set @UpdateClause = @UpdateClause +
case when @UpdateClause = '' THEN '' ELSE ',' end
+ @ColumnName + ' = ' + 'S.' + @ColumnName + char(10)
END

if @isIdentity = 1 set @identityColName = @ColumnName
END

FETCH NEXT FROM @ColNames INTO @ColumnName, @isIdentity, @IsComputed, @DATA_TYPE
END

CLOSE @ColNames
DEALLOCATE @ColNames

SET @sql = 'SET IDENTITY_INSERT ' + @TableName + ' ON;
MERGE ' + @TableName + ' AS D
USING ' + @SourceDB + @TableName + ' AS S
ON (D.' + @identityColName + ' = S.' + @identityColName + ')
WHEN NOT MATCHED BY TARGET
THEN INSERT(' + @DestInsertColumns + ')
VALUES(' + @SourceInsertColumns + ')
WHEN MATCHED
THEN UPDATE SET
' + @UpdateClause + '
WHEN NOT MATCHED BY SOURCE
THEN DELETE
OUTPUT $action, Inserted.*, Deleted.*;
SET IDENTITY_INSERT ' + @TableName + ' OFF'

Print @SQL

END

关于sql-server - SQL Server 2008 中不指定列名的 MERGE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7326061/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com