2016-12-12 3 views
7

私はコメントのパスIDを取得する必要がある場合は、単一値のために、私はこのようにそれを得ることができ、次の表に挿入する列がないidentity-insert FROMの構文はありますか?

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) 
); 

を定義している。しかし

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 

これは

"近いFROM-キーワード不適切な構文" を生み出す

私は(カーソルなし)ことをどのように行うことができますか?
注:私は、MySQLとの互換性が必要なので、そこにはUUID型は、MySQLでいない、と私はvarchar型またはvarbinary型のいずれかを使用したくないので、私は、)(NEWIDを使用することはできません...

+0

@Ivan Starostin:それは重複していない、彼は1つだけの値を挿入しています。この記事も見つかりました。それは私が望むものではありません。 –

+0

com_idの接頭辞にINSERTEDを付けてみましたか?したがって:OUTPUT INSERTED.path_id、INSERTED.com_id INTO @outputTableデフォルト値? –

+0

@ジョン・ジョセフ:私はcom_idをT_Comments_Pathsに挿入していません。出力テーブルに、生成されたオートノードと一緒にそれを含めています。 –

答えて

1

私が正しく理解していれば、あなたの問題は次のようになります。 ID列に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'); 

** SOLUTION 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; 

** SOLUTION 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; 
+1

明確でない場合は:私は0の追加の列と2つの出力列を厳密に要求します。追加の列を使用すると、すべてのソリューションよりもはるかに短くなり、すべてが追加の列を追加します。また、マージは必要でもなく、望ましくもありません。これはマルチスレッド環境のバグ・ソースです。 –

+0

私は、元のT_Comments_Pathsテーブル(私のソリューションでは#T_Comments_Pathsです)ではなく、変数テーブルoutputTableに余分な列を意味しました。変数outputTableに余分な列を持つものと、変数outputTableに追加の列を持たないものの2つのソリューションを入れました。(ただし余分なテーブル変数が必要です) – DVT

+1

これを読んでいる人は何が起こっているのか分かりません。その理由だけでは、それを「解決策」と呼ぶことはできません。また、私はこれがカーソル上でどのような利益をもたらすかは分かりません。それはもっと長くて複雑です。私はポータブルなRDBMSに依存しないコードを書こうとしています。したがって、技術的に可能な限り、このようなものはほとんど必要ありません。それはカーソルやこのようなものを防ぐ唯一の解決策であるため、追加の列を使用しました。質問に対する正解はこうです: "それは不可能です"。 –

関連する問題