Sql server 为了减少工作和错误,我们称之为“提高效率”,而不是“懒惰”。干得好。@kuru在某些情况下我不太确定。这里没有太多的键入操作,只需从对象资源管理器中拖动列列表即可。并且在代码中显式列出列名可以防止以后在表结构更改(添加列等)时调试噩梦。你可以说相反的说法是
Sql server 为了减少工作和错误,我们称之为“提高效率”,而不是“懒惰”。干得好。@kuru在某些情况下我不太确定。这里没有太多的键入操作,只需从对象资源管理器中拖动列列表即可。并且在代码中显式列出列名可以防止以后在表结构更改(添加列等)时调试噩梦。你可以说相反的说法是,sql-server,sql-server-2008,Sql Server,Sql Server 2008,为了减少工作和错误,我们称之为“提高效率”,而不是“懒惰”。干得好。@kuru在某些情况下我不太确定。这里没有太多的键入操作,只需从对象资源管理器中拖动列列表即可。并且在代码中显式列出列名可以防止以后在表结构更改(添加列等)时调试噩梦。你可以说相反的说法是正确的(例如,一列被删除),但前者是一种更常见的情况。@Aaron——OP问。。。我倾向于分享你关于列出来的好处的一般技术观点,但无论如何,这是对TSQL的一般批评(例如,为什么它允许你在某些情况下不列出来,并迫使你在其他情况下列出来),而不是
为了减少工作和错误,我们称之为“提高效率”,而不是“懒惰”。干得好。@kuru在某些情况下我不太确定。这里没有太多的键入操作,只需从对象资源管理器中拖动列列表即可。并且在代码中显式列出列名可以防止以后在表结构更改(添加列等)时调试噩梦。你可以说相反的说法是正确的(例如,一列被删除),但前者是一种更常见的情况。@Aaron——OP问。。。我倾向于分享你关于列出来的好处的一般技术观点,但无论如何,这是对TSQL的一般批评(例如,为什么它允许你在某些情况下不列出来,并迫使你在其他情况下列出来),而不是对OP的个人批评。此外,在某些情况下,您提到的问题不会带来风险——我们无法从OP提供的有限信息中得知。头脑发热的垃圾(HLGEM称OP为懒惰和不专业,只是为了问问题)在任何方面都不是建设性的。@kuru我同意,我只是不同意这样的概括,即少打字总是能提高效率。是的,在某些情况下这是正确的,但也有一些情况下,你只是将付款推迟到稍后,稍后可能是凌晨3点,因为部署导致系统停机。当然,我对脚本进行了更多的自定义,但这太棒了!6年后,这仍然在帮助人们。。
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])
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
--Two statement run as transaction batch
DELETE
C
FROM
productschina C
JOIN
(select * from productschina c except select * from productsus) z
on c.productid=z.productid
INSERT into productschina select * from productsus except select * from productschina
--Create a target table
--drop table ProductsUS
CREATE TABLE ProductsUS
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100),
Rate MONEY
)
GO
--Insert records into target table
INSERT INTO ProductsUS
VALUES
(1, 'Tea', 10.00),
(2, 'Coffee', 20.00),
(3, 'Muffin', 30.00),
(4, 'Biscuit', 40.00)
GO
--Create source table
--drop table productschina
CREATE TABLE ProductsChina
(
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100),
Rate MONEY
)
GO
--Insert records into source table
INSERT INTO ProductsChina
VALUES
(1, 'Tea', 10.00),
(2, 'Coffee', 25.00),
(3, 'Muffin', 35.00),
(5, 'Pizza', 60.00)
GO
SELECT * FROM ProductsUS
SELECT * FROM ProductsChina
GO
DELETE
C
FROM
productschina C
JOIN
(select primary_key, last_mod_date from productschina c except select primary_key, last_mod_date from productsus) z
on c.productid=z.productid
INSERT into productschina select * from productsus except select * from productschina