给出以下SQL(MS SQL 2008):
SET IDENTITY_INSERT MyTable ON
GO
INSERT INTO MyTable
SELECT * FROM MyTable
WHERE Id = @SomeId
GO
SET IDENTITY_INSERT MyTable OFF
这会导致:
An explicit value for the identity column in table 'MyTable' can only be specified when a column list is used and IDENTITY_INSERT is ON.
那么,我真的需要定义列列表吗?有没有办法保持通用?例如。如果开发人员稍后添加了一个列,则此列不会进入此例程,如果不允许null,它甚至会失败...
答案 0 :(得分:26)
嗯,实际上有一种更通用的方式,这在不知道列的情况下运行良好:
DECLARE @Tablename NVARCHAR(255) = 'MyTable'
DECLARE @IdColumn NVARCHAR(255) = 'MyTableId' -- Primarykey-Column, will be ignored
DECLARE @IdToCopyFrom VARCHAR(255) = '33' -- Copy from this ID
DECLARE @ColName NVARCHAR(255)
DECLARE @SQL NVARCHAR(MAX) = ''
DECLARE Table_Cursor CURSOR FOR
SELECT [B].[Name]
FROM SYSOBJECTS AS [A], SYSCOLUMNS AS [B]
WHERE [A].[ID] = [B].[ID] AND A.name = @Tablename
OPEN Table_Cursor
FETCH NEXT FROM Table_Cursor INTO @ColName
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- Loop through all columns and link them into the Sql-string (except the PK-column)
DECLARE @SkipComma BIT = 0
IF (@ColName <> @IdColumn)
SET @SQL = @SQL + @ColName
ELSE
SET @SkipComma = 1
FETCH NEXT FROM Table_Cursor INTO @ColName
IF (@SkipComma = 0 AND @@FETCH_STATUS = 0)
SET @SQL = @SQL + ','
END
CLOSE Table_Cursor
DEALLOCATE Table_Cursor
SET @SQL = 'INSERT INTO ' + @Tablename + '(' + @SQL + ')' +
' SELECT ' + @SQL + ' FROM ' + @Tablename +
' WHERE ' + @IdColumn + ' = ' + @IdToCopyFrom
PRINT @SQL
EXEC(@SQL)
干杯!
答案 1 :(得分:16)
我不是MS-SQL用户,但在我使用过的所有其他数据库中,我从未见过一种不涉及手动列出所有列但自动增加列的方法。
insert into mytable (some, columns, but, not, the, id)
select some, columns, but, not, the, id from mytable where id = someid
答案 2 :(得分:2)
答案 3 :(得分:0)
一个很大的帮助是在SQL-Manager中使用自动脚本创建程序:
在我的案例中有超过60列,编写每一个列都很痛苦。所以,右键单击表并选择: “脚本表为” - &gt; “选择” - &gt; “新查询窗口”