我正在尝试从sql server中的另一个表进行批量插入。我的查询目前是这样的:
INSERT INTO Table1(Id, Value)
SELECT ??, Value
FROM Table2;
现在,我的问题显然是由我取代??
。 Id
是没有标识属性的整数列。我想为每个插入的行Id
获取当前的max(Id) + 1
。
我可以直接在插入命令中执行此操作吗?
答案 0 :(得分:5)
如果您使用的是较新版本的SQL Server(2008+),可以试试ROW_NUMBER():
DECLARE @BASE INT
SET @BASE = (SELECT IsNull(MAX(ID),0) FROM Table1)
INSERT INTO Table1(Id, Value)
SELECT
@BASE + ROW_NUMBER() OVER (ORDER BY Value) ID,
Value
FROM Table2;
由于您使用的是SQL Server 2000,因此可以尝试下面的命令:
DECLARE @BASE INT
SET @BASE = (SELECT IsNull(MAX(ID),0) FROM Table1)
INSERT INTO Table1(Id, Value)
SELECT
@BASE + (SELECT COUNT(*) FROM Table2 AS i2 WHERE i2.Value <= a.Value),
a.Value
FROM Table2 a
但只有在Table2中的值为唯一
时才会有效如果Table2有主键(字段PK
),那么您可以使用:
INSERT INTO Table1(Id, Value)
SELECT
@BASE + (SELECT COUNT(*) FROM Table2 AS i2 WHERE i2.PK <= a.PK),
a.Value
FROM Table2 a
答案 1 :(得分:2)
这是一种邪恶的方式。 我们创建一个带有标识的临时表来生成新的ID。这样我们就可以避免使用while循环。
DECLARE @CurrentMaxID INT,
@DynamicQuery NVARCHAR(MAX)
--TODO : Acquired table lock here on table1
SELECT @FirstNextID = ISNULL(MAX(Id), 0)
FROM Table1 --WITH(TABLOCK)
CREATE TABLE #TempTableWithID( Table2Id INT,
Table1FuturId INT IDENTITY(1, 1))
INSERT INTO #TempTableWithID(Table2Id)
SELECT Id --Here we use identity to generate table1 futur id
FROM Table2
INSERT INTO Table1(Id, value)
SELECT Temp.Table1FuturId + @FirstNextID,
Table2.Value
FROM Table2
INNER JOIN #TempTableWithID AS Temp ON Table2.Id = Temp.Table2Id
--TODO : release table lock here on table1
DROP TABLE #TempTableWithID
答案 2 :(得分:1)
如果我正确理解你,这应该有效。
CREATE TABLE #tbl1 (ID int, Value float)
CREATE TABLE #tbl2 (ID int, Value float)
INSERT INTO #tbl2 values (4, 2.0)
INSERT INTO #tbl2 values (8, 3.0)
INSERT INTO #tbl2 values (6, 4.0)
INSERT INTO #tbl1 values (1,1.0)
INSERT INTO #tbl1 values (3,3)
INSERT INTO #tbl1 values (9,3)
/*meat and potatoes start*/
INSERT INTO #tbl1(Id, Value)
SELECT (SELECT MAX(ID) FROM #tbl1) + ROW_NUMBER() OVER (ORDER BY Value) ID, Value
FROM #tbl2;
/*meat and potatoes end*/
Select * From #tbl1
drop table #tbl1
drop table #tbl2
答案 3 :(得分:-1)
为什么不IDENT_CURRENT()?
SELECT IDENT_CURRENT('yourtablename')
它为您提供下一个ID参考。但这仅在ID列已启用IDENTITY的情况下有效。
或者您可以尝试使用SEQUENCE
和NEXT VALUE FOR。
即
CREATE TABLE Test.TestTable
(CounterColumn int PRIMARY KEY,
Name nvarchar(25) NOT NULL) ;
GO
INSERT Test.TestTable (CounterColumn,Name)
VALUES (NEXT VALUE FOR Test.CountBy1, 'Syed') ;
GO
SELECT * FROM Test.TestTable;
GO