Обновить таблицу Oracle из набора данных SAS

Как обновить таблицу Oracle в SAS из набора данных SAS?

Вот сценарий:

  1. Через имя библиотеки я загружаю таблицу Oracle в набор данных SAS.

  2. Произведите некоторую обработку данных, во время которой я ОБНОВЛЯЮ некоторые значения, ВСТАВЛЯЮ некоторые новые наблюдения и УДАЛЯЮ некоторые наблюдения в наборе данных.

  3. Мне нужно обновить исходную таблицу Oracle с помощью набора данных, который я изменил на предыдущем шаге, поэтому, когда есть совпадение между ключами таблицы Oracle и набором данных, значения будут обновлены, когда в таблица Oracle, тогда она будет вставлена, и когда есть ключ, который находится в таблице Oracle, но уже удален из набора данных, он будет удален из таблицы Oracle.

ПРИМЕЧАНИЕ. Я не могу создать новую таблицу в Oracle. Мне нужно сделать "обновление" по исходной таблице.

Я пытался сделать это в два этапа, используя MERGE INTO и DELETE, но в PROC SQL нет MERGE INTO. Буду очень признателен за любую помощь.

РЕДАКТИРОВАТЬ: Я также думал об усечении таблицы оракула и вставке строк (речь идет о 4-5000 строк на запуск процедуры), но похоже, что в PROC SQL нет встроенного оператора усечения.


person Martin    schedule 13.05.2017    source источник
comment
Хотя вы можете сделать это с помощью Sql pass в SAS, почему вы не можете выполнить обновление в самом Oracle? Кроме того, вместе с кодом укажите, что вы пробовали до сих пор.   -  person Praneeth Rachumallu    schedule 13.05.2017
comment
Это часть веб-службы SAS, которая вызывается в запросе SOAP. Таким образом, в основном это часть автоматизированного процесса в фоновом режиме, когда пользователи вызывают процедуру / веб-сервис. В общем, я не могу просто вызывать это все время в Oracle вручную. Я попробовал proc sql удалить все строки из таблицы Oracle, а затем вставить все наблюдения из набора данных в усеченную таблицу в Oracle. Измененные наблюдения обычно составляют 5-10% всех строк, поэтому я удаляю и вставляю ~~ 90% наблюдений без всякой причины.   -  person Martin    schedule 13.05.2017
comment
Он работает довольно быстро, я просто подумал, есть ли более эффективный способ.   -  person Martin    schedule 13.05.2017
comment
Разве вы не можете загрузить данные транзакции во временную таблицу oracle, а затем использовать явную передачу для обновления основной таблицы?   -  person Quentin    schedule 13.05.2017
comment
@Quentin благодарит за предложение, но это строгая схема, в которой я не могу создавать или удалять таблицы.   -  person Martin    schedule 14.05.2017


Ответы (2)


Пожалуйста, попробуйте использовать нижеприведенное,

Способ 1:

PROC SQL;
insert into <User_Defined_Oracle_table>
select variables
from <SAS_Tables>;
QUIT;

Выше создается таблица, которая находится в той же базе данных и схеме.

  PROC SQL;
    connect to oracle (user= oraclepwd=);
    execute(
    UPDATE <Oracle_table> a SET <Column to be updated> = (SELECT <Columns to update seperated by commas>
    FROM <SAS_table> b
    WHERE a.<VARIABLE>=b.<VARIABLE>)
    WHERE exists (select * from <SAS_table> b
    WHERE a.<VARIABLE>=b.<VARIABLE> ))
    by oracle;
    QUIT; 
    
    PROC SQL;
    connect to oracle
    (user= oraclepwd=};
    execute (truncate table <SAS_table>) by
    oracle;
    QUIT; 

Это один из эффективных способов обновить таблицу оракула. Дополнительную информацию см. На странице Update Oracle using SAS.

Способ 2:

LIBNAME Sample oracle user=  password= path=  schema= ; run;
PROC SQL;
UPDATE Sample_Oracle.<Table_Name> as a SET <Variable_Name> = (SELECT <Varibales>
FROM <Sas_table> as b
WHERE <A.Variable_Name>=<B.Variable_Name>)
WHERE exists
(select * from <Sas_table> as b
WHERE <A.Variable_Name>=<B.Variable_Name>);
QUIT; 

Этот метод занимает больше времени обработки всех методов.

Также,

Способ 3:

%MACRO update_oracle (SAS_Table,Oracle_Table); 

Proc sql ;
select count(*) into: Count_Obs from <SAS_Table> ; Quit;

%do i = 1 %to &Count_Obs;

Proc sql; 
select <variables to update seperated by commas> into: <macros> ; Quit;

PROC SQL;
UPDATE &Oracle_Table as a
SET <Oracle_Variable_to_Update>=<Variable_macro_created_above>
WHERE <A.Variable_Name>=<B.Variable_Name> 
QUIT;

%end;
%MEND update_oracle;
%update_oracle(); 

Макропеременные SAS_Table и Oracle_Table представляют набор данных SAS, который содержит записи для обновления и записи, которые необходимо обновить в oracle, соответственно.

Метод 3 использует меньше времени обработки, чем метод 2, но не так эффективен, как метод 1.

person Praneeth Rachumallu    schedule 13.05.2017
comment
Спасибо. Усеченный раствор оказался очень полезным. Проблема с решением для обновления заключается в том, что таблица b не является настоящей таблицей Oracle, вместо этого это только набор данных SAS. Так что в этом случае передача через SQL не является решением. Либо это? - person Martin; 13.05.2017
comment
Извините, @MartinToth, это должен быть SAS_Table. Я обновил код. Спасибо. - person Praneeth Rachumallu; 13.05.2017
comment
Ага, понятно. Попробую через несколько часов на своем рабочем ПК и напишу результат. Спасибо, что помогли мне. - person Martin; 13.05.2017
comment
Я не думаю, что это сработает, если вы сначала не загрузите набор данных SAS в Oracle. Без этого Oracle не сможет запросить набор данных SAS. - person Quentin; 13.05.2017
comment
@ Квентин, верно, я попробовал. К сожалению, чтобы использовать это решение, мне сначала нужно было бы загрузить набор данных в oracle. Так что это не работает, а я не могу, потому что у меня нет прав на создание таблиц. - person Martin; 14.05.2017
comment
@ Квентин, я понял ... Спасибо за внимание. Я отредактировал код. @ Martin Toth Я обновил еще 2 метода, которые вы можете использовать, даже если у вас нет доступа для создания таблиц в Oracle. Можете ли вы дать им шанс и сообщить нам о любых проблемах. - person Praneeth Rachumallu; 14.05.2017
comment
@PraneethKumar благодарит за предоставленные решения. Третий на самом деле довольно умен. Никогда не думал об использовании proc sql в цикле макроса% do. Я отмечаю ваш ответ как решение моей проблемы. - person Martin; 16.05.2017

Наверняка в proc SQL есть методы UPDATE и INSERT. Кроме того, проверьте, позволяет ли SAS выполнять другие операции SQL «немедленно» (например, разрешает PL / SQL), где вы можете построить оператор SQL в виде строки, а затем отправить ее в Oracle для выполнения.

person Roger Cornejo    schedule 13.05.2017
comment
Привет, Роджер. Спасибо за предложение. Мне известно об этом решении, но, к сожалению, вы не можете передавать объекты SAS, такие как набор данных, в код SQL. Он предназначен для выполнения непосредственно на сервере Oracle, а не на сервере SAS, но он может использовать в запросе только объекты Oracle. - person Martin; 13.05.2017