SQL 服务器:table 中的重复行,同时使用 select 更改某些值*

SQL Server : Duplicate row in table while changing some values with select *

我需要在 table 中插入一个几乎重复的行,同时更改一些值。

例如,插入具有新 ID(我不想要自动 ID)和不同名称但所有其他值相同的重复行。 问题是我需要做一个 select *

我知道有一种方法可以从 select 插入并以这种方式更改值:

insert into Table1(id,name,surname) select newid(),'David',surname from Table1 where id=1

但我不想征集所有字段,而是想使用 select *,所以如果添加了字段,我就不必更改我的存储过程。

我想要这样的东西:

insert into Table1 (
   update (SELECT *
          FROM Table1
          WHERE  id= 1  ) t 
    set t.id= newid(),name='David')

有办法吗?

不,因为 SELECT * 将始终包含 id 列。

一般来说,你应该避免在任何地方使用 SELECT *,除非是交互式查询。编译存储过程时,查询文本将被解析并替换为正确的列,从而使您的存储过程在每次结构更改时都无效。

您可以使用临时哈希 table 来完成此操作。

SELECT *
INTO #temp 
FROM Table1
WHERE id= 1;

UPDATE #temp 
  SET ID = newid(),
      Name='David'

INSERT INTO Table1 SELECT * FROM #temp;

请注意,当客户端与数据库服务器断开连接时,#temp table 会自动删除。

此外,如前所述,我更喜欢单独使用列名而不是 *。

示例:SQL Fiddle

我使用的代码:

    declare @table sysname
declare @excludecols nvarchar(max)
declare @uniqueWhereToCopy nvarchar(max)
declare @valuesToChange nvarchar(max)

--copy settings
set @table = 'orsrg' --the tablename
set @excludecols='' --columnnames to exclude from the copy, seperated by commas
set @uniqueWhereToCopy = 'ID=1188'
set @valuesToChange = 'regel=''   4''' --columnName=<value>,columnName2=<value2>, .... (needed for unique indexes)

set @excludecols=@excludecols + ','
set @valuesToChange=@valuesToChange + ','

--get the columnnames to copy
declare @sqlcolumns nvarchar(max)
set @sqlcolumns = ''
SELECT @sqlcolumns = @sqlcolumns + name from
    (select '[' + c.name + '], ' as name FROM sys.COLUMNS c inner join sys.objects o
        on c.object_id = o.object_id 
    WHERE o.name = @table
    and is_identity = 0 /*exclude identity*/
    and is_rowguidcol = 0 /*exclude rowguids*/
    and is_computed = 0 /*exclude computed columns*/
    and system_type_id <> 189 /*exclude timestamp*/
    and charindex(c.name, @excludecols,1) = 0 /*exclude user specified columns*/)q

--get the select columns and values
declare @sqlselectvalues nvarchar(max)
set @sqlselectvalues = @sqlcolumns
while len(@valuesToChange)>1
begin
    declare @colValueSet nvarchar(max)
    declare @colname sysname
    declare @value nvarchar(max)
    set @colValueSet = left(@valuesToChange,charindex(',',@valuesToChange,1)-1)
    set @valuesToChange = substring(@valuesToChange,charindex(',',@valuesToChange,1)+1,len(@valuesToChange))
    set @colname = '[' + left(@colValueSet,charindex('=',@colValueSet,1)-1) +']'
    set @value = substring(@colValueSet,charindex('=',@colValueSet,1)+1,len(@colValueSet))

    set @sqlselectvalues = REPLACE(@sqlselectvalues,@colname,@value)
end

--remove the last comma
set @sqlcolumns = left(@sqlcolumns, len(@sqlcolumns)-1)
set @sqlselectvalues = left(@sqlselectvalues, len(@sqlselectvalues)-1)

--create the statement
declare @stmt nvarchar(max)
set @stmt = 'Insert into ' + @table + '(' + @sqlcolumns + ') select ' + @sqlselectvalues + ' from ' + @table + ' with (nolock) where ' + @uniqueWhereToCopy
--copy the row
exec sp_executesql @stmt