【问题标题】:oracle delete data from remote SQL Server tableoracle 从远程 SQL Server 表中删除数据
【发布时间】:2011-01-20 19:48:00
【问题描述】:

使用下面的过程,我们试图将数据从 SQL Server 传输到 oracle,但是我们得到了错误:

Tarih : 20/01/2011, Hata yeri :
pr_get_customer,Hata Açıklaması:
-28500 => v_trace : 2,v_transfer_id :1ORA-28500: ORACLE 系统 Oracle olmayan sisteme bağlantı şu mesajı
威尔第:[Oracle][ODBC SQL Server
Driver][SQL Server]多部分 标识符
“PUBLIC.TMP_CUSTOMER.TRANSFER_ID” 无法绑定。 {42000,NativeErr = 4104} ORA-02063:önceki 2 行, kaynağı DBLINK_NAV2

v trace 是我们定位错误区域的变量,transfer_id 取值。

这里列出了程序:

PROCEDURE pr_get_customer
   IS
      CURSOR cur_tmp_customer
      IS
         SELECT "TRANSFER_ID" AS transfer_id, "INSERT_DATE" AS insert_date,
                "OP_TYPE" AS op_type, "STATUS" AS status, "No_" AS NO,
                "Name" AS NAME, "Name 2" AS name_2, "Address" AS address,
                "Address 2" AS address_2, "City" AS city,
                "Phone No_" AS phone_no, "Chain Name" AS chain_name,
                "Customer Price Group" AS customer_price_group,
                "Blocked" AS blocked,
                "Bill-to Customer No_" AS bill_to_customer_no,
                "Fax No_" AS fax_no, "SUBE" AS sube, "Alt Grup" AS alt_grup,
                "Location Code" AS location_code
           FROM nav_tmp_customer
          WHERE "STATUS" = 0
            AND ("TRANSFER_ID" > (SELECT NVL (MAX (transfer_id), 0)
                                    FROM t_tmp_customer));

      r_tmp_customer     cur_tmp_customer%ROWTYPE;

      TYPE tmp_customer_tbl_typ IS TABLE OF cur_tmp_customer%ROWTYPE;

      tmp_customer_tbl   tmp_customer_tbl_typ       := tmp_customer_tbl_typ
                                                                           ();
      v_trace            INTEGER                    := 0;
      v_transfer_id      NUMBER (28, 0)             := 0;
   BEGIN
      OPEN cur_tmp_customer;

      FETCH cur_tmp_customer
      BULK COLLECT INTO tmp_customer_tbl;

      CLOSE cur_tmp_customer;

      FOR x IN 1 .. tmp_customer_tbl.COUNT ()
      LOOP
         BEGIN
            v_trace := 1;

            INSERT INTO esiparis.t_tmp_customer
                        (transfer_id,
                         insert_date,
                         op_type,
                         status,
                         NO, NAME,
                         name2,
                         address,
                         address2,
                         city,
                         phone_no,
                         chain_name,
                         customer_price_group,
                         blocked,
                         bill_to_customer_no,
                         location_code,
                         fax_no,
                         sube,
                         alt_grup
                        )
                 VALUES (tmp_customer_tbl (x).transfer_id,
                         tmp_customer_tbl (x).insert_date,
                         tmp_customer_tbl (x).op_type,
                         tmp_customer_tbl (x).status,
                         tmp_customer_tbl (x).NO, tmp_customer_tbl (x).NAME,
                         tmp_customer_tbl (x).name_2,
                         tmp_customer_tbl (x).address,
                         tmp_customer_tbl (x).address_2,
                         tmp_customer_tbl (x).city,
                         tmp_customer_tbl (x).phone_no,
                         tmp_customer_tbl (x).chain_name,
                         tmp_customer_tbl (x).customer_price_group,
                         tmp_customer_tbl (x).blocked,
                         tmp_customer_tbl (x).bill_to_customer_no,
                         tmp_customer_tbl (x).location_code,
                         tmp_customer_tbl (x).fax_no,
                         tmp_customer_tbl (x).sube,
                         tmp_customer_tbl (x).alt_grup
                        );

            COMMIT;
            v_trace := 2;
            v_transfer_id := tmp_customer_tbl (x).transfer_id;

            DELETE FROM nav_tmp_customer
                  WHERE "TRANSFER_ID" = v_transfer_id;

            COMMIT;
            v_trace := 3;
         EXCEPTION
            WHEN OTHERS
            THEN
               ROLLBACK;
               pck_helper.pr_log_error (SQLCODE,
                                           'v_trace : '
                                        || v_trace
                                        || ',v_transfer_id :'
                                        || v_transfer_id
                                        || SQLERRM,
                                        'pr_get_customer'
                                       );
         END;
      END LOOP;
   EXCEPTION
      WHEN OTHERS
      THEN
         ROLLBACK;
         pck_helper.pr_log_error (SQLCODE,
                                  'v_trace : ' || v_trace || ',' || SQLERRM,
                                  'pr_get_customer'
                                 );
   END pr_**strong text****strong text****strong text**get_customer;

