C# 调用替换后 Oracle 包无效
Oracle package invalid after C# call to replace
我假设我从 C# 运行 SQL 脚本中做错了什么,但在 Internet 上进行大量搜索后,我仍然不知道哪里出了问题.. .
我在通过 C# 加载 Oracle 包和包主体时遇到问题。当我通过脚本在 SQL*PLUS 中加载包时,对脚本中函数的后续调用工作正常。当我从 C# 调用它时,它也有效。但是,当我从 C# 加载相同的脚本时,脚本的 运行ning 似乎有效,但随后对包函数的调用(来自 C# 和 SQL*PLUS)失败并显示 PLS- 00905 错误 ("object ANON.MY_PKG is invalid").
SQL脚本("simple.sql")的内容是:
CREATE OR REPLACE PACKAGE my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
)RETURN VARCHAR2;
END my_pkg;
/
CREATE OR REPLACE PACKAGE BODY my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
) RETURN VARCHAR2 AS p_result VARCHAR2(2000);
BEGIN
RETURN p_1;
END my_function;
END my_pkg;
/
运行 它在 SQL*PLUS 中工作正常...
SQL> SET SERVEROUTPUT ON
SQL> @"D:\_temp\simple.sql"
Package created.
Package body created.
SQL> EXEC DBMS_OUTPUT.PUT_LINE(my_pkg.my_function('hello'));
hello
PL/SQL procedure successfully completed.
然后在 C# 程序中调用该函数(与 SQL*PLUS 中使用的相同的 Oracle 用户)工作正常,直到 SQL 脚本在 运行程序。
using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestApplication
{
class Program
{
static void Main(string[] args)
{
OracleConnection conn = getConnection();
Debug.WriteLine("first call to my_function:");
callMyFunction(conn);
loadMyPackage(conn);
try
{
Debug.WriteLine("second call to my_function:");
callMyFunction(conn);
}
catch (Exception ex)
{
Debug.WriteLine("ex = " + ex.ToString());
}
}
private static OracleConnection getConnection()
{
string connStr = "redacted...";
OracleConnection conn = new OracleConnection();
conn.ConnectionString = connStr;
conn.Open();
return conn;
}
private static void loadMyPackage(OracleConnection conn)
{
OracleCommand command = new OracleCommand();
command.CommandType = CommandType.Text;
command.CommandText = File.ReadAllText(@"D:\_temp\simple.sql");
command.Connection = conn;
int response = command.ExecuteNonQuery();
Debug.WriteLine("response = " + response);
}
private static void callMyFunction(OracleConnection conn)
{
int RETURN_BUFFER_SIZE = 32767;
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "my_pkg.my_function";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("returnVal", OracleDbType.Varchar2, RETURN_BUFFER_SIZE);
cmd.Parameters["returnVal"].Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add("p_1", OracleDbType.Varchar2);
cmd.Parameters["p_1"].Value = "hello";
cmd.ExecuteNonQuery();
string result = cmd.Parameters[0].Value.ToString();
Debug.WriteLine("function result = " + result);
}
}
}
重新加载后 ("loadMyPackage") 出错。具体来说:
first call to my_function:
function result = hello
response = -1
second call to my_function:
A first chance exception of type 'Oracle.ManagedDataAccess.Client.OracleException' occurred in Oracle.ManagedDataAccess.dll
ex = Oracle.ManagedDataAccess.Client.OracleException (0x00001996): ORA-06550: line 1, column 15:
PLS-00905: object ANON.MY_PKG is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteNonQuery(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, OracleException& exceptionForArrayBindDML, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteNonQuery()
at TestApplication.Program.callMyFunction(OracleConnection conn) in c:\Users\ANON\Documents\Visual Studio 2013\Projects\myProject\TestApplication\Program.cs:line 73
at TestApplication.Program.Main(String[] args) in c:\Users\ANON\Documents\Visual Studio 2013\Projects\myProject\TestApplication\Program.cs:line 29
The thread 0x2838 has exited with code 259 (0x103).
The thread 0x2d9c has exited with code 259 (0x103).
The program '[11268] TestApplication.vshost.exe' has exited with code 0 (0x0).
如何让 C# 正确地 运行 脚本?
更新:
根据反馈,我将 SQL 脚本分成两部分。第一部分 ("simple_A.sql") 现在是:
CREATE OR REPLACE PACKAGE my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
)RETURN VARCHAR2;
END my_pkg;
/
第二部分("simple_B.sql")是:
CREATE OR REPLACE PACKAGE BODY my_pkg IS -- body
FUNCTION my_function (
p_1 IN VARCHAR2
) RETURN VARCHAR2 AS p_result VARCHAR2(2000);
BEGIN
RETURN p_1;
END my_function;
END my_pkg;
/
在此之后,更改,我通过以下方式验证它在 SQL*PLUS 中仍然有效:
SQL> drop package my_pkg;
Package dropped.
SQL> @"D:\_temp\simple_A.sql"
Package created.
SQL> @"D:\_temp\simple_B.sql"
Package body created.
SQL> EXEC DBMS_OUTPUT.PUT_LINE(my_pkg.my_function('hello'));
hello
PL/SQL procedure successfully completed.
SQL>
然后我通过以下更改更新 C# 代码以使用这两个脚本:
private static void loadMyPackage(OracleConnection conn)
{
OracleCommand command_A = new OracleCommand();
command_A.CommandType = CommandType.Text;
command_A.CommandText = File.ReadAllText(@"D:\_temp\simple_A.sql");
command_A.Connection = conn;
int response = command_A.ExecuteNonQuery();
Debug.WriteLine("response A = " + response);
OracleCommand command_B = new OracleCommand();
command_B.CommandType = CommandType.Text;
command_B.CommandText = File.ReadAllText(@"D:\_temp\simple_B.sql");
command_B.Connection = conn;
response = command_B.ExecuteNonQuery();
Debug.WriteLine("response B = " + response);
}
但是,我仍然遇到同样的错误。具体来说,现在的输出如下:
first call to my_function:
function result = hello
response A = -1
response B = -1
second call to my_function:
A first chance exception of type 'Oracle.ManagedDataAccess.Client.OracleException' occurred in Oracle.ManagedDataAccess.dll
ex = Oracle.ManagedDataAccess.Client.OracleException (0x00001996): ORA-06550: line 1, column 15:
PLS-00905: object ANON.MY_PKG is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteNonQuery(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, OracleException& exceptionForArrayBindDML, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteNonQuery()
...
The thread 0x4f0 has exited with code 259 (0x103).
The thread 0x3310 has exited with code 259 (0x103).
The program '[10728] TestApplication.vshost.exe' has exited with code 0 (0x0).
更新#2:
根据 Justin 的评论,我将 sql 脚本拆分为两个单独的文件,并从中删除了“/”字符。他们现在是:
simple_A.sql:
CREATE OR REPLACE PACKAGE my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
)RETURN VARCHAR2;
END my_pkg;
simple_B.sql
CREATE OR REPLACE PACKAGE BODY my_pkg IS -- body
FUNCTION my_function (
p_1 IN VARCHAR2
) RETURN VARCHAR2 AS p_result VARCHAR2(2000);
BEGIN
RETURN p_1;
END my_function;
END my_pkg;
通过这些更改以及第一次更新中的更改,代码可以正常工作。
在让代码正常工作后,我根据 Justin 的另一条评论添加了一个额外的位,这是一种识别错误原因的方法。具体来说,我添加了一个 printErrors 函数,并在我的 C# 代码中添加了对它的调用。对代码的增补和修改为:
private static void loadMyPackage(OracleConnection conn)
{
OracleCommand command_A = new OracleCommand();
command_A.CommandType = CommandType.Text;
command_A.CommandText = File.ReadAllText(@"D:\_temp\simple_A.sql");
command_A.Connection = conn;
int response = command_A.ExecuteNonQuery();
printErrors(conn);
Debug.WriteLine("response A = " + response);
OracleCommand command_B = new OracleCommand();
command_B.CommandType = CommandType.Text;
command_B.CommandText = File.ReadAllText(@"D:\_temp\simple_B.sql");
command_B.Connection = conn;
response = command_B.ExecuteNonQuery();
printErrors(conn);
Debug.WriteLine("response B = " + response);
}
private static void printErrors(OracleConnection conn)
{
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT name, text FROM user_errors";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Debug.WriteLine("user_error: " + dr.GetString(0) + ": " + dr.GetString(1) );
}
}
添加了 printErrors 代码后,错误的原因就很容易看出了。第一次更新的错误 SQL 版本产生以下输出:
...
first call to my_function:
function result = hello
user_error: MY_PKG: PLS-00103: Encountered the symbol "/" The symbol "/" was ignored.
response A = -1
...
[注意:以上错误消息来自给定有错误的 sql 脚本时的最终代码。 sql 脚本的最终版本没有错误。]
因此,此代码不仅开始工作,而且现在能够在失败的情况下提供描述性错误信息。
假设您的文件看起来像这样,包含两个 DDL 语句且没有 SQL*Plus
命令
CREATE OR REPLACE PACKAGE package_name
...
END;
/
CREATE OR REPLACE PACKAGE BODY package_name
...
END;
/
有两个问题。
首先,这是两个独立的 DDL 语句,因此它们必须通过两个独立的 ExecuteNonQuery
调用来执行。您可以将单个文件拆分为多个文件,每个 DDL 语句一个,或者您可以在 C# 代码中解析文件中的各个语句。
其次,每个 DDL 语句的末尾都有一个 /
字符。那是 SQL*Plus
的分隔符,因此它知道您的语句何时完成,它不是 DDL 语句的一部分。您可以在执行语句之前在 C# 中删除它,也可以从文件中删除语句并创建一个单独的 SQL*Plus
脚本来引用各个语句文件并包含适当的分隔符。
我假设我从 C# 运行 SQL 脚本中做错了什么,但在 Internet 上进行大量搜索后,我仍然不知道哪里出了问题.. .
我在通过 C# 加载 Oracle 包和包主体时遇到问题。当我通过脚本在 SQL*PLUS 中加载包时,对脚本中函数的后续调用工作正常。当我从 C# 调用它时,它也有效。但是,当我从 C# 加载相同的脚本时,脚本的 运行ning 似乎有效,但随后对包函数的调用(来自 C# 和 SQL*PLUS)失败并显示 PLS- 00905 错误 ("object ANON.MY_PKG is invalid").
SQL脚本("simple.sql")的内容是:
CREATE OR REPLACE PACKAGE my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
)RETURN VARCHAR2;
END my_pkg;
/
CREATE OR REPLACE PACKAGE BODY my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
) RETURN VARCHAR2 AS p_result VARCHAR2(2000);
BEGIN
RETURN p_1;
END my_function;
END my_pkg;
/
运行 它在 SQL*PLUS 中工作正常...
SQL> SET SERVEROUTPUT ON
SQL> @"D:\_temp\simple.sql"
Package created.
Package body created.
SQL> EXEC DBMS_OUTPUT.PUT_LINE(my_pkg.my_function('hello'));
hello
PL/SQL procedure successfully completed.
然后在 C# 程序中调用该函数(与 SQL*PLUS 中使用的相同的 Oracle 用户)工作正常,直到 SQL 脚本在 运行程序。
using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestApplication
{
class Program
{
static void Main(string[] args)
{
OracleConnection conn = getConnection();
Debug.WriteLine("first call to my_function:");
callMyFunction(conn);
loadMyPackage(conn);
try
{
Debug.WriteLine("second call to my_function:");
callMyFunction(conn);
}
catch (Exception ex)
{
Debug.WriteLine("ex = " + ex.ToString());
}
}
private static OracleConnection getConnection()
{
string connStr = "redacted...";
OracleConnection conn = new OracleConnection();
conn.ConnectionString = connStr;
conn.Open();
return conn;
}
private static void loadMyPackage(OracleConnection conn)
{
OracleCommand command = new OracleCommand();
command.CommandType = CommandType.Text;
command.CommandText = File.ReadAllText(@"D:\_temp\simple.sql");
command.Connection = conn;
int response = command.ExecuteNonQuery();
Debug.WriteLine("response = " + response);
}
private static void callMyFunction(OracleConnection conn)
{
int RETURN_BUFFER_SIZE = 32767;
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "my_pkg.my_function";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("returnVal", OracleDbType.Varchar2, RETURN_BUFFER_SIZE);
cmd.Parameters["returnVal"].Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add("p_1", OracleDbType.Varchar2);
cmd.Parameters["p_1"].Value = "hello";
cmd.ExecuteNonQuery();
string result = cmd.Parameters[0].Value.ToString();
Debug.WriteLine("function result = " + result);
}
}
}
重新加载后 ("loadMyPackage") 出错。具体来说:
first call to my_function:
function result = hello
response = -1
second call to my_function:
A first chance exception of type 'Oracle.ManagedDataAccess.Client.OracleException' occurred in Oracle.ManagedDataAccess.dll
ex = Oracle.ManagedDataAccess.Client.OracleException (0x00001996): ORA-06550: line 1, column 15:
PLS-00905: object ANON.MY_PKG is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteNonQuery(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, OracleException& exceptionForArrayBindDML, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteNonQuery()
at TestApplication.Program.callMyFunction(OracleConnection conn) in c:\Users\ANON\Documents\Visual Studio 2013\Projects\myProject\TestApplication\Program.cs:line 73
at TestApplication.Program.Main(String[] args) in c:\Users\ANON\Documents\Visual Studio 2013\Projects\myProject\TestApplication\Program.cs:line 29
The thread 0x2838 has exited with code 259 (0x103).
The thread 0x2d9c has exited with code 259 (0x103).
The program '[11268] TestApplication.vshost.exe' has exited with code 0 (0x0).
如何让 C# 正确地 运行 脚本?
更新: 根据反馈,我将 SQL 脚本分成两部分。第一部分 ("simple_A.sql") 现在是:
CREATE OR REPLACE PACKAGE my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
)RETURN VARCHAR2;
END my_pkg;
/
第二部分("simple_B.sql")是:
CREATE OR REPLACE PACKAGE BODY my_pkg IS -- body
FUNCTION my_function (
p_1 IN VARCHAR2
) RETURN VARCHAR2 AS p_result VARCHAR2(2000);
BEGIN
RETURN p_1;
END my_function;
END my_pkg;
/
在此之后,更改,我通过以下方式验证它在 SQL*PLUS 中仍然有效:
SQL> drop package my_pkg;
Package dropped.
SQL> @"D:\_temp\simple_A.sql"
Package created.
SQL> @"D:\_temp\simple_B.sql"
Package body created.
SQL> EXEC DBMS_OUTPUT.PUT_LINE(my_pkg.my_function('hello'));
hello
PL/SQL procedure successfully completed.
SQL>
然后我通过以下更改更新 C# 代码以使用这两个脚本:
private static void loadMyPackage(OracleConnection conn)
{
OracleCommand command_A = new OracleCommand();
command_A.CommandType = CommandType.Text;
command_A.CommandText = File.ReadAllText(@"D:\_temp\simple_A.sql");
command_A.Connection = conn;
int response = command_A.ExecuteNonQuery();
Debug.WriteLine("response A = " + response);
OracleCommand command_B = new OracleCommand();
command_B.CommandType = CommandType.Text;
command_B.CommandText = File.ReadAllText(@"D:\_temp\simple_B.sql");
command_B.Connection = conn;
response = command_B.ExecuteNonQuery();
Debug.WriteLine("response B = " + response);
}
但是,我仍然遇到同样的错误。具体来说,现在的输出如下:
first call to my_function:
function result = hello
response A = -1
response B = -1
second call to my_function:
A first chance exception of type 'Oracle.ManagedDataAccess.Client.OracleException' occurred in Oracle.ManagedDataAccess.dll
ex = Oracle.ManagedDataAccess.Client.OracleException (0x00001996): ORA-06550: line 1, column 15:
PLS-00905: object ANON.MY_PKG is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean& hasMoreRowsInDB, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.VerifyExecution(OracleConnectionImpl connectionImpl, Int32& cursorId, Boolean bThrowArrayBindRelatedErrors, OracleException& exceptionForArrayBindDML, Boolean bFirstIterationDone)
at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteNonQuery(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, Int32 longFetchSize, Int64 clientInitialLOBFS, OracleDependencyImpl orclDependencyImpl, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, OracleException& exceptionForArrayBindDML, Boolean isFromEF)
at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteNonQuery()
...
The thread 0x4f0 has exited with code 259 (0x103).
The thread 0x3310 has exited with code 259 (0x103).
The program '[10728] TestApplication.vshost.exe' has exited with code 0 (0x0).
更新#2: 根据 Justin 的评论,我将 sql 脚本拆分为两个单独的文件,并从中删除了“/”字符。他们现在是:
simple_A.sql:
CREATE OR REPLACE PACKAGE my_pkg IS
FUNCTION my_function (
p_1 IN VARCHAR2
)RETURN VARCHAR2;
END my_pkg;
simple_B.sql
CREATE OR REPLACE PACKAGE BODY my_pkg IS -- body
FUNCTION my_function (
p_1 IN VARCHAR2
) RETURN VARCHAR2 AS p_result VARCHAR2(2000);
BEGIN
RETURN p_1;
END my_function;
END my_pkg;
通过这些更改以及第一次更新中的更改,代码可以正常工作。
在让代码正常工作后,我根据 Justin 的另一条评论添加了一个额外的位,这是一种识别错误原因的方法。具体来说,我添加了一个 printErrors 函数,并在我的 C# 代码中添加了对它的调用。对代码的增补和修改为:
private static void loadMyPackage(OracleConnection conn)
{
OracleCommand command_A = new OracleCommand();
command_A.CommandType = CommandType.Text;
command_A.CommandText = File.ReadAllText(@"D:\_temp\simple_A.sql");
command_A.Connection = conn;
int response = command_A.ExecuteNonQuery();
printErrors(conn);
Debug.WriteLine("response A = " + response);
OracleCommand command_B = new OracleCommand();
command_B.CommandType = CommandType.Text;
command_B.CommandText = File.ReadAllText(@"D:\_temp\simple_B.sql");
command_B.Connection = conn;
response = command_B.ExecuteNonQuery();
printErrors(conn);
Debug.WriteLine("response B = " + response);
}
private static void printErrors(OracleConnection conn)
{
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT name, text FROM user_errors";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Debug.WriteLine("user_error: " + dr.GetString(0) + ": " + dr.GetString(1) );
}
}
添加了 printErrors 代码后,错误的原因就很容易看出了。第一次更新的错误 SQL 版本产生以下输出:
...
first call to my_function:
function result = hello
user_error: MY_PKG: PLS-00103: Encountered the symbol "/" The symbol "/" was ignored.
response A = -1
...
[注意:以上错误消息来自给定有错误的 sql 脚本时的最终代码。 sql 脚本的最终版本没有错误。]
因此,此代码不仅开始工作,而且现在能够在失败的情况下提供描述性错误信息。
假设您的文件看起来像这样,包含两个 DDL 语句且没有 SQL*Plus
命令
CREATE OR REPLACE PACKAGE package_name
...
END;
/
CREATE OR REPLACE PACKAGE BODY package_name
...
END;
/
有两个问题。
首先,这是两个独立的 DDL 语句,因此它们必须通过两个独立的 ExecuteNonQuery
调用来执行。您可以将单个文件拆分为多个文件,每个 DDL 语句一个,或者您可以在 C# 代码中解析文件中的各个语句。
其次,每个 DDL 语句的末尾都有一个 /
字符。那是 SQL*Plus
的分隔符,因此它知道您的语句何时完成,它不是 DDL 语句的一部分。您可以在执行语句之前在 C# 中删除它,也可以从文件中删除语句并创建一个单独的 SQL*Plus
脚本来引用各个语句文件并包含适当的分隔符。