【问题标题】:Finding missing record via PLSQL procedure通过 PLSQL 过程查找丢失的记录
【发布时间】:2021-07-01 03:48:20
【问题描述】:

我有一种情况,我在本地数据库中有一个表,该表必须始终与服务器中的数据库保持同步。服务器数据库中的记录由第三方更新/删除/插入,我必须保持本地数据库与服务器同步。

我的本​​地机器在服务器中接收当前数据。假设服务器数据库有 4 条记录,我的本地机器接收这 4 条记录,我必须使用主键更新我的本地数据库。

当有人删除服务器数据库中的一条记录(只剩下3条记录)时,它只发送剩余的记录(本地数据库只接收3条记录)。

如何找到删除的记录。 (本地机器接收要使用的主键)。

我尝试了以下过程,但它似乎在服务器中找到了额外的详细信息,而不是删除的。

PROCEDURE CheckDeletedRecord ( primarykeyRecieved IN varchar, toDeletedPrimarykey OUT varchar) AS
    vStorePrimaryKey VARCHAR2(45);
    BEGIN
      SELECT t.primarykeyOfTable INTO vStorePrimaryKey FROM tableName t where t.primarykeyOfTable = primarykeyRecieved 
      
      IF vStorePrimaryKey = '' THEN
        toDeletedPrimarykey := primarykeyRecieved ;
      END IF;  

    END CheckDeletedInfections; 

【问题讨论】:

  • 使用存在/不存在的 sql 会有所帮助。
  • exist / not exists 适用于两个表。我只有一张表,其他记录在光标中
  • 你需要在EXCEPTION WHEN NO_DATA_FOUND中分配给toDeletedPrimaryKey
  • 为什么不截断表格然后插入所有新行。

标签: sql database plsql


【解决方案1】:

MERGEDELETE 的组合怎么样?您将在同一过程中执行所有操作,即您不必“返回”任何内容(作为OUT 参数)。像这样的:

create or replace procedure p_check (pkrec in varchar2) is
begin
  -- if pkrec represents new or updated row
  merge into local_table a
    using server_table b
    on (a.pkrec = b.pkrec)
    when matched then update set (a.col1 = b.col1,
                                  a.col2 = b.col2, ...
                                 )
    when not matched then insert (pkrec, col1, col2, ...)
      values (pkrec, b.col1, b.col2, ...);

  -- remove rows which are deleted in the server table  
  delete from local_table a
    where not exists (select null 
                      from server_table b
                      where b.pkrec = a.pkrec
                     );
end;                     

【讨论】:

  • 如果我有两个表(local_table 和 server_table),这将起作用。但我只有一张表,即 local_table。服务器表的数据在游标中
  • 来自“服务器”的数据如何到达您的“本地”机器?在一个文件中?如果是这样,请将其用作外部表(这样上面的代码就可以工作)。如果没有,那怎么办?
  • 数据以加密方式直接保存在数据库表中。然后使用 Views 解密加密的数据,然后使用 refcursors 处理其余部分。
  • 那“数据库表”是什么?本地数据库中的另一个表,对吗?如果是这样,您确实有两个表可以使用 - 一个是“本地表”,另一个是“本地数据库中的表,其中包含从服务器表发送的行”。如果是这种情况,为什么还需要本地数据库中的另一个表?为什么不使用基于包含来自服务器的数据集的表来呈现解密数据的视图?
【解决方案2】:

SELECT INTO 当查询的行不存在时抛出NO_DATA_FOUND,所以(dummy 是我的测试表):

CREATE PROCEDURE CheckDeletedRecord ( primarykeyRecieved IN varchar, toDeletedPrimarykey OUT varchar) AS

  vStorePrimaryKey varchar(45);

BEGIN
     SELECT t.primaryKey INTO vStorePrimaryKey FROM dummy t where t.primaryKey = primarykeyRecieved;
     
EXCEPTION 
    WHEN NO_DATA_FOUND THEN
            toDeletedPrimarykey :=  primarykeyRecieved ;

END CheckDeletedRecord; 
/ 

写了一个存储函数来测试它:

CREATE FUNCTION todelete (primarykeyRecieved IN varchar) return  varchar IS
l_retval  varchar(45) := ''; 
BEGIN
CheckDeletedRecord(primarykeyRecieved, l_retval);
return l_retval;
END;
/

测试准备:

insert into dummy values('EXISTS');

测试:

select todelete('EXISTS') from dual;

输出

null

不存在测试

select todelete('EXISTS NOT') from dual;

输出

EXISTS NOT

把它做成了

db-fiddle

【讨论】:

    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-15
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多