【问题标题】:Syntax issue using ON in a MERGE INTO statement在 MERGE INTO 语句中使用 ON 的语法问题
【发布时间】:2017-08-10 17:07:10
【问题描述】:

智能感知错误:

消息 156,级别 15,状态 1,过程 Location_CVT_Insert,第 19 行 [批处理开始第 2 行]
关键字“ON”附近的语法不正确。

存储过程代码:

DROP PROCEDURE IF EXISTS [dbo].[Location_CVT_Insert]
GO

CREATE PROCEDURE [dbo].[Location_CVT_Insert]
     (@Location_NotificationJson NVARCHAR(MAX))
AS 
BEGIN
    MERGE INTO Location_CVT AS C
    USING (SELECT 
               deviceID, lastSeen, locationMapHierarchy, locationCoordinateX, 
               locationCoordinateY, locationCoordinateUnit, geoCoordinateLat,
               geoCoordinateLong, geoCoordinateUnit
           FROM 
               OPENJSON(@Location_NotificationJson)
           WITH 
               (deviceId nchar(17),
                lastSeen varchar(128),
                locationMapHierarchy nvarchar(256),
                locationCoordinateX float,
                locationCoordinateY float,
                locationCoordinateUnit nvarchar(64),
                geoCoordinateLat float,
                geoCoordinateLong float,
                geoCoordinateUnit nvarchar(64)) AS InputJSON) ON (C.deviceId = InputJSON.deviceId)

    WHEN MATCHED THEN
        UPDATE 
            SET C.deviceId = InputJSON.deviceId,
                C.lastSeen = InputJSON.lastSeen,
                C.locationMapHierarchy = InputJSON.locationMapHierarchy,
                C.locationCoordinateX = InputJSON.locationCoordinateX,
                C.locationCoordinateY = InputJSON.locationCoordinateY,
                C.locationCoordinateUnit = InputJSON.locationCoordinateUnit,
                C.geoCoordinateLat = InputJSON.geoCoordinateLat,
                C.geoCoordinateLong = InputJSON.geoCoordinateLong,
                C.geoCoordinateUnit = InputJSON.geoCoordinateUnit

    WHEN NOT MATCHED THEN
        INSERT (deviceId, lastSeen, locationMapHierarchy, 
                locationCoordinateX, locationCoordinateY, 
                locationCoordinateUnit, geoCoordinateLat, 
                geoCoordinateLong, geoCoordinateUnit)
        VALUES (InputJSON.deviceId, InputJSON.lastSeen, InputJSON.locationMapHierarchy, 
                InputJSON.locationCoordinateX, InputJSON.locationCoordinateY, 
                InputJSON.locationCoordinateUnit, InputJSON.geoCoordinateLat, 
                InputJSON.geoCoordinateLong, InputJSON.geoCoordinateUnit);
END

似乎ON 语句是问题所在。我想从 JSON 对象 (SQL Server 2016) 中进行选择,如果我的 Location_CVT 表中的设备 ID 匹配,请更新此条目,否则插入新记录。

我正在尝试做类似于以下示例的操作。

MERGE INTO Person AS P
USING (
    SELECT *
    FROM  OPENJSON(@json)
          WITH (id int, firstName nvarchar(50), lastName nvarchar(50),
                age int, dateOfBirth datetime2) InputJSON
    ON (P.id = InputJSON.id)
WHEN MATCHED THEN
    UPDATE SET P.firstName = InputJSON.firstName,
               P.lastName = InputJSON.lastName,
               P.age = InputJSON.age,
               P.dateOfBirth = InputJSON.dateOfBirth
WHEN NOT MATCHED THEN
    INSERT (firstName, lastName, age, dateOfBirth)
    VALUES (InputJSON.firstName, InputJSON.lastName, InputJSON.age, 
            InputJSON.dateOfBirth);

来源:https://www.codeproject.com/Articles/1087995/Inserting-JSON-Text-into-SQL-Server-Table

【问题讨论】:

  • 你的括号在源子查询后面的位置错误,应该是...nvarchar(64))) AS InputJSON ON ...而不是...nvarchar(64)) AS InputJSON) ON ...
  • 尝试删除)之后的AS InputJSON
  • @GarethD 当我这样做时, InputJSON. 对于其余的查询变得无效。
  • @Xedni,我最初也是这样认为的,但这只会在下面的其余语句关键字和大部分 '.'、'=' 和 ',' 上产生语法错误跨度>

