繁体   English   中英

如何使用 asp.net (vb.net) 执行 Oracle.SQL 脚本文件

[英]How to execute an Oracle .SQL script file using asp.net (vb.net)

The overall goal of what I am trying to do here is execute an Oracle SQL Script from as asp.net (vb.net) web application that has SQL*Plus commands in it that queries the data and drops the results to a text file and then display将文本文件发送给 web 应用程序的最终用户。 我在尝试在我的 Visual Studio 代码中执行 .sql 文件时遇到问题,它告诉我它不是有效的 SQL 语句。 当然这是有道理的,因为 .sql 文件中的内容比 sql 语句更多。

我在我的 Visual Studio 项目中使用 .NET 版本 4.6.1,我正在调用 Oracle 11 数据库。

这是我要执行的代码。 当它到达尝试执行脚本的行时,它会引发以下错误:

错误:Oracle.OracleException:'ORA-00900:无效的 SQL 语句'

这是 VB.NET 代码:

Dim OracleConnection As OracleConnection = New OracleConnection()
OracleConnection.ConnectionString = Settings.GetOracleConnectionString
OracleConnection.Open()
Dim script As String = File.ReadAllText("C:\OracleScripts\p_sum.sql")

Dim command As OracleCommand = OracleConnection.CreateCommand()
command.CommandText = script
command.ExecuteNonQuery()   << Errors on this line

.sql 文件对 Oracle 进行几次调用,然后将结果导出(假脱机)到 a.txt 文件。 一旦执行了 .sql 脚本,我就会显示在浏览器中创建的 .txt 文件。

我在下面提供了 .sql 文件的副本:

SPOOL data/p_sum.txt
PROMPT REPORT P_SUM.SQL Rev.04 (MIXER=&&MIXER) (CMPD=&&CMPD) (START=&&START) (END=&&END)
SET VERIFY OFF
SET LINESIZE 130

CLEAR BREAKS
CLEAR COMPUTES

COLUMN SHIFT_DT         FORMAT A6       HEADING Shift|Date
COLUMN SHIFT_NUM    FORMAT B9       HEADING Sh|#
COLUMN MIXER_NUM    FORMAT B99      HEADING Mix|Num
COLUMN RUN_START_DT FORMAT A12      HEADING Shift|Start
COLUMN COMPOUND     FORMAT A11      HEADING |Compound
COLUMN BAG_NAME     FORMAT A11      HEADING 'Bag Name'
COLUMN BAG_MIXER_NUM    FORMAT B99      HEADING Bag|Usr
COLUMN BATCH_CNT    FORMAT B99,999      HEADING Good|Cnt
COLUMN ERROR_CNT    FORMAT B999     HEADING Bad|Cnt
COLUMN EDIT_CNT     FORMAT B999     HEADING Edt|Cnt
COLUMN WT_PROD      FORMAT B999,999     HEADING Lbs/Kg|Produced
COLUMN TCHARGE      FORMAT B9999.9      HEADING Cycle|Min
COLUMN TDELAY       FORMAT B9999.9      HEADING Delay|Min
COLUMN TCHANGE      FORMAT B9999.9      HEADING Change|Min
COLUMN TNOTSCHED    FORMAT B9999.9      HEADING Unschd|Min
COLUMN RUN      FORMAT B99,999      HEADING Run|Min
COLUMN Avg_CHARGE   FORMAT B9.99        HEADING Cycle|Avg
COLUMN pct_up       FORMAT B999.9       HEADING '% Up|Time'

BREAK ON SHIFT_DT SKIP 1
CLEAR &&CLAUSE1

