无法将显式值插入时间戳列

时间:2015-03-19 10:01:11

标签: sql-server tsql sql-server-2012

试图找到解决错误的方法

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插入时间戳列。

我不想在语句中明确地放置每一列,因为该表可能会更改,我只想复制行&改变一些事情。

我尝试了一些解决方法,阅读了很多帖子,但没有快乐。救命啊!

6 个答案:

答案 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 tableselect 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)。那么你不需要列出列。