文档首页/ 数据仓库服务 GaussDB(DWS)/ 故障排除/ 数据库使用/ 业务报错:unable to get a stable set of rows in the source table
更新时间:2024-11-01 GMT+08:00

业务报错:unable to get a stable set of rows in the source table

问题现象

执行MERGE INTO将源表内容根据匹配条件对目标表做更新报错unable to get a stable set of rows in the source table。

现有目标表products和源表newproducts,以源表newproducts中product_id为1502为匹配条件,对目标表进行更新报错:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
CREATE TABLE products (product_id INTEGER,product_name VARCHAR2(60),category VARCHAR2(60));

INSERT INTO products VALUES (1501, 'vivitar 35mm', 'electrncs'),(1502, 'olympus is50', 'electrncs'),(1600, 'play gym', 'toys');

CREATE TABLE newproducts (product_id INTEGER,product_name VARCHAR2(60),category VARCHAR2(60));

INSERT INTO newproducts VALUES (1502, 'olympus camera', 'electrncs'),(1600, 'lamaze', 'toys'),(1502, 'skateboard', 'toy');

MERGE INTO products p
  USING newproducts np
  ON (p.product_id = np.product_id)
  WHEN MATCHED THEN
  UPDATE SET p.product_name = np.product_name, p.category = np.category WHERE np.product_id = 1502;
ERROR:  dn_6003_6004: unable to get a stable set of rows in the source tables

原因分析

源表newproducts中product_id为1502的数据有两条,且参数behavior_compat_options缺省,因此MERGE INTO时匹配到多条数据报错。

MERGE INTO的作用是将源表内容根据匹配条件对目标表做更新或插入,当目标表匹配到多行满足条件时,GaussDB(DWS)有以下两种行为:

  1. 业务报错:unable to get a stable set of rows in the source table。
  2. 随机匹配一行数据,可能会导致实际与预期不符。

这两种行为由参数behavior_compat_options控制,当参数behavior_compat_options缺省的情况下,匹配到多行会报错,如果behavior_compat_options被设置为merge_update_multi,则不会报错,而是会随机匹配一行数据。

因此,当出现merge into的结果与预期不符的情况时,需查看该参数是否被设置,同时排查是否匹配了多行数据,并根据实际情况修改业务逻辑。

解决方案

  • 方案一:设置参数behavior_compat_options为merge_update_multi。
    当目标表匹配到多行满足条件时,该方案不会报错,而是会随机匹配一行数据,有数据遗漏风险。
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    SET behavior_compat_options=merge_update_multi;
    
    MERGE INTO products p
      USING newproducts np
      ON (p.product_id = np.product_id)
      WHEN MATCHED THEN
      UPDATE SET p.product_name = np.product_name, p.category = np.category WHERE np.product_id = 1502;
    MERGE 1
    
    SELECT * FROM products ;
     product_id |  product_name  | category
    ------------+----------------+-----------
           1501 | vivitar 35mm   | electrncs
           1502 | olympus camera | electrncs
           1600 | play gym       | toys
    (3 rows)
    
  • 方案二:修改MERGE INTO匹配条件。

    尽可能选择筛选结果唯一的表达式为匹配条件。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    MERGE INTO products p
      USING newproducts np
      ON (p.product_id = np.product_id)
      WHEN MATCHED THEN
      UPDATE SET p.product_name = np.product_name, p.category = np.category WHERE np.product_id != 1502;
    MERGE 1
    
    SELECT * FROM products;
     product_id |  product_name  | category
    ------------+----------------+-----------
           1501 | vivitar 35mm   | electrncs
           1502 | olympus camera | electrncs
           1600 | lamaze         | toys
    (3 rows)