如何使用SQL insert将自动增量值插入select语句

时间:2017-04-08 06:55:44

标签: sql-server tsql

我有以下代码从另一个数据库中的表中插入数据,但是如何通过将ID列值中的最后一个记录增加1来插入主键列?在我的情况下,[WORK ORDER #]是主键,它不允许为空。

[WORK ORDER #]nvarchar(10)

INSERT INTO DB1.dbo.WORKORDERS ([WORK ORDER #], [CUSTOMER], [SO DATE], [SO NUMBER])
    SELECT * 
    FROM OPENQUERY([DB29],
                  'SELECT DISTINCT 
                       NULL, --need to set auto increment value here 
                       Customers.Customer_Bill_Name, 
                       JrnlHdr.TransactionDate,
                       JrnlHdr.Reference)
                   FROM Customers
                   INNER JOIN JrnlHdr ON Customers.CustomerRecordNumber = JrnlHdr.CustVendId
                   WHERE JrnlHdr.JrnlKey_Journal = 11 
                     AND JrnlHdr.TransactionDate = CURDATE()

------------------- //我尝试如下-----

--> You only do this one time...not with each query
create sequence dbo.WorkOrderSequence
  as int
  start with 43236


--> I took out the part that failed (you got option 1 and 3 kinda
--> mashed together)
insert DB1.dbo.WORKORDERS 
   ([WORK ORDER #],[CUSTOMER],[SO DATE],[SO NUMBER],[ASSY PN-S],[CUSTOMER PN],[SHIP VIA],[PROMISED DATE],[COMMENTS],[PO #],[WO Notes])
select 
  convert(varchar(10), next value for DB1.dbo.WorkOrderSequence ),
  x.Customer_Bill_Name,
  x.TransactionDate,
  x.Reference,
  x.ItemID,
  x.PartNumber,
  x.WhichShipVia,
  x.ShipByDate,
  x.Comment2,
  x.CustomerInvoiceNo,
  x.SalesDescription
from
  openquery
  ([DB29],
    'select distinct           
       Customers.Customer_Bill_Name,
       JrnlHdr.TransactionDate,
       JrnlHdr.Reference, 
       LineItem.ItemID ,
       LineItem.PartNumber, 
       Customers.WhichShipVia, 
       JrnlHdr.ShipByDate, 
       JrnlHdr.Comment2,
       JrnlHdr.CustomerInvoiceNo, 
       LineItem.SalesDescription    
FROM   Customers
INNER JOIN JrnlHdr
ON Customers.CustomerRecordNumber = JrnlHdr.CustVendId
LEFT OUTER JOIN Address
ON Customers.CustomerRecordNumber = Address.CustomerRecordNumber
INNER JOIN JrnlRow
ON JrnlHdr.PostOrder = JrnlRow.PostOrder
INNER JOIN LineItem 
ON JrnlRow.ItemRecordNumber = LineItem.ItemRecordNumber
WHERE  JrnlHdr.JrnlKey_Journal = 11 AND JrnlHdr.TransactionDate = CURDATE() 
AND JrnlHdr.PostOrder = JrnlRow.PostOrder  
AND JrnlHdr.CustVendId = Customers.CustomerRecordNumber 
AND JrnlRow.ItemRecordNumber = LineItem.ItemRecordNumber 
AND JrnlHdr.POSOisClosed = 0' 
) as x

2 个答案:

答案 0 :(得分:1)

选项1

如果您至少使用SQL Server 2012(您没有提及特定版本),则可以使用常规序列号生成器。对于这种情况,我非常喜欢它。在DB1数据库中,您将添加如下序列:

create sequence dbo.WorkOrderSequence
  as int
  start with 5002230 --> pick a starting number greater 
                     --> than any existing [WorkOrder #] 

然后,您可以在insert-for-select语句中获取下一个数字:

insert DB1.dbo.WORKORDERS 
  ([WORK ORDER #], [CUSTOMER], [SO DATE], [SO NUMBER])
select 
  convert(varchar(10), next value for DB1.dbo.WorkOrderSequence ),
  x.Customer_Bill_Name,
  x.TransactionDate,
  x.Reference
from
  openquery
  ([DB29],
    'select distinct 
       Customers.Customer_Bill_Name, 
       JrnlHdr.TransactionDate,
       JrnlHdr.Reference
     from
       Customers
       inner join 
       JrnlHdr on 
         Customers.CustomerRecordNumber = JrnlHdr.CustVendId
     where
       JrnlHdr.JrnlKey_Journal = 11
       and 
       JrnlHdr.TransactionDate = CURDATE()' 
  ) as x

序列是一个独立的自动递增数字。每次使用next value for dbo.WorkOrderSequence时,它都会自动递增。这样,您就不必修改任何表定义。

选项2

或者,您可以更改DB1.dbo.WORKORDERS表,以便使用表达式的默认值...

alter table dbo.WORKORDERS
  alter column [Work Order #] nvarchar(10) not null
    default( convert( nvarchar(10), next value for dbo.WorkOrderSequence ) )

如果您这样做,那么您可以完全省略完全插入[Work Order #]并让默认设置成为魔术。

选项3

如果你不是在2012年,但至少在2008年,你仍然可以到达那里......但这有点棘手,因为你必须得到当前的开始[Work Order #]

insert DB1.dbo.WORKORDERS 
  ([WORK ORDER #], [CUSTOMER], [SO DATE], [SO NUMBER])
select 
  convert(varchar(10), x.RowNum + y.MaxOrderNum ),
  x.Customer_Bill_Name,
  x.TransactionDate,
  x.Reference
from
  openquery
  ([DB29],
    'select distinct 
       row_number() over( order by JrnlHdr.TransactionDate ) as RowNum,
       Customers.Customer_Bill_Name, 
       JrnlHdr.TransactionDate,
       JrnlHdr.Reference
     from
       Customers
       inner join 
       JrnlHdr on 
         Customers.CustomerRecordNumber = JrnlHdr.CustVendId
     where
       JrnlHdr.JrnlKey_Journal = 11
       and 
       JrnlHdr.TransactionDate = CURDATE()' 
  ) as x
  cross join
  (
    select 
      convert( int, max( [Work Order #] ) ) as MaxOrderNum
    from 
      Db1.dbo.WORKORDERS
  ) as y

选项4

如果您使用的是早于2008年的某些内容...您可能希望存储过程分两步执行插入操作:将工作订单插入临时表(具有自动增量的表{{1} }从当前表的最大值开始([工作单#])+ 1)...然后步骤2将临时表插入带有转换的[Work Order #]

答案 1 :(得分:0)

我已经尝试了一点SQL,但没有创建表格。我已经使用postgreSQL和knex这样做了,我相信适合您需求的解决方案也是使用唯一值。我很抱歉,如果这不正确,因为我不熟悉编码,但希望看到这将有助于或查看SQL文档:) difference between primary key and unique key