我们有超过30个Oracle查询文件,其中包含存储过程和SQL查询。
我尝试通过创建一个批处理脚本来自动化该过程,该脚本调用包含文件名的文本文件“driverssql.txt”。以下是批处理脚本:
@echo off
setlocal enabledelayedexpansion
>output.txt
( for /f %%a in (driversql.txt) do (
sqlplus uname/pwd@"(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXXXX) (PORT=1521)))(CONNECT_DATA=(SID=XXXXX)))" "%%a"
))
上面的脚本运行良好,但问题是每次脚本循环时,它会创建一个连接,这是一种浪费,而不是处理此问题的最佳方法。
当我将连接放在循环外部时,连接成功但在此之后SQLPlus窗口处于挂起状态并且不执行查询。请提出更好的方法来实现这一目标。
答案 0 :(得分:0)
@ECHO OFF
SETLOCAL
SET "list="
FOR /f %%i IN (driversql.txt) DO (
CALL SET list=%%list%% "%%i"
)
ECHO sqlplus uname/pwd@"(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=XXXXXX) (PORT=1521)))(CONNECT_DATA=(SID=XXXXX)))"%list%
我相信我们需要知道的是SQLPLUS
如何运作。
上面的代码所做的是将所有文件名累积到一个列表中,以空格分隔和引用。它可能会工作 - 一切都取决于你如何使用一个SQLPLUS
命令级联操作sql1.sql然后sql2.sql ...
那么,如何能够控制哪些[一组] SQL文件被执行,以及以什么顺序执行?
我假设您可以简单地将.SQL文件连接成一个如果不是这样,那么现在就停止阅读......
@ECHO OFF
SETLOCAL
:tloop
SET tempfile=%RANDOM%
IF EXIST "%temp%\%tempfile%*" GOTO tloop
COPY NUL "%temp%\%tempfile%.1" >nul
FOR /f %%s IN (sqlsched.txt) DO (
FOR /f "tokens=1,2" %%i IN (%%s) DO (
FINDSTR /i /b /e /c:"%%i" "%temp%\%tempfile%.1" >nul
IF ERRORLEVEL 1 (SET "excludeme=") ELSE (SET excludeme=Y)
IF /i "%%j"=="again" (SET "excludeme=")
IF NOT DEFINED excludeme (>>"%temp%\%tempfile%.1" ECHO %%i)
)
)
TYPE "%temp%\%tempfile%.1"
(
FOR /f "delims=" %%i IN ('type "%temp%\%tempfile%.1"') DO type %%i
)>humungous.sql
DEL "%temp%\%tempfile%.1"
假设我们有一个文件SQLSCHED.TXT,内容
daily1.txt
special.txt
daily2.txt
weekly1.txt
,例如daily2.txt包含
D0S9.sql
D2S1.sql
D0S0.sql
D2S1.sql
D0S9.sql again
然后,此批次将首先阅读sqlsched.txt
,然后依次处理每个文件daily1.txt
,special.txt
,daily2.txt
,weekly1.txt
,从而产生临时文件。
逐行读取临时文件将生成humungous.sql
,其中包含所提到的每个sql文件的所有内容。您只需使用sqlplus
humungous.sql
即可
我已经包含了一些智能 - 如果你重建了一个SQL文件名humungous.sql
,那么该过程只包含一次,所以在daily2.txt
列表中,第二个将跳过D2S1.sql
。但是,由于D0S9.sql
标记,again
将再次运行。
如果需要,可以进行扩展 - 例如,如果您在变量中有当前的日期名称,那么您可以添加该行
IF /i NOT "%%j"=="%dayname%" (SET "excludeme=Y")
和行
dWdX.sql Wed
确保WdX.sql
只能在星期三运行