原子INSERT + SELECT或SELECT行(基于UNIQUE列)

时间:2018-03-28 16:13:49

标签: sql sql-server sql-server-2008

我的表格创建如下:

CREATE TABLE StackFunctionID
(
    m_FunctionID int PRIMARY KEY IDENTITY,
    m_GroupID int DEFAULT 0 NOT NULL,
    m_Function varchar(256) UNIQUE NOT NULL,
);

GO
CREATE TRIGGER INSERT_MakeGroupID ON StackFunctionID AFTER INSERT AS
BEGIN
    SET NOCOUNT ON;

    UPDATE StackFunctionID
    SET StackFunctionID.m_GroupID = INSERTED.m_FunctionID
    FROM StackFunctionID
    INNER JOIN INSERTED ON (StackFunctionID.m_FunctionID = INSERTED.m_FunctionID)
END;

现在我正在尝试编写一个

的Sql Server 2008查询
  1. 如果m_Function不存在,请创建它,然后返回m_FunctionIDm_GroupID
  2. 如果m_Function存在,请返回m_FunctionIDm_GroupID
  3. 原子地执行
  4. 经过多次尝试,这是过去几年的成效:

    DECLARE @Results TABLE(m_FunctionID INT, m_GroupID INT);  -- trash use
    DECLARE @dummy1 int;                                      -- trash use
    MERGE INTO StackFunctionID WITH(HOLDLOCK) AS Target       -- WITH(HOLDLOCK) for thread safety
    USING (VALUES(null)) AS dummy2(dummy3)                    -- syntax requires USING
    ON Target.m_Function = @m_Function
    WHEN MATCHED THEN
        UPDATE SET @dummy1 = 0                                -- syntax requires something in 'WHEN MATCHED', which is needed for OUTPUT
    WHEN NOT MATCHED THEN
        INSERT(m_Function) VALUES(@m_Function)
    OUTPUT inserted.m_FunctionID, inserted.m_GroupID
    INTO @Results;                                            -- Having a trigger requires 'INTO'
    SELECT * FROM @Results                                    -- Having a trigger requires 'INTO'
    

    然而,有一个错误:当一行被INSERTED时,OUTPUT返回m_GroupID = 0

    问题:

    1. 我如何始终正确m_GroupID
    2. 是否可以通过更简单的查询来实现目标? (因为现在很难理解所有这些“语法要求”)

1 个答案:

答案 0 :(得分:2)

依靠UNIQUE m_Function使用TRY CATCHINSERT然后SELECT。 演示

CREATE TABLE StackFunctionID
(
    m_FunctionID int PRIMARY KEY IDENTITY,
    m_GroupID int DEFAULT 0 NOT NULL,
    m_Function varchar(256) UNIQUE NOT NULL,
);
INSERT StackFunctionID(m_Function)
VALUES ('a'), ('b');
SELECT * FROM StackFunctionID;

DECLARE @m_Function varchar(256) = 'a'; 
BEGIN TRY
  INSERT StackFunctionID(m_Function)
  VALUES ( @m_Function);
END TRY
BEGIN CATCH
  PRINT 'Already exists';
END CATCH

SELECT m_FunctionID, m_GroupID 
FROM StackFunctionID
WHERE m_Function = @m_Function;
相关问题