[英]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 the text file to the end user of the web application. 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 应用程序的最终用户。 I am running into a problem attempting to execute the.sql file in my visual studio code it tells me that it is not a valid SQL statement.
我在尝试在我的 Visual Studio 代码中执行 .sql 文件时遇到问题,它告诉我它不是有效的 SQL 语句。 Of course that makes sense because there is more in the.sql file than a sql statement.
当然这是有道理的,因为 .sql 文件中的内容比 sql 语句更多。
I am using .NET version 4.6.1 in my Visual Studio project and I am calling an Oracle 11 database.我在我的 Visual Studio 项目中使用 .NET 版本 4.6.1,我正在调用 Oracle 11 数据库。
Here is the code that I am trying to execute.这是我要执行的代码。 When it gets to the line where it is attempting to execute the script it throws the following error:
当它到达尝试执行脚本的行时,它会引发以下错误:
ERROR: Oracle.OracleException: 'ORA-00900: invalid SQL statement'
错误:Oracle.OracleException:'ORA-00900:无效的 SQL 语句'
Here is the VB.NET code:这是 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
The.sql file makes a few calls to Oracle and then exports (spools) the results to a.txt file. .sql 文件对 Oracle 进行几次调用,然后将结果导出(假脱机)到 a.txt 文件。 Once the.sql script is executed I would then display the.txt file that is created in the browser.
一旦执行了 .sql 脚本,我就会显示在浏览器中创建的 .txt 文件。
I have provided a copy of the.sql file below:我在下面提供了 .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
Unfortunately, your VB.NET code has no idea what to do with all the SQL*Plus
commands embedded in your script.不幸的是,您的 VB.NET 代码不知道如何处理脚本中嵌入的所有
SQL*Plus
命令。 SQL*Plus
is the only application that supports the full set of commands. SQL*Plus
是唯一支持全套命令的应用程序。 SQL Developer supports a subset of the SQL*Plus
commands. SQL Developer 支持
SQL*Plus
命令的子集。 It looks like SQL Developer would support all the SQL*Plus
commands in this particular script but I'd need to go through the documentation to be sure.看起来 SQL Developer 将支持此特定脚本中的所有
SQL*Plus
命令,但我需要通过文档确定 go。
The quick and dirty solution would be to shell out to the operating system from VB and invoke SQL*Plus
to produce the file and then let VB.NET return the file to the client.快速而肮脏的解决方案是将 shell 从 VB 输出到操作系统并调用
SQL*Plus
生成文件,然后让 VB.NET 将文件返回给客户端。 That's not particularly elegant and you'd have a problem in a multi-user environment because the script would try to spool the same file from two different sessions if it was called with the same parameters.这不是特别优雅,并且在多用户环境中会遇到问题,因为如果使用相同的参数调用脚本,它将尝试从两个不同的会话中假脱机相同的文件。 But it appears that the legacy solution has the same multi-user problem already.
但似乎遗留解决方案已经存在相同的多用户问题。
The more elegant solution would be to refactor the scripts to move as much of the logic as possible into a view.更优雅的解决方案是重构脚本以将尽可能多的逻辑移动到视图中。 Your VB.NET code could call the view and present the data in a more elegant data table format rather than returning a simple flat file (assuming that this is intended to present data to humans for analysis rather than producing files in a particular format that are fed into some downstream process).
您的 VB.NET 代码可以调用视图并以更优雅的数据表格式呈现数据,而不是返回简单的平面文件(假设这旨在将数据呈现给人类进行分析,而不是生成特定格式的文件,然后输入一些下游过程)。 That would be more effort than invoking
SQL*Plus
but would mean that your upgrade of the legacy system would produce much more user-friendly results.这将比调用
SQL*Plus
更费力,但意味着您对旧系统的升级将产生对用户更友好的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.