【问题标题】:Setting IDENTITY_INSERT ON for SQL Server table valued type为 SQL Server 表值类型设置 IDENTITY_INSERT ON
【发布时间】:2020-11-16 09:02:59
【问题描述】:

有没有办法为表值类型设置IDENTITY_INSERT ON?处理表格的方式 - 不起作用。

CREATE TYPE dbo.tvp_test AS TABLE
(
    id INT NOT NULL IDENTITY(1, 1),
    a  INT NULL
);
GO

DECLARE @test dbo.tvp_test;

SET IDENTITY_INSERT @test ON;

INSERT INTO @test VALUES (1, 1);

DROP TYPE dbo.tvp_test;

错误:

消息 102,第 15 级,状态 1,第 13 行
'@test' 附近的语法不正确

【问题讨论】:

  • IDENTITY_INSERT 允许您专门更改表,而不是变量。如果您需要一种具有IDENTITY 的类型,而另一种没有,则需要两种类型。
  • 你到底为什么想要那个?恕我直言,仅在将数据从一个表复制到另一个表时才应使用身份插入。至少,我似乎想不出任何其他有效的用例。
  • @ZoharPeled 因为我希望在一种情况下自动生成此序列并在另一种情况下进行预定义

标签: sql-server identity-insert


【解决方案1】:

有没有办法为表值类型设置IDENTITY_INSERT ON

TL;DR:没有。


SET IDENTITY_INSERT 是用于针对表对象而非变量的命令。 SET IDENTITY_INSERT (Transact-SQL):

SET IDENTITY_INSERT (Transact-SQL)

允许将显式值插入到表的标识列中。 ##语法

SET IDENTITY_INSERT [ [ database_name . ] schema_name . ] table_name { ON | OFF }  

参数

数据库名称
是指定表所在的数据库的名称。

架构名称
是表所属的架构名称。

表名
是具有标识列的表的名称。

请注意,这根本没有引用变量;那是因为它不能用来对付一个人。

如果您确实需要两种版本的表类型,一种允许其 ID 列的显式值,另一种使用 IDENTITY,您将需要定义 2 种表类型;一个有IDENTITY 属性,另一个没有:

CREATE TYPE dbo.tvp_test_i AS TABLE (id INT NOT NULL IDENTITY(1, 1),
                                     a INT NULL);

CREATE TYPE dbo.tvp_test_ni AS TABLE (id INT NOT NULL,
                                     a INT NULL);
GO

DECLARE @i dbo.tvp_test_i;
INSERT INTO @i (a)
VALUES(17),(21);

DECLARE @ni dbo.tvp_test_ni;
INSERT INTO @ni (id,a)
VALUES(3,95),(5,34);

SELECT *
FROM @i;

SELECT *
FROM @ni;

【讨论】:

    【解决方案2】:

    您可以在同一表类型中容纳两个 ID(自动生成和/或手动指定),但会增加一些开销:

    CREATE TYPE dbo.tvp_test_xyz AS TABLE
    (
        autoid INT NOT NULL IDENTITY(1, 1), --auto generated id
        manualid int null, --manually inserted id (filled in when needed)
        id as isnull(manualid, autoid) unique, --the final id, this is used in queries etc....
        a  INT NULL
    );
    GO
    
    
    declare @t as dbo.tvp_test_xyz ;
    
    --case, use autogenerated id
    insert into @t(a)
    select top (100) object_id
    from sys.all_objects;
    
    --id = autoid
    select *
    from @t;
    
    select * from @t
    where id between 10 and 20;
    
    --case, manual id
    delete from @t;
    
    insert into @t(manualid, a)
    select top (100) row_number() over(order by name desc), object_id
    from sys.all_objects;
    
    --id = manualid
    select * from @t;
    
    select * from @t
    where id between 10 and 20;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      相关资源
      最近更新 更多