SELECT TO_CHAR(SHIFT_DT,' MM/DD') SHIFT_DT,
 R.SHIFT_NUM,
 TO_CHAR(MIN(R.RUN_START_DT),' MM/DD HH24:MI') RUN_START_DT,
 '*SHIFT' COMPOUND,
 'TOTAL ' BAG_NAME,
 SUM(R.BATCH_CNT)-NVL(SUM(R.ERROR_CNT),0) BATCH_CNT,
 SUM(R.ERROR_CNT) ERROR_CNT,
 SUM(EDIT_CNT)    EDIT_CNT,
 SUM(R.WT_PROD)   WT_PROD,
 SUM(R.TCHARGE)   TCHARGE,
 SUM(R.TDELAY)    TDELAY,
 SUM(R.TCHANGE)   TCHANGE,
 SUM(R.TNOTSCHED) TNOTSCHED,
 NVL(SUM(R.TCHARGE),0)+NVL(SUM(R.TDELAY),0)+NVL(SUM(R.TCHANGE),0)+NVL(SUM(R.TNOTSCHED),0) RUN,
 DECODE(SUM(R.BATCH_CNT)-SUM(R.ERROR_CNT),0,0,SUM(R.TCHARGE)/(SUM(R.BATCH_CNT)-SUM(R.ERROR_CNT))) AVG_CHARGE,
 SUM(R.TCHARGE)*100/(NVL(SUM(R.TCHARGE),0)+NVL(SUM(R.TDELAY),0)+NVL(SUM(R.TCHANGE),0)) PCT_UP
FROM MIXER.RUN_SUMM R, MIXER.SPEC S
WHERE R.SPEC_NUM=S.SPEC_NUM
  AND R.MIXER_NUM IN(&&MIXER)
  AND R.MIXER_NUM >=80
  AND SHIFT_DT BETWEEN TO_DATE('&&START','MM/DD/RR') AND TO_DATE('&&END','MM/DD/RR')
GROUP BY R.SHIFT_DT, R.SHIFT_NUM
UNION
SELECT TO_CHAR(R.SHIFT_DT,' MM/DD') SHIFT_DT,
 0 SHIFT_NUM,
 'ALL SHIFTS' RUN_START_DT,
 '**DAILY' COMPOUND,
 'TOTAL' BAG_NAME,
 SUM(R.BATCH_CNT)-NVL(SUM(R.ERROR_CNT),0) BATCH_CNT,
 SUM(R.ERROR_CNT) ERROR_CNT,
 SUM(EDIT_CNT)    EDIT_CNT,
 SUM(R.WT_PROD)   WT_PROD,
 SUM(R.TCHARGE)   TCHARGE,
 SUM(R.TDELAY)    TDELAY,
 SUM(R.TCHANGE)   TCHANGE,
 SUM(R.TNOTSCHED) TNOTSCHED,
 NVL(SUM(R.TCHARGE),0)+NVL(SUM(R.TDELAY),0)+NVL(SUM(R.TCHANGE),0)+NVL(SUM(R.TNOTSCHED),0) RUN,
 DECODE(SUM(R.BATCH_CNT)-SUM(R.ERROR_CNT),0,0,SUM(R.TCHARGE)/(SUM(R.BATCH_CNT)-SUM(R.ERROR_CNT))) AVG_CHARGE,
 SUM(R.TCHARGE)*100/(NVL(SUM(R.TCHARGE),0)+NVL(SUM(R.TDELAY),0)+NVL(SUM(R.TCHANGE),0)) PCT_UP
FROM MIXER.RUN_SUMM R, MIXER.SPEC S
WHERE R.SPEC_NUM=S.SPEC_NUM
  AND R.MIXER_NUM IN(&&MIXER)
  AND R.MIXER_NUM >=80
  AND SHIFT_DT BETWEEN TO_DATE('&&START','MM/DD/RR') AND TO_DATE('&&END','MM/DD/RR')
GROUP BY R.SHIFT_DT
UNION
SELECT 'ALL' SHIFT_DT,
 0 SHIFT_NUM,
 ' ' RUN_START_DT,
 '***GRAND' COMPOUND,
 'TOTAL' BAG_NAME,
 SUM(R.BATCH_CNT)-NVL(SUM(R.ERROR_CNT),0) BATCH_CNT,
 SUM(R.ERROR_CNT) ERROR_CNT,
 SUM(EDIT_CNT)    EDIT_CNT,
 SUM(R.WT_PROD)   WT_PROD,
 SUM(R.TCHARGE)   TCHARGE,
 SUM(R.TDELAY)    TDELAY,
 SUM(R.TCHANGE)   TCHANGE,
 SUM(R.TNOTSCHED) TNOTSCHED,
 NVL(SUM(R.TCHARGE),0)+NVL(SUM(R.TDELAY),0)+NVL(SUM(R.TCHANGE),0)+NVL(SUM(R.TNOTSCHED),0) RUN,
 DECODE(SUM(R.BATCH_CNT)-SUM(R.ERROR_CNT),0,0,SUM(R.TCHARGE)/(SUM(R.BATCH_CNT)-SUM(R.ERROR_CNT))) AVG_CHARGE,
 SUM(R.TCHARGE)*100/(NVL(SUM(R.TCHARGE),0)+NVL(SUM(R.TDELAY),0)+NVL(SUM(R.TCHANGE),0)) PCT_UP
