我的代码:
SELECT * INTO #t FROM CTABLE WHERE CID = @cid --get data, put into a temp table
ALTER TABLE #t
DROP COLUMN CID -- remove primary key column CID
INSERT INTO CTABLE SELECT * FROM #t -- insert record to table
DROP TABLE #t -- drop temp table
错误是:
Msg 8101,
An explicit value for the identity column in table 'CTABLE' can only
be specified when a column list is used and IDENTITY_INSERT is ON.
我确实设置了
SET IDENTITY_INSERT CTABLE OFF
GO
答案 0 :(得分:9)
DECLARE
@cid INT,
@o INT,
@t NVARCHAR(255),
@c NVARCHAR(MAX),
@sql NVARCHAR(MAX);
SELECT
@cid = 10,
@t = N'dbo.CTABLE',
@o = OBJECT_ID(@t);
SELECT @c = COALESCE(@c, '') + ',' + QUOTENAME(name)
FROM sys.columns
WHERE [object_id] = @o
AND is_identity = 0;
SELECT @c = STUFF(@c, 1, 1, '');
SET @sql = 'SELECT ' + @c + ' INTO #t
FROM ' + @t + ' WHERE CID = ' + RTRIM(@cid) + ';
INSERT ' + @t + '('+ @c + ')
SELECT ' + @c + ' FROM #t;'
PRINT @sql;
-- exec sp_executeSQL @sql;
但是,构建以下SQL并完全避免使用#temp表似乎要容易得多:
SET @sql = 'INSERT ' + @t + '(' + @c + ')
SELECT ' + @c + ' FROM ' + @t + '
WHERE CID = ' + RTRIM(@cid);
PRINT @sql;
-- exec sp_executeSQL @sql;
答案 1 :(得分:4)
试试这个:
SELECT * INTO #t FROM CTABLE WHERE CID = @cid
ALTER TABLE #t
DROP COLUMN CID
INSERT CTABLE --Notice that INTO is removed here.
SELECT top(1) * FROM #t
DROP TABLE #t
测试脚本(在SQL 2005中测试):
CREATE TABLE #TestIDNT
(
ID INT IDENTITY(1,1) PRIMARY KEY,
TITLE VARCHAR(20)
)
INSERT #TestIDNT
SELECT 'Cybenate'
答案 2 :(得分:1)
尝试指定列:
INSERT INTO CTABLE
(col2, col3, col4)
SELECT col2, col3, col4
FROM #t
似乎可能认为您正在尝试插入PK字段,因为您没有明确定义要插入的列。如果Identity插件已关闭且您指定了非pk列,那么您不应该收到该错误。
答案 3 :(得分:1)
这是一个动态构建列列表的示例 - 不包括主键列 - 并执行INSERT
declare @tablename nvarchar(100), @column nvarchar(100), @cid int, @sql nvarchar(max)
set @tablename = N'ctable'
set @cid = 1
set @sql = N''
declare example cursor for
select column_name
from information_schema.columns
where table_name = @tablename
and column_name not in (
select column_name
from information_schema.key_column_usage
where constraint_name in (select constraint_name from information_schema.table_constraints)
and table_name = @tablename
)
open example
fetch next from example into @column
while @@fetch_status = 0
begin
set @sql = @sql + N'[' + @column + N'],'
fetch next from example into @column
end
set @sql = substring(@sql, 1, len(@sql)-1)
close example
deallocate example
set @sql = N'insert into ' + @tablename + '(' + @sql + N') select top(1) ' + @sql + ' from #t'
--select @sql
exec sp_executesql @sql
答案 4 :(得分:0)
尝试使用EXEC调用INSERT语句:
SELECT * INTO #t FROM CTABLE WHERE CID = @cid
ALTER TABLE #t
DROP COLUMN CID
EXEC('INSERT INTO CTABLE SELECT top(1) * FROM #t')
DROP TABLE #t
答案 5 :(得分:0)
你不能这样做:
INSERT INTO CTABLE SELECT top(1) * FROM #t
因为列列表不一样。您已从#t中删除了PK列,因此#t中的列少于CTABLE中的列。这相当于以下内容:
INSERT INTO CTABLE(pk, col1, col2, col3, ...)
select top(1) col1, col2, col3, ...
from #t
由于显而易见的原因,这不起作用。同样,如果您没有插入所有列,则无法指定*通配符来执行插入操作。在不包含PK的情况下执行插入的唯一方法是指定每列。您可以通过动态sql生成列列表,但是您必须以这种或那种方式指定它们。
答案 6 :(得分:0)
如果使用SQL Server Management Studio和您的问题,除了标识列之外,您有太多字段无法输入它们,请右键单击该表并单击“脚本表为”/“选择到”/“新建查询窗口”。
这将提供您可以复制的字段列表。粘贴到您自己的查询中,然后只删除标识列。