SQL Server:使用select更改某些值时复制表中的行*

SQL Server:使用select更改某些值时复制表中的行*,sql,tsql,insert,sql-server-2014,insert-update,Sql,Tsql,Insert,Sql Server 2014,Insert Update,我需要在表中插入一个几乎重复的行,同时更改几个值 例如,插入具有新id的重复行我不希望自动id和不同的名称,但所有其他值都相同。 问题是我需要做出选择* 我知道有一种方法可以通过选择插入并通过这种方式更改值: insert into Table1(id,name,surname) select newid(),'David',surname from Table1 where id=1 但我不想登记所有字段,而是希望使用select*,这样,如果添加了字段,就不必更改存储过程 我想要像这样的东

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

例如,插入具有新id的重复行我不希望自动id和不同的名称,但所有其他值都相同。 问题是我需要做出选择*

我知道有一种方法可以通过选择插入并通过这种方式更改值:

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*始终包含id列


通常,除了交互式查询外,您应该避免在任何地方选择*。编译存储过程时,查询文本将被解析并替换为正确的列,从而使存储过程在每次更改结构时都无效。

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

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

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

INSERT INTO Table1 SELECT * FROM #temp;
请注意,当客户端断开与DB服务器的连接时,临时表会自动删除

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


示例:

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

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

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

INSERT INTO Table1 SELECT * FROM #temp;
请注意,当客户端断开与DB服务器的连接时,临时表会自动删除

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

示例:

我使用的代码:

    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
我使用的代码是:

    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

在查询中使用*是一种不好的做法。因此,如果你开始遵循最佳实践,你将一箭双雕……我知道这通常是一种不好的实践,但如果字段将添加到我的表中,我将不得不更改我的sp。因为我们这里有许多sp,这些新字段肯定会被遗忘。在查询中使用*是一种不好的实践。因此,如果你开始遵循这一最佳做法,你将一箭双雕……我知道这通常是一种不好的做法,但如果字段将添加到我的表中,我将不得不更改我的sp。因为我们这里有许多sp,这些新字段肯定会被遗忘。这就是为什么我想在选择上插入一个更新,这就是我想更改的原因以某种方式在选择上插入更新创建表的开销是什么?有关应使用哪种临时表类型的详细信息,请参阅以下帖子:。创建表的开销是什么?有关应使用哪种临时表类型的详细信息,请参阅以下帖子:。