是否有一种使用SQL Server 2005插入多行并增加特定字段的简单方法?
注意,我不正在寻找涉及identity
列的解决方案 - 请参阅问题的底部以获得解释
(已复制以下架构和数据here in this SQLFiddle。)
例如,请考虑以下表格和数据......
CREATE TABLE #TEMPTABLE (
[PKID] INT IDENTITY, [FKID] INT, [MYTEXT] VARCHAR(10), [SEQUENCE] INT
)
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE]) VALUES (1, 'one', 1)
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE]) VALUES (1, 'two', 2)
-- Table data
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
要插入以下数据......
DECLARE @FKID INT
SET @FKID = 1
DECLARE @NEWDATA XML
SET @NEWDATA = '<data><text>three</text><text>four</text></data>'
以下内容是否可以SEQUENCE
字段显示为1,2,3,4
而不是当前的1,2,3,3
?
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE])
SELECT @FKID,
X.value('.','VARCHAR(10)'),
(SELECT ISNULL(MAX([SEQUENCE]),0)+1 FROM #TEMPTABLE WHERE [FKID]=@FKID)
FROM @NEWDATA.nodes('/data/text') AS X(X)
-- Actual result...
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
3 1 three 3
4 1 four 3 <-- Issue
-- Required result...
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
3 1 three 3
4 1 four 4
更新
回应@marc_s的评论......
身份将是2005年的最佳解决方案......到目前为止最好的解决方案 - 为什么你明确地排除它并坚持自己滚动? (具有造成重复的所有风险等等......)
相关表格将包含多组SEQUENCE
值,每个值都根据FKID
值“设置”...因此表格可以保存这些行的数据......
PKID FKID MYTEXT SEQUENCE
1 1 one 1
2 1 two 2
3 1 three 3
4 1 four 4
5 2 ett 1
6 2 tva 2
7 2 tre 3
答案 0 :(得分:4)
我无法在2005年进行测试,但您应该可以使用CTE来编号;
DECLARE @FKID INT
SET @FKID = 1
DECLARE @NEWDATA XML
SET @NEWDATA = '<data><text>three</text><text>four</text><text>five</text></data>'
;WITH cte AS (SELECT @FKID FKID, X.value('.','VARCHAR(10)') a,
ROW_NUMBER() OVER (ORDER BY X) r
FROM @NEWDATA.nodes('/data/text') AS X(X))
INSERT INTO TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE])
SELECT fkid, a,
(SELECT ISNULL(MAX([SEQUENCE]),0)+r FROM TEMPTABLE WHERE [FKID]=cte.fkid)
FROM cte;
SELECT * FROM TEMPTABLE;
给出了结果:
1 1 one 1
2 1 two 2
3 1 three 3
4 1 four 4
5 1 five 5
<强>更新强>
如果查询只插入一个FKID,则以下简化版本也会起作用(突出显示当前查询的必要更改):
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE])
SELECT @FKID,
X.value('.','VARCHAR(10)'),
(SELECT ISNULL(MAX([SEQUENCE]),0)+1 FROM #TEMPTABLE WHERE [FKID]=@FKID)
+ ROW_NUMBER() OVER (ORDER BY (SELECT 1))
FROM @NEWDATA.nodes('/data/text') AS X(X)
(SELECT 1)
ROW_NUMBER
子句中ORDER BY
的目的是避免指定任何特定顺序。如有必要,可将其更改为其他内容(例如X.value('.','VARCHAR(10)'
)。
答案 1 :(得分:1)
怎么样
INSERT INTO #TEMPTABLE ([FKID], [MYTEXT], [SEQUENCE])
SELECT @FKID,
X.value('.','VARCHAR(10)'),
(SELECT ISNULL(Count(*),0)+1 FROM #TEMPTABLE)
FROM @NEWDATA.nodes('/data/text') AS X(X)
答案 2 :(得分:0)
试试这个:
with data as (
select * from ( values
(1,1,'one'),
(2,1,'two'),
(3,1,'three'),
(5,1,'five'),
(6,1,'six')
) data(PKID, FKID, MYTEXT)
)
select lhs.*, sequence = count(*)
from data lhs
left join data rhs on rhs.FKID = lhs.FKID
and rhs.PKID <= lhs.PKID
group by
lhs.PKID,
lhs.FKID,
lhs.MYTEXT
产生这个:
PKID FKID MYTEXT sequence
----------- ----------- ------ -----------
1 1 one 1
2 1 two 2
3 1 three 3
5 1 five 4
6 1 six 5