感谢任何想法,


更新: 工作流程如下

PROCEDURE pr_get_item
IS
  CURSOR cur_tmp_item
  IS
     SELECT "TRANSFER_ID" AS transfer_id, "INSERT_DATE" AS insert_date,
            "OP_TYPE" AS op_type, "STATUS" AS status, "No_" AS NO,
            "Description" AS description,
            "Base Unit of Measure" AS base_unit_of_measure,
            "Inventory Posting Group" AS inventory_posting_group,
            "Net Weight" AS net_weight,
            "Genel Ürün Sahibi" AS genel_urun_sahibi,
            "Tab Code" AS tab_code,
            "Tab Unit of Measure" AS tab_unit_of_measure,
            "TAB Qty_ per Unit of Measure"
                                          AS tab_qty_per_unit_of_measure,
            "Blocked 2" AS blocked_2
       FROM nav_tmp_item
      WHERE "STATUS" = 0
        AND ("TRANSFER_ID" > (SELECT NVL (MAX (transfer_id), 0)
                                FROM t_tmp_item));

  r_tmp_item     cur_tmp_item%ROWTYPE;

  TYPE tmp_item_tbl_typ IS TABLE OF cur_tmp_item%ROWTYPE;

  tmp_item_tbl   tmp_item_tbl_typ       := tmp_item_tbl_typ ();
  v_trace        INTEGER                := 0;
  v_count        NUMBER (28, 0)         := 1;
BEGIN
  OPEN cur_tmp_item;

  FETCH cur_tmp_item
  BULK COLLECT INTO tmp_item_tbl;

  CLOSE cur_tmp_item;

  FOR x IN 1 .. tmp_item_tbl.COUNT ()
  LOOP
     BEGIN
        v_trace := 1;

        INSERT INTO esiparis.t_tmp_item
                    (transfer_id,
                     insert_date,
                     op_type, status,
                     NO, description,
                     base_unit_of_measure,
                     inventory_posting_group,
                     net_weight,
                     genel_urun_sahibi,
                     tab_code,
                     tab_unit_of_measure,
                     tab_qty_per_unit_of_measure,
                     blocked_2
                    )
             VALUES (tmp_item_tbl (x).transfer_id,
                     tmp_item_tbl (x).insert_date,
                     tmp_item_tbl (x).op_type, tmp_item_tbl (x).status,
                     tmp_item_tbl (x).NO, tmp_item_tbl (x).description,
                     tmp_item_tbl (x).base_unit_of_measure,
                     tmp_item_tbl (x).inventory_posting_group,
                     tmp_item_tbl (x).net_weight,
                     tmp_item_tbl (x).genel_urun_sahibi,
                     tmp_item_tbl (x).tab_code,
                     tmp_item_tbl (x).tab_unit_of_measure,
                     tmp_item_tbl (x).tab_qty_per_unit_of_measure,
                     tmp_item_tbl (x).blocked_2
                    );

        COMMIT;
        v_trace := 2;

        DELETE FROM nav_tmp_item
              WHERE "TRANSFER_ID" = tmp_item_tbl (x).transfer_id;

        COMMIT;
        v_trace := 3;
     EXCEPTION
        WHEN OTHERS
        THEN
           ROLLBACK;
           pck_helper.pr_log_error (SQLCODE,
                                    'v_trace : ' || v_trace || ','
                                    || SQLERRM,
                                    'pr_get_item'
                                   );
     END;
  END LOOP;
