gpt4 book ai didi

sql - Identity-insert FROM 的语法没有要插入的列?

转载 作者:行者123 更新时间:2023-12-02 21:09:04 25 4
gpt4 key购买 nike

我定义了下表

CREATE TABLE dbo.T_Comments_Paths
(
path_id bigint IDENTITY(1,1) NOT NULL
,CONSTRAINT [PK_T_Comments_Paths] PRIMARY KEY(path_id)
);


CREATE TABLE dbo.T_Comments
(
COM_Id int IDENTITY(1,1) NOT NULL
,COM_Text NATIONAL CHARACTER VARYING(255) NULL
,CONSTRAINT [PK_T_Comments] PRIMARY KEY(COM_Id)
);

如果我需要获取评论的路径 ID,对于单值,我可以这样获取:

DECLARE @outputTable TABLE (path_id bigint); 
INSERT INTO T_Comments_Paths OUTPUT INSERTED.path_id INTO @outputTable DEFAULT VALUES;
SET @__pathuid = (SELECT TOP 1 id FROM @outputTable);

但是,我找不到从另一个表插入的插入 ID(多个)的语法。

例如我想这样做:

DECLARE @outputTable TABLE (path_id bigint, com_id bigint); 
INSERT INTO T_Comments_Paths
OUTPUT INSERTED.path_id, com_id INTO @outputTable DEFAULT VALUES
FROM T_Comments

这会产生

"Incorrect syntax near FROM-keyword"

我怎样才能做到这一点(没有光标)?
注意:我需要与MySQL兼容,所以我不能使用newid(),因为MySQL中没有uuid类型,而且我也不想使用varchar或varbinary.. .

最佳答案

如果我理解正确的话,你的问题可以归结为:将 n 个新行添加到标识列,然后使用这些新添加的值来更新包含 n 行的表 (@outputTable) 中的空列,而无需担心匹配。

设置测试

CREATE TABLE #T_Comments_Paths (
path_id BIGINT IDENTITY(1,1) NOT NULL
, CONSTRAINT [PK1] PRIMARY KEY (path_id)
);

CREATE TABLE #T_Comments (
com_id BIGINT IDENTITY(1,1) NOT NULL
, com_text NVARCHAR(20) NULL
, CONSTRAINT [PK2] PRIMARY KEY (com_id)
);

INSERT INTO #T_comments (com_text)
VALUES
('com1')
, ('com2');

**解决方案 1 **

如果您愿意向 @outputTable 添加额外的列(又名 rowNo),您可以获得如下更短的解决方案:

--Add a few values to make #T_Comment_Paths not empty, for testing purpose, making things not matching
INSERT INTO #T_Comments_Paths DEFAULT VALUES;
INSERT INTO #T_Comments_Paths DEFAULT VALUES;
INSERT INTO #T_Comments_Paths DEFAULT VALUES;

DECLARE @currentID BIGINT;
SELECT @currentID = IDENT_CURRENT('#T_Comments_Paths');
-- @currentID should be 3

DECLARE @outputTable TABLE (path_id bigint, com_id bigint, rowNo bigInt);

INSERT INTO @outputTable (com_id, rowNo)
SELECT
com_id
, ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM
#T_comments;

MERGE #T_Comments_Paths tgt
USING @outputTable src
ON tgt.path_id = src.path_id
WHEN NOT MATCHED THEN INSERT DEFAULT VALUES;

MERGE @outputTable tgt
USING (
SELECT
path_id
, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNo
FROM
#T_Comments_Paths
WHERE
path_id > @currentID
) src
ON tgt.RowNo = src.RowNo
WHEN MATCHED THEN UPDATE SET
tgt.path_id = src.PATH_ID;

SELECT *
FROM
@outputTable;

SELECT *
FROM
#T_Comments_Paths

DROP TABLE #T_Comments;
DROP TABLE #T_Comments_Paths;

**解决方案 2 **

如果您坚持@outputTable 中只有 2 列,那么这是一个解决方案(更长)

--Add a few values to make #T_Comment_Paths not empty, for testing purpose
INSERT INTO #T_Comments_Paths DEFAULT VALUES;
INSERT INTO #T_Comments_Paths DEFAULT VALUES;
INSERT INTO #T_Comments_Paths DEFAULT VALUES;
DECLARE @currentID BIGINT;
SELECT @currentID = IDENT_CURRENT('#T_Comments_Paths');
-- @currentID should be 3

DECLARE @outputTable TABLE (path_id bigint, com_id bigint);
DECLARE @outputMiddleTable TABLE (rowNo bigint, com_id bigint);


INSERT INTO @outputTable (com_id)
SELECT
com_id
FROM
#T_comments;

WITH cte AS (
SELECT
com_id
, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNo
FROM
@outputTable
)
INSERT INTO @outputMiddleTable (rowNo,com_id)
SELECT RowNo, com_id
FROM cte;

MERGE #T_Comments_Paths tgt
USING @outputTable src
ON tgt.path_id = src.path_id
WHEN NOT MATCHED THEN INSERT DEFAULT VALUES;

WITH cte1 AS (
SELECT
path_id
, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNo
FROM
#T_Comments_Paths
WHERE
path_id > @currentID
), cte2 AS (
SELECT
cte1.path_id
, t1.com_id
FROM
@outputMiddleTable t1
JOIN cte1 ON t1.rowNo = cte1.RowNo
)
UPDATE ot
SET path_id = cte2.path_id
FROM @outputTable ot
JOIN cte2 ON ot.com_id = cte2.com_id

SELECT *
FROM
@outputTable;


DROP TABLE #T_Comments;
DROP TABLE #T_Comments_Paths;

关于sql - Identity-insert FROM 的语法没有要插入的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41100621/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com