标签: sql-server merge


【解决方案1】:

如果你的括号跨越多行,你确保你的左括号和右括号有一致的缩进,问题就变得更清楚了(至少对我来说是这样)。

MERGE INTO Location_CVT AS C
USING 
(   SELECT 
        deviceID, lastSeen, locationMapHierarchy, locationCoordinateX, 
        locationCoordinateY, locationCoordinateUnit, geoCoordinateLat,
        geoCoordinateLong, geoCoordinateUnit
    FROM 
        OPENJSON(@Location_NotificationJson)
    WITH 
        (   deviceId nchar(17),
            lastSeen varchar(128),
            locationMapHierarchy nvarchar(256),
            locationCoordinateX float,
            locationCoordinateY float,
            locationCoordinateUnit nvarchar(64),
            geoCoordinateLat float,
            geoCoordinateLong float,
            geoCoordinateUnit nvarchar(64)
        ) AS InputJSON
)   ------------------------------------------------- ISSUE IS HERE
    ON (C.deviceId = InputJSON.deviceId)        
WHEN MATCHED THEN
    UPDATE 
        SET C.deviceId = InputJSON.deviceId,
            C.lastSeen = InputJSON.lastSeen,
            C.locationMapHierarchy = InputJSON.locationMapHierarchy,
            C.locationCoordinateX = InputJSON.locationCoordinateX,
            C.locationCoordinateY = InputJSON.locationCoordinateY,
            C.locationCoordinateUnit = InputJSON.locationCoordinateUnit,
            C.geoCoordinateLat = InputJSON.geoCoordinateLat,
            C.geoCoordinateLong = InputJSON.geoCoordinateLong,
            C.geoCoordinateUnit = InputJSON.geoCoordinateUnit

您现在可以看到,您用于源的子查询没有别名。应该是:

MERGE INTO Location_CVT AS C
USING 
(   SELECT 
        deviceID, lastSeen, locationMapHierarchy, locationCoordinateX, 
        locationCoordinateY, locationCoordinateUnit, geoCoordinateLat,
        geoCoordinateLong, geoCoordinateUnit
    FROM 
        OPENJSON(@Location_NotificationJson)
    WITH 
        (   deviceId nchar(17),
            lastSeen varchar(128),
            locationMapHierarchy nvarchar(256),
            locationCoordinateX float,
            locationCoordinateY float,
            locationCoordinateUnit nvarchar(64),
            geoCoordinateLat float,
            geoCoordinateLong float,
            geoCoordinateUnit nvarchar(64)
        ) AS InputJSON
) AS InputJSON                              -- ALIAS ADDED HERE
    ON (C.deviceId = InputJSON.deviceId)    
WHEN MATCHED THEN
    UPDATE 
        SET C.deviceId = InputJSON.deviceId,
            C.lastSeen = InputJSON.lastSeen,
            C.locationMapHierarchy = InputJSON.locationMapHierarchy,
            C.locationCoordinateX = InputJSON.locationCoordinateX,
            C.locationCoordinateY = InputJSON.locationCoordinateY,
            C.locationCoordinateUnit = InputJSON.locationCoordinateUnit,
            C.geoCoordinateLat = InputJSON.geoCoordinateLat,
            C.geoCoordinateLong = InputJSON.geoCoordinateLong,
            C.geoCoordinateUnit = InputJSON.geoCoordinateUnit

【讨论】:

  • 这解决了关键字“ON”附近语法不正确的问题,但它引入了“InputJSON”别名的问题,其中 ON 条件、SET 和 VALUE 都是无效的列名。在第二个别名之前是否需要额外的 WITH 语句?
  • 转到原始问题,评论太长了。
  • Location_CVT 中是否存在这些列?确切的错误信息是什么?
  • 是的。我可以执行 SP,但是当它运行时 SQL 抱怨关联的语句没有准备好。我认为我们与最初的问题相差甚远,因此我将自行解决更多问题,并可能为此创建一个新问题。
猜你喜欢
  • 2011-09-12
  • 2013-01-23
  • 2023-03-05
  • 2016-11-30
  • 1970-01-01
  • 2010-12-15
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多