创建自定义“自动增量”复合主键?

2023-12-31

我有一组父子表(一对多关系)。我正在建表,对 PK 和自动增量的使用有一些疑问。

父表有一个自动编号 PK(用于存储销售单标头)。这里的一张记录是指票上的记录。

子表用于存储票证详细信息。这里的一条记录是票证中的一项(例如可乐、火星棒等)

我知道子表的 PK 应该有 2 个字段:

  1. 父表PK
  2. 使订单项在此工单中唯一的数字

如果我使用IDENTITY,当父母的 PK 改变后,它不会“重新启动”。

我将用一个例子来展示它:

A) SQL 的作用

Parent table
Col1  Col2
1     1000
2     2543
3     3454
Note: Col1 is IDENTITY

Child Table
Col1  Col2  Col3
1     1     Coke
1     2     Mars Bar
2     3     Sprite
3     4     Coke
3     5     Sprite
3     6     Mars Bar
Note: Col1 is taken from Parent Table; Col2 is IDENTITY

B)我想要达到的目标

Parent table is the same as above

Child Table
Col1  Col2  Col3
1     1     Coke
1     2     Mars Bar
2     1     Sprite
3     1     Coke
3     2     Sprite
3     3     Mars Bar

注:Col1取自Parent Table; Col1 更改后 Col2 重置; Col1 和 Col2 组成的都是唯一的。

SQL Server 是否实现了键的这种使用?或者我需要编码吗?


举个例子:

create table dbo.tOrders (
    OrderID int not null identity primary key,
    CustomerID int not null
);
create table dbo.tOrderPos (
    OrderID int not null foreign key references dbo.tOrders,
    OrderPosNo int null,
    ProductID int null
);
create clustered index ciOrderPos on dbo.tOrderPos
    (OrderID, OrderPosNo);
go
create trigger dbo.trInsertOrderPos on dbo.tOrderPos for insert
as begin
    update  opo
    set     OrderPosNo = isnull(opo2.MaxOrderPosNo,0) + opo.RowNo
    from    (select OrderID, OrderPosNo,
                    RowNo = row_number() over (partition by OrderID order by (select 1))
            from    dbo.tOrderPos opo
            where   OrderPosNo is null) opo
    cross apply
            (select MaxOrderPosNo = max(opo2.OrderPosNo)
            from    dbo.tOrderPos opo2
            where   opo2.OrderID = opo.OrderID) opo2
    where   exists (select * from inserted i where i.OrderID = opo.OrderID);
end;
go
declare @OrderID1 int;
declare @OrderID2 int;
insert into dbo.tOrders (CustomerID) values (11);
set @OrderID1 = scope_identity();
insert into dbo.tOrderPos (OrderID, ProductID)
values (@OrderID1, 1), (@OrderID1, 2), (@OrderID1, 3);
insert into dbo.tOrders (CustomerID) values (12);
set @OrderID2 = scope_identity();
insert into dbo.tOrderPos (OrderID, ProductID)
values (@OrderID2, 4), (@OrderID2, 5);
insert into dbo.tOrderPos (OrderID, ProductID)
values (@OrderID1, 6);
select * from dbo.tOrderPos;
go
drop trigger dbo.trInsertOrderPos;
drop table dbo.tOrderPos;
drop table dbo.tOrders;
go

困难在于允许多次插入和延迟插入。 华泰

另一种选择是使用替代触发器:

create trigger dbo.trInsertOrderPos on dbo.tOrderPos instead of insert
as begin
    insert into dbo.tOrderPos
            (OrderID, OrderPosNo, ProductID)
    select  OrderID,
            OrderPosNo =
            isnull( (select max(opo.OrderPosNo)
                    from    dbo.tOrderPos opo
                    where   opo.OrderID = i.OrderID), 0) +
            row_number() over (partition by OrderID order by (select 1)),
            ProductID
    from    inserted i;
end;

不幸的是,似乎不可能将 OrderPosNo 设置为“非空”,因为多次插入会导致重复的键。因此,我无法使用主键,而是使用聚集索引。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

创建自定义“自动增量”复合主键? 的相关文章

  • SQL Server 使用通配符加入并在第一个匹配处停止

    IF OBJECT ID tempdb TABLE1 IS NOT NULL DROP TABLE TABLE1 IF OBJECT ID tempdb TABLE2 IS NOT NULL DROP TABLE TABLE2 CREATE
  • SQL - 为每条记录调用存储过程

    我正在寻找一种方法来为 select 语句的每条记录调用存储过程 SELECT SomeIds SELECT spro Id FROM SomeTable as spro INNER JOIN Address addr ON addr Id
  • Postgres、更新和锁定顺序

    我正在研究 Postgres 9 2 有 2 个更新 每个更新都有自己的事务 一个看起来像 UPDATE foo SET a 1 WHERE b IN 1 2 3 4 另一个也类似 UPDATE foo SET a 2 WHERE b IN
  • Quartz.NET 设置 MisfireInstruction

    我正在使用 Quartz NET 在 C 中工作 并且在 CronTrigger 上设置失火指令时遇到问题 我正在运行安装了 Quartz DB 的 SQL 后端 我有以下代码 可以很好地创建作业和运行调度程序 IScheduler sch
  • 如何通过循环变量在 dbt 中多次运行 SQL 模型?

    我有一个 dbt 模型 测试模型 接受地理变量 zip state region 在配置中 我想通过循环变量来运行模型三次 每次使用不同的变量运行它 问题是 我有一个如下所示的宏 它将变量附加到输出表名称的末尾 即运行测试模型 with z
  • 将多行合并为一行并根据行数附加列

    我正在尝试将同一个表的多行合并为一个 我有一个像这样的示例表 Col1 Col2 Col3 Col4 Col5 Col6 1 BH1 CB 12 CC CC Conveyor Mal 1 BH1 CB 104 ZC ZC Full Emp
  • SQL Server 2000 中是否提供公用表表达式 (CTE)

    我最近发现了以下文章 http www tsqltutorials com with common table expressions php http www tsqltutorials com with common table exp
  • 案例陈述以确定我是否应该结合

    我目前想做某种条件联合 给出以下示例 SELECT age name FROM users UNION SELECT 25 AS age Betty AS name 假设我只想在 用户 计数 gt 2 时合并第二个语句 否则不合并两者 总之
  • SQL Server 支持哈希索引吗?

    所有索引都在SQL Server B Tree中吗 主键和外键肯定应该是基于哈希的索引吗 SQL Server中并非所有索引都是B树索引 SQL Server 2012添加了列存储索引 http msdn microsoft com en
  • PHP DBlib PDO 问题

    我正在尝试通过 php 连接到 MSSQL 服务器 但我的 pdo 连接给我带来了困难和我不太理解的错误 我在下面粘贴的代码一周前运行得很好 突然间它就停止了 没有任何人进行任何更改 我仍然可以连接到服务器并直接从命令行运行查询 但我在 p
  • 为什么查询优化器完全忽略索引视图索引?

    SQL 小提琴 http sqlfiddle com 6 d4496 1 http sqlfiddle com 6 d4496 1 数据是为您的实验预先生成的 有一个明显的表格 CREATE TABLE Entity ID int Clas
  • 使用 xmlagg 时出现子查询错误和太多值

    我在连接许多大型表中的所有数据时遇到问题 我昨天对此提出了问题 但不幸的是 listagg 似乎不是一个好的选择 链接子查询返回多行 https stackoverflow com questions 54651144 subquery r
  • SqlException超时未达到

    我们的服务器有时会抛出这个众所周知的异常 超时已过 操作完成之前超时时间已过 或者服务器未响应 当服务器处理大请求时 这种情况会在压力下发生 我做了一些研究 发现我可以改变连接字符串连接超时设置和 或SqlCommand 超时数据读取器属性
  • 如何将整行(在 SQL 中,而不是 PL/SQL 中)传递给存储函数?

    我遇到以下 非常简单 问题 我想编写一个 Oracle SQL 查询 大致如下 SELECT count MyFunc MyTable FROM MyTable GROUP BY MyFunc MyTable 在 PL SQL 中 可以使用
  • 如何在sqlite中添加特定数量的空行?

    我有一个SQLite文件 我想添加2550 empty NULL rows 我可以使用此代码添加一个空行 INSERT INTO my table DEFAULT VALUES 但我需要 2550 行 有什么捷径吗 我不想执行相同的代码 2
  • ActiveRecord 嵌套 SELECT——我可以在没有手动 SQL 的情况下完成它吗?

    我有一张桌子 上面有 除其他外 一个名字和一个等级 我想返回所有唯一名称的集合 但对于返回的每个名称 我想选择排名最高的行 这很简单 有两个嵌套的 SELECT 语句 SELECT FROM SELECT FROM foo ORDER BY
  • 按两列的最小值排序

    I use SQL Server 2008 R2 我需要按两列的最小值对表进行排序 该表如下所示 ID integer Date1 datetime Date2 datetime 我希望我的数据按至少两个日期排序 以这种方式对该表进行排序的
  • 部署 dacpac 所需的权限

    我正在尝试使用 sqlpackage exe 在租户上部署 dacpac 目前 我正在向将部署此功能的帐户授予 SysAdmin 或 db owner 权限 并且它工作正常 但在生产中 如果目标租户数据库属于其他应用程序 我可能无法获得这些
  • 在 SSIS 中使用合并任务的指南

    我有一个包含三个字段的表 其中一个是身份字段 我需要从具有其他两个字段的源中添加一些新记录 我正在使用SSIS 我认为我应该使用合并工具 因为其中一个源不在本地数据库中 但是 我对合并工具和正确的过程感到困惑 我有一个源 一个 Oracle
  • 最佳实践 - 存储过程日志记录

    如果您有一个长时间运行的 SP 您会以某种方式记录其操作还是只是等待此消息 命令成功完成 我认为 关于这个主题可以有很多解决方案 但是有没有最佳实践 一个经常使用的简单解决方案 EDIT 我发现了一个关于这个主题的有趣链接 http web

随机推荐