【问题标题】:SQL Server Insert Into Table containing a column "Timestamp (Rowversion)"SQL Server 插入到包含列“时间戳(行版本)”的表中
【发布时间】:2020-12-17 17:28:58
【问题描述】:

我正在为工业环境中的配方管理创建一个 C# Winforms 应用程序。

我创建了一个包含 130 列的 SQL Server 表。该表包含一个名为CheckData(数据类型为Timestamp)的列,我用它来检测对一行所做的更改。

如果我在该表中插入新行,一切正常。我使用的代码是:

INSERT INTO tablename (Column1, column2, column3, column4) 
VALUES (value1, value2, value3, value4)

我只是为主要列分配值,其他列获得它们的默认值。我没有为时间戳字段赋值,因为它是由系统编写的。

另外,我想从这个表中复制一行到同一个表中(复制一条数据记录)。

我将源行复制到临时表,删除该临时表中的 ID(主键)和时间戳字段,并尝试将临时表中的唯一行插入到表中。这失败了。

代码如下:

SELECT * 
INTO #temptable 
FROM tablename 
WHERE Recipe_No = 8;

ALTER TABLE #temptable DROP COLUMN ID, CHECKDATA;

ALTER TABLE #temptable REBUILD;

UPDATE #temptable 
SET Recipe_No = 9, Recipe_Name = 'Test' 
WHERE Recipe_No = 8;

INSERT INTO tablename 
    SELECT * FROM #temptable;

我不明白通过INSERT INTO xxx (yyy) VALUES (zzz)INSERT INTO xxx SELECT * FROM yyy 插入新行之间的区别在哪里。在这两种情况下,我都不会尝试在新行中写入时间戳值。

有人知道我在这里缺少什么吗?

【问题讨论】:

  • 什么失败了?你有几笔交易在这里进行。有什么错误吗?
  • INSERT INTO 失败。

标签: sql sql-server insert timestamp


【解决方案1】:

它失败了,因为本质上是你的命令

INSERT INTO tablename SELECT * FROM #temptable;";

正在告诉 SQL -“从这个临时表中将所有内容插入到这个表中。”

虽然您可以解决这个问题,但我想说的是,您为什么不尝试仅将您想要包含的值插入到当前表中可用的列中。无需删除列/值,您只需不要一开始就导入它。

另一种选择 - 如果您可以写入辅助表,那么与临时表相比,您拥有的值可能对INSERT INTO 有益于该辅助表,而不是临时表。然后转换那个帮助表,然后你可以做INSERT INTO final_table SELECT * FROM helper。这应该会为您提供您正在寻找的结果。

我希望这会有所帮助,并希望它能解释您当前命令失败的原因。

【讨论】:

  • 我希望将所有列值复制到表的新行中。这就是为什么我将整个临时表插入到目标表中只要我从表中删除时间戳列,事务就可以正常工作。
  • @ChrisJ 如果您可以提供错误消息来说明失败的位置以及伴随的消息,那将会很有帮助。此外,我不明白您为什么声明要复制所有列值,但是您要删除时间戳和 ID。如果您仍然要更改并且这就是导致错误的原因,请不要在您的 select 语句中包含这些列。
  • 1.错误消息正是大卫布朗提到的:
【解决方案2】:

我不明白通过 INSERT INTO xxx (yyy) VALUES (zzz) 插入新行和 INSERT INTO xxx SELECT * FROM yyy 之间的区别在哪里。

有了这个,

INSERT INTO xxx SELECT * FROM yyy.

您未能指定从 SELECT 到目标表的列映射。您应该始终使用

INSERT INTO xxx (Column1, Column2, . . .)
SELECT (Column1, Column2, . . .)
FROM yyy

这是您正在尝试的简化示例:

drop table if exists t

create table t(id int, a int)
insert into t(id,a) values (1,1)

select * into #t from t where id = 1

alter table #t drop column id

insert into t select * from #t 

它会失败

Msg 213, Level 16, State 1, Line 12
Column name or number of supplied values does not match table definition.

因为临时表甚至没有相同数量的列。即使是这样,您也无法确定列映射是否正确。

【讨论】:

  • 我希望将所有列值复制到表的新行中。这就是我将整个 temptable 插入目标表的原因。
猜你喜欢
  • 2017-08-29
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-02
  • 2014-08-08
相关资源
最近更新 更多