EXCEPTION
  WHEN OTHERS
  THEN
     ROLLBACK;
     pck_helper.pr_log_error (SQLCODE,
                              'v_trace : ' || v_trace || ',' || SQLERRM,
                              'pr_get_item'
                             );
END pr_get_item;

【问题讨论】:

  • 当您在循环中提交 TWICE 时,错误处理程序中的回滚有什么意义?
  • 斯蒂芬妮,逻辑点。我们试图通过迭代添加到过程中。这个过程是从一个类似的过程中派生出来的,在那个过程中——同样的错误仍然存​​在——我们测试了先获取数据,然后再删除远程数据库。
  • 另一点是它给出了一个错误,我没有准确记录它,但我们只能通过删除表来恢复它。如果那是生产数据库,那将是不可接受的 :( .. 在远程删除时使用调试跟踪代码时发生错误。
  • 所以这不是确切的代码,它为调试做了调整。好的,那么您确定您在 SQL Server 端具有 DELETE 权限吗?
  • 是的,唯一的区别是表,nav_tmp_customer 是 symb。链接到 sql server 上的 tmp_customer,nav_tmp_item 是 symb。在另一个 proc 的 sql server 上链接到 tmp_item。 tmp 客户的名称字段有问题,因此我们必须通过将 VARCHAR 更改为 NVARCHAR 来重新创建表

标签: sql-server oracle transfer


【解决方案1】:

我认为更好的问题是:将数据从 SQL Server 移动到 Oracle 的最佳方法是从 MSSS 中删除每个成功交付的行?

您在循环中执行这些操作,以确保当您添加到一个时,您会从另一个中删除。

如果插入时发生了一些未知的随机错误,您将避免删除源记录。

这就是要点,对吧?

有更好的方法来处理这种数据移动,然后在每个插入/删除分布式事务循环之后提交。

首先在循环中间提交是很糟糕的。在 Oracle 中,这是导致其他会话出现 ORA-01555 错误的好方法。因此,如果可能的话,我会避免这种情况。

其次,您应该绝对知道插入时出现合理错误的可能原因是什么。您违反了列长度,FK,UK ...插入时可能会中断的内容有限。像无法扩展表空间这样的大毛病应该导致系统停止运行。没有必要为此而设下陷阱。但是我提到的应用程序问题很容易解决。

如果我正在写这篇文章,我会使用 Oracle 的 LOG ERRORS INTO 批量插入所有行,以避免在只有一行/几行失败时发生完整的 ROLLBACK。

现在您有一个表,其中包含每个失败的行及其失败的原因。现在您可以在 SQL Server 端删除所有不在失败 ID 列表中的行。

您已经完成了同样的事情,但是使用基于 Set 的操作而不是 SLOW-BY-SLOW,哎呀,我的意思是逐行。

【讨论】:

  • 嗯,好点。非常感谢您提供 LOG_ERRORS_INTO 提示。 ORA-28534:异构服务预处理错误现在是这个故事的一部分,因为日期时间字段。这次我们尝试将订单从 Oracle 发送到 Sql-Server。不知道我是否能活到足以看到 ORA-001 没有错误的生活是美好的
  • 循环中的一点是,避免删除在我的过程中刚刚插入的源记录。我必须将数字保留在 VARRAY 或其他内容中,然后我必须使用 LOG ERRORS INTO 减去以获取要删除的源记录的 ID 号。
  • 我不明白最后的评论。你有一大把要移动的行。你是说那个拳头的定义并不简单。我会猜到这是所有带有时间戳的行 > 比我上次移动它们时 在那个时间范围内的所有其他内容。你是说范围不是这么容易定义的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-31
  • 2023-02-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多