FROM MIXER.RUN_SUMM R, MIXER.SPEC S
WHERE R.SPEC_NUM=S.SPEC_NUM
  AND R.MIXER_NUM IN(&&MIXER)
  AND R.MIXER_NUM >=80
  AND SHIFT_DT BETWEEN TO_DATE('&&START','MM/DD/RR') AND TO_DATE('&&END','MM/DD/RR')
ORDER BY SHIFT_DT,RUN_START_DT;

COLUMN SHIFT_DT         FORMAT A5       HEADING Shift|Date
COLUMN RUN_START_DT FORMAT A11      HEADING Run|Start
COLUMN COMPOUND     FORMAT A10      HEADING |Compound
COLUMN BAG_NAME     FORMAT A10      HEADING 'Bag Name'

BREAK ON SHIFT_DT SKIP PAGE ON SHIFT_NUM SKIP 1
CLEAR &&CLAUSE1

SELECT TO_CHAR(SHIFT_DT,'MM/DD') SHIFT_DT,
 R.SHIFT_NUM,
 TO_CHAR(RUN_START_DT,'MM/DD HH24:MI') RUN_START_DT,
 S.COMPOUND,
 R.BAG_NAME,
 R.BAG_MIXER_NUM,
 R.BATCH_CNT-NVL(R.ERROR_CNT,0) BATCH_CNT,
 R.ERROR_CNT,
 R.EDIT_CNT,
 R.WT_PROD,
 R.TCHARGE,
 R.TDELAY,
 R.TCHANGE,
 R.TNOTSCHED,
 NVL(R.TCHARGE,0)+NVL(R.TDELAY,0)+NVL(R.TCHANGE,0)+NVL(R.TNOTSCHED,0) RUN,
 DECODE(R.BATCH_CNT-NVL(R.ERROR_CNT,0),0,0,R.TCHARGE/(R.BATCH_CNT-NVL(R.ERROR_CNT,0))) AVG_CHARGE
FROM MIXER.RUN_SUMM R, MIXER.SPEC S
WHERE R.SPEC_NUM=S.SPEC_NUM
  AND R.MIXER_NUM IN(&&MIXER)
  AND R.MIXER_NUM >=80
  AND SHIFT_DT BETWEEN TO_DATE('&&START','MM/DD/RR') AND TO_DATE('&&END','MM/DD/RR')
  AND ROWNUM<=&&ROWLIMIT
ORDER BY SHIFT_DT,RUN_START_DT;

SPOOL OFF
SET VERIFY ON
CLEAR BREAKS
CLEAR COMPUTES

不幸的是,您的 VB.NET 代码不知道如何处理脚本中嵌入的所有SQL*Plus命令。 SQL*Plus是唯一支持全套命令的应用程序。 SQL Developer 支持SQL*Plus命令的子集。 看起来 SQL Developer 将支持此特定脚本中的所有SQL*Plus命令,但我需要通过文档确定 go。

快速而肮脏的解决方案是将 shell 从 VB 输出到操作系统并调用SQL*Plus生成文件,然后让 VB.NET 将文件返回给客户端。 这不是特别优雅,并且在多用户环境中会遇到问题,因为如果使用相同的参数调用脚本,它将尝试从两个不同的会话中假脱机相同的文件。 但似乎遗留解决方案已经存在相同的多用户问题。

更优雅的解决方案是重构脚本以将尽可能多的逻辑移动到视图中。 您的 VB.NET 代码可以调用视图并以更优雅的数据表格式呈现数据,而不是返回简单的平面文件(假设这旨在将数据呈现给人类进行分析,而不是生成特定格式的文件,然后输入一些下游过程)。 这将比调用SQL*Plus更费力,但意味着您对旧系统的升级将产生对用户更友好的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM