
# 业务报错：unable to get a stable set of rows in the source table
#### 问题现象
ORA和TD数据库兼容模式下，执行MERGE INTO将源表内容根据匹配条件对目标表进行更新报错：unable to get a stable set of rows in the source table。
现有目标表products和源表newproducts，以源表newproducts中product_id为1502为匹配条件，对目标表进行更新报错：
```
CREATE TABLE products (product_id INTEGER,product_name VARCHAR2(60),category VARCHAR2(60));
INSERT INTO products VALUES (1501, 'vivitar 35mm', 'electronics'),(1502, 'olympus is50', 'electronics'),(1600, 'play gym', 'toys');
CREATE TABLE newproducts (product_id INTEGER,product_name VARCHAR2(60),category VARCHAR2(60));
INSERT INTO newproducts VALUES (1502, 'olympus camera', 'electronics'),(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](https://support.huaweicloud.com/devg-dws/dws_04_0931.html#section2)缺省，因此MERGE INTO时匹配到多条数据报错。
MERGE INTO的作用是将源表内容根据匹配条件对目标表做更新或插入，当目标表匹配到多行满足条件时，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（仅针对ORA和TD兼容模式），则不会报错，而是会随机匹配一行数据。
因此，当出现merge into的结果与预期不符的情况时，需查看该参数是否被设置，同时排查是否匹配了多行数据，并根据实际情况修改业务逻辑。
#### 解决方案
- 方案一：设置参数behavior_compat_options为merge_update_multi。
  当目标表匹配到多行满足条件时，该方案不会报错，而是会随机匹配一行数据，有数据遗漏风险。
  ```
  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   | electronics
         1502 | olympus camera | electronics
         1600 | play gym       | toys
  (3 rows)
  ```
  
- 方案二：修改MERGE INTO匹配条件。 尽可能选择筛选结果唯一的表达式为匹配条件。
  ```
  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   | electronics
         1502 | olympus camera | electronics
         1600 | lamaze         | toys
  (3 rows)
  ```
  
 
