我有以下问题,我有一个用DBI CPAN模块Perl执行的SQL文件 我在这个网站上看到了两个解决方案来解决我的问题。
那么,哪一种更好,哪种解决方案之间真正的区别呢?
修改
这是一个图书馆。我需要检索输出和返回代码。
传递的文件类型如下:
set serveroutput on;
set pagesize 20000;
spool "&1."
DECLARE
-- Récupération des arguments
-- &2: FLX_REF, &3: SVR_ID, &4: ACQ_STT, &5: ACQ_LOG, &6: FLX_COD_DOC, &7: ACQ_NEL, &8: ACQ_TYP
VAR_FLX_REF VARCHAR2(100):=&2;
VAR_SVR_ID NUMBER(10):=&3;
VAR_ACQ_STT NUMBER(4):=&4;
VAR_ACQ_LOG VARCHAR2(255):=&5;
VAR_FLX_COD_DOC VARCHAR2(30):=&6;
VAR_ACQ_NEL NUMBER(10):=&7;
VAR_ACQ_TYP NUMBER:=&8;
BEGIN
INSERT INTO ACQUISITION_CFT
(ACQ_ID, FLX_REF, SVR_ID, ACQ_DATE, ACQ_STT, ACQ_LOG, FLX_COD_DOC, ACQ_NEL, ACQ_TYP)
VALUES
(TRACKING.SEQ_ACQUISITION_CFT.NEXTVAL, ''VAR_FLX_REF'',
''VAR_SVR_ID'', sysdate, VAR_ACQ_STT, ''VAR_ACQ_LOG'',
''VAR_FLX_COD_DOC'', VAR_ACQ_NEL, VAR_ACQ_TYP);
END;
/
exit;
我还有另一个问题要问,再次使用DBI Oracle模块。 我可以为SQL文件和Control文件使用相同的代码吗?
(SQL控制文件示例)
LOAD DATA
APPEND INTO TABLE DOSSIER
FIELDS TERMINATED BY ';'
(
DSR_IDT,
DSR_CNL,
DSR_PRQ,
DSR_CEN,
DSR_FEN,
DSR_AN1,
DSR_AN2,
DSR_AN3,
DSR_AN4,
DSR_AN5,
DSR_AN6,
DSR_PI1,
DSR_PI2,
DSR_PI3,
DSR_PI4,
DSR_NP1,
DSR_NP2,
DSR_NP3,
DSR_NP4,
DSR_NFL,
DSR_NPG,
DSR_LTP,
DSR_FLF,
DSR_CLR,
DSR_MIM,
DSR_TIM,
DSR_NDC,
DSR_EMS NULLIF DSR_EMS=BLANKS "sysdate",
JOB_IDT,
DSR_STT,
DSR_DAQ "CASE WHEN :DSR_DAQ IS NOT NULL THEN SYSDATE ELSE NULL END"
)
答案 0 :(得分:1)
一次一行地读取一个表格会更复杂,但它可以使用更少的内存 - 只要您构建代码以使用每个项目的数据而不需要以后再使用它。
通常,您希望单独处理每个项目(例如,对数据进行处理),在这种情况下,您也可以使用逐行读取方法来定义循环。
我倾向于默认使用单指令方法,但是一旦我关注记录数量(特别是在长时间运行的批处理过程中),或者需要循环数据作为第一个任务,那么我读了记录一个接一个。
答案 1 :(得分:1)
事实上,你引用的两个答案提出了相同的解决方案,逐行阅读和执行(但第一点更清楚)。第二个问题有一个可选的答案,其中文件包含单个语句。
如果不逐行执行SQL,则很难捕获任何错误。
答案 2 :(得分:1)
“逐行”仅在每个SQL语句位于一行上时才有意义。您可能的意思是声明。
除此之外,它取决于您的SQL文件的样子以及您想要做的事情。
您的SQL文件有多复杂?它可能包含这样的内容吗?
select foo from table where column1 = 'bar;'; --Get foo; it will be used later.
按语句读取SQL文件语句的简单方法是使用分号(或语句分隔符所用的内容)进行拆分。但是如果你可能在其他地方有分号,例如注释或字符串,则此方法将失败。如果用分号拆分此语句,则会尝试执行以下四个“命令”:
select foo from table where column1 = 'bar;
';
--Get foo;
it will be used later.
显然,这些都不是有效的。正确处理这样的语句并非易事。您必须完全解析SQL以确定语句是什么。不幸的是,没有现成的模块可以为你做这件事(SQL::Script
是一个很好的开始SQL文件处理模块,但根据文档,它只是分裂在分号上。)
如果您的SQL文件很简单,那么在语句或注释中不包含任何语句分隔符;或者如果它以某种其他方式可预测(例如每行有一个语句),则很容易将文件拆分为语句并逐个执行。但是如果你必须处理任意的SQL语法,包括上面的情况,这将是一项复杂的任务。
什么样的任务?
如果这是您可以运行并忘记的事情,您可以让Perl执行系统命令,告诉Oracle处理该文件。这比自己处理所有语句更简单。但是如果你需要在Perl中处理结果或处理错误,那么自己按语句执行它将是必要的。
更新:根据您的响应,您希望编写一个可以处理任意SQL语句的库。在这种情况下,您肯定需要解析SQL并一次执行一个语句。这是可行的,但并不简单。 BEGIN...END
块的可能性意味着您必须能够在语句中正确处理分号。
SQL::Statement
class of modules可能会有所帮助。