我想解决的问题:
我有一个SAS数据集work.testData
(在工作库中),包含8列和大约100万行。所有列都是文本(即没有数字数据)。此SAS数据集的文件大小约为100 MB。我的目标是将整个SAS数据集解析为Oracle。即有点像SAS数据集从SAS平台到Oracle平台的“复制和粘贴”。这背后的基本原理是,Oracle中的这个表每天都被SAS中的表替换,这将启用下游Oracle进程。
我解决问题的方法:
Oracle中的一次性初始设置:
testData
的表,其表结构与SAS数据集testData
几乎完全相同。 (即相同的表名,相同的列数,相同的列名等)。正在进行的重复过程:
示例代码
Oracle中的一次性初始设置:
步骤1:在Oracle SQL Developer中运行此Oracle SQL脚本(为表testData创建表结构。开始使用0行数据。)
DROP TABLE testData;
CREATE TABLE testData
(
NODENAME VARCHAR2(64) NOT NULL,
STORAGE_NAME VARCHAR2(100) NOT NULL,
TS VARCHAR2(10) NOT NULL,
STORAGE_TYPE VARCHAR2(12) NOT NULL,
CAPACITY_MB VARCHAR2(11) NOT NULL,
MAX_UTIL_PCT VARCHAR2(12) NOT NULL,
AVG_UTIL_PCT VARCHAR2(12) NOT NULL,
JOBRUN_START_TIME VARCHAR2(19) NOT NULL
)
;
COMMIT;
正在进行的重复过程:
步骤2,3和4:在SAS中运行此SAS代码
******************************************************;
******* On-going repeatable process starts here ******;
******************************************************;
*** Step 2: Trancate the temporary Oracle transaction dataset;
proc sql;
connect to oracle (user=XXX password=YYY path=ZZZ);
execute (
truncate table testData
) by oracle;
execute (
commit
) by oracle;
disconnect from oracle;
quit;
*** Step 3: Assign Oracle DB as a libname;
LIBNAME ora Oracle user=XXX password=YYY path=ZZZ dbcommit=100000;
*** Step 4: Insert data from SAS to Oracle;
PROC SQL;
insert into ora.testData
select NODENAME length=64,
STORAGE_NAME length=100,
TS length=10,
STORAGE_TYPE length=12,
CAPACITY_MB length=11,
MAX_UTIL_PCT length=12,
AVG_UTIL_PCT length=12,
JOBRUN_START_TIME length=19
from work.testData;
QUIT;
******************************************************;
**** On-going repeatable process ends here *****;
******************************************************;
我的方法的限制/问题:
Proc SQL步骤(将100 MB数据从SAS传输到Oracle)大约需要5个小时才能完成 - 这项工作需要很长时间才能运行!
问题:
有没有更明智的方法来执行从SAS到Oracle的数据传输? (即从SAS更新Oracle表)。
答案 0 :(得分:4)
首先,如果必要,您可以从SAS进行删除/重新创建。我不会每次都丢弃并重新创建 - 截断似乎更容易得到相同的结果 - 但如果你有其他原因那么那很好;但无论哪种方式,您都可以使用execute (truncate table xyz) from oracle
或类似方式使用传递连接。
其次,假设桌面上没有约束或索引 - 这似乎可能会让您丢弃并重新创建它 - 您可能无法改进这一点,因为它可能基于网络延迟。但是,您应该在连接设置中查看一个区域(您未提供):SAS提交数据的频率。
有两种方法可以控制此设置,DBCOMMMIT设置和BULKLOAD设置。前者控制提交执行的频率(因此,如果DBCOMMIT=100
则每100行执行一次提交)。更频繁的提交=如果发生随机故障,则丢失的数据更少,但执行速度要慢得多。对于PROC SQL INSERT
,DBCOMMIT默认为0,这意味着只进行一次提交(假设没有错误的最快选项),所以除非你覆盖它,否则这不太可能有用。
批量加载可能是我的建议;它使用SQLLDR加载你的数据,即它将整个批量批量转移到Oracle,然后说“请加载这个,谢谢”。它只适用于某些设置和某些类型的查询,但它应该在这里工作(根据其他条件 - 阅读上面的文档页面)。
如果您正在使用BULKLOAD,那么您可能会遇到网络延迟。 100 MB的5个小时看起来很慢,但我在(相对较短的)日里看到了各种各样的事情。如果BULKLOAD不起作用,我可能会引入Oracle DBA并让它们对此进行故障排除,从.csv文件和SQL * LDR命令文件开始(这应该与SAS在BULKLOAD中的操作基本相同);他们应该知道如何排除故障并至少能够监控数据库本身的性能。如果这里存在其他表有问题的限制(例如,其他表太频繁地根据您的插入或其他任何方式重新计算),他们应该能够找到并推荐解决方案。
您可以查看PROC DBLOAD
,它有时比SQL中的插入更快(尽管总的来说不应该是,并且是'旧的'过程不再使用太多)。您还可以查看是否可以避免执行完全刷新和填充(即,是否有通过网络传输较少数据的方法),甚至只是缩小列大小。