试图找到解决错误的方法
SELECT *
INTO #Products
FROM Products
WHERE Code = @sku
Update #products
SET Code = Code+'Group',
ProducttypeID = @SimpleProducttype,
ParentProductID = @SimpleProductID,
ID = NEWID()
ALTER TABLE #Products Drop column ts
INSERT Products
SELECT *, null ts FROM #Products
然后我得到:
无法将显式值插入时间戳列。将INSERT与列列表一起使用以排除时间戳列,或将DEFAULT插入时间戳列。
我不想在语句中明确地放置每一列,因为该表可能会更改,我只想复制行&改变一些事情。
我尝试了一些解决方法,阅读了很多帖子,但没有快乐。救命啊!
答案 0 :(得分:4)
始终始终,始终在INSERT
声明中列出您的列。
INSERT INTO your_table (foo, bar)
SELECT list_columns
, here_too
FROM select_star_is_evil As seriously
;
不这样做的唯一借口是懒惰。
明确您的代码非常重要!
</rant>
错误消息非常明确:您正在尝试在时间戳列中插入值。您的最终陈述是尝试插入NULL
值。
避免此行为的唯一方法是不在列出INSERT
列表中的时间戳列。
答案 1 :(得分:1)
此处您尝试将null
值插入列ts
另外,此处insert
table
和select
table
具有不同的列列表,因此您必须在select statement
中列出该列。
试。
SELECT *
INTO #Products
FROM Products
WHERE Code = @sku
Update #products
SET Code = Code+'Group',
ProducttypeID = @SimpleProducttype,
ParentProductID = @SimpleProductID,
ID = NEWID()
ALTER TABLE #Products Drop column ts
INSERT INTO Products(col1,col2)
SELECT col1,col2 FROM #Products
答案 2 :(得分:1)
这是您的解决方法。
/************************************************************************************************
CREATE SAMPLE TABLE AND ADD SAMPLE DATA
************************************************************************************************/
CREATE TABLE Products
(
ID UNIQUEIDENTIFIER NOT NULL,
ProductTypeID INT NOT NULL,
ParentProductID INT NOT NULL,
Code VARCHAR(255) NOT NULL,
ts TIMESTAMP
);
INSERT Products (ID, ProductTypeID, ParentProductID, Code)
VALUES (NEWID(), 1, 1, 'SKU');
/************************************************************************************************
DECLARE INPUT VARIABLES
************************************************************************************************/
DECLARE @SimpleProducttype INT = 2,
@SimpleProductID INT = 2,
@Sku VARCHAR(255) = 'SKU',
@ID UNIQUEIDENTIFIER = NEWID();
/************************************************************************************************
GENERATE INSERT SCRIPT USING SYS.COLUMNS AND XML CONCATENATION
************************************************************************************************/
DECLARE @SQL NVARCHAR(MAX) =
'INSERT Products (' +
STUFF(( SELECT ',' + QUOTENAME(c.name)
FROM sys.columns AS c
WHERE c.[object_id] = OBJECT_ID(N'dbo.Products')
AND c.name != 'ts'
ORDER BY c.column_id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
+ ')
SELECT ' +
STUFF(( SELECT ',' + CASE WHEN c.Name IN ('ProducttypeID', 'ParentProductID', 'ID') THEN '@' + Name
ELSE QUOTENAME(c.name)
END
FROM sys.columns AS c
WHERE c.[object_id] = OBJECT_ID(N'dbo.Products')
AND c.name != 'ts'
ORDER BY c.column_id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '') + '
FROM Products
WHERE Code = @sku;';
/************************************************************************************************
EXECUTE THE SCRIPT
************************************************************************************************/
EXECUTE sp_executesql
@SQL,
N'@ParentProductID INT, @ProductTypeID INT, @ID UNIQUEIDENTIFIER, @Sku VARCHAR(255)',
@ParentProductID = @SimpleProductID,
@ProducttypeID = @SimpleProducttype,
@ID = @ID,
@Sku = @Sku;
为示例表生成的脚本是:
INSERT Products ([ID],[ProductTypeID],[ParentProductID],[Code])
SELECT @ID,@ProductTypeID,@ParentProductID,[Code]
FROM Products
WHERE Code = @sku;
这是一个 UGLY 黑客,我不建议您使用它,我发布它以显示列出列的简单程度,每次架构更改时,都会对存储过程的更改。
答案 3 :(得分:1)
我建议创建一个视图,该视图返回除时间戳之外的所有列。 您需要确保视图保持最新,但这样可以使更新脚本本身无需显式指定列即可运行。
您的脚本如下所示:
SELECT *
INTO #Products
FROM vwProducts
WHERE Code = @sku
Update #products
SET Code = Code+'Group',
ProducttypeID = @SimpleProducttype,
ParentProductID = @SimpleProductID,
ID = NEWID()
INSERT vwProducts
SELECT * FROM #Products
答案 4 :(得分:0)
你不能使用select *
一种方法是从列列表中删除timespan
:
INSERT INTO Products ( [Col1],[Col2],[Coln] )
VALUES ( 'ValueCol1','ValueCol2','ValueCol' )
第二种方法是将DEFAULT指定为timestamp
列中的值:
INSERT INTO Products ( [Col1], [Timestamp] )
VALUES ( 'Col1Value', DEFAULT )
答案 5 :(得分:0)
如果不关心timestamp/rowversion字段中的值,可以在copy表上定义为binary(8)。那么你不需要列出列。