简体   繁体   English

如何在SQL Server插入选择查询中插入循环值?

[英]How to insert loop value in SQL Server insert-select query?

I have three tables: 我有三个表:

ORSeries where the last official receipt is temporarily saved: 临时保存最后一张正式收据的ORSeries

|ORSeries|
+--------+
| 1000   |

Collections where users issued with an official receipt will be saved: 带有官方收据的用户的Collections将被保存:

|   OR   |  ID    |  Date  |
+--------+--------+--------+
|        |        |        |

Users where users without an official receipt are saved: Users ,用户没有正式收据保存:

|  ID    |  Date      |
+--------+------------+
|  0001  | 08-10-2019 |
|  0002  | 08-10-2019 |
|  0003  | 08-10-2018 |
|  0004  | 08-10-2018 |
|  0005  | 08-10-2018 |

I want to issue an official receipt to the users dated 08-10-2018. 我想向用户签发日期为2018年10月10日的正式收据。 What I have so far: 到目前为止,我有:

INSERT INTO [Collections] (OR, Name, [Date])
    SELECT
        (SELECT SeriesNo + 1 FROM TempORSeries),
        Name,
        [Date]
    FROM 
        ORSeries

Expected output: 预期产量:

|   OR   |  ID    |    Date    |
+--------+--------+------------+
| 10001  |  0003  | 08-10-2018 |
| 10002  |  0004  | 08-10-2018 |
| 10003  |  0005  | 08-10-2018 |

However, all the users received the same official receipt number. 但是,所有用户都收到相同的正式收据号。

My query returns: 我的查询返回:

|   OR   |  ID    |    Date    |
+--------+--------+------------+
| 10001  |  0003  | 08-10-2018 |
| 10001  |  0004  | 08-10-2018 |
| 10001  |  0005  | 08-10-2018 |

How can I fix this? 我怎样才能解决这个问题?

You can use row_number + SeriesNo 您可以使用row_number + SeriesNo

begin transaction;

declare @SeriesNo int = (case 
                            when not exists(select 1 from Collections) 
                               then (select SeriesNo from TempORSeries)
                               else (select max([OR]) from Collections) 
                         end);

Insert into [Collections] 
    select
        @SeriesNo + (row_number() over (order by (select 1))),
        [Name],
        [Date]
    from
        ORSeries
    where 
        [Date] = '2018-08-10';

commit;

Online Demo With SQL Server 2012 | SQL Server 2012在线演示 db<>fiddle db <>小提琴

在此处输入图片说明


How can I update my ORSeries table with the last issued official receipt ? 如何使用最后一张正式收据更新ORSeries表?

This is a new question, I recommend using auto increment concat to avoid multiple connection problem. 这是一个新问题,我建议使用auto increment concat连接以避免多路连接问题。 Please read : 请阅读 :

tsql - How do I add string with auto increment value in SQL Server? tsql-如何在SQL Server中添加具有自动增量值的字符串? - Stack Overflow - 堆栈溢出

Assuming there is some reason you couldn't use an Identity column , Sql Server 2016 and later support SEQUENCES . 假设由于某些原因您无法使用Identity列 ,则Sql Server 2016及更高版本支持SEQUENCES

You should get rid of the ORSeries table completely and either replace it with a new Sequence or convert the OR column in the Collections table to an identity. 您应该完全摆脱ORSeries表,或者用新的Sequence替换它,或者将Collections表中的OR列转换为一个标识。 Here is the Sequence example: 这是序列示例:

CREATE SEQUENCE ORSequence START WITH {current sequence value + 1 here};

Then the INSERT statement will look like this: 然后,INSERT语句将如下所示:

Insert into [Collections] 
(
    OR,
    ID, 
    [Date]
)
SELECT
    NEXT VALUE FOR ORSequence,
    ID,
    [Date]
FROM Users WHERE Date = '20181018'

Both options get rid of the need to use a transaction to control updating the old ORSeries table — which you probably weren't doing before, and were therefore at risk of two sessions using the same OR numbers. 这两个选项都摆脱了使用事务来控制更新旧ORSeries表的需要-您以前可能没有做过,因此有使用相同OR号进行两次会话的风险。

begin transaction

insert Collections
select t1.[OR] + row_number() over(order by t2.ID), t2.ID, t2.Date
from ORSeries t1
cross join Users t2
where t2.Date = "08-10-2019"

update ORSeries
set [OR] = (select MAX([OR]) from Collections where Date = "08-10-2019")

commit transaction

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM