.NET/Oracle:如何以编程方式使用DDL语句执行脚本
本文关键字:方式使 DDL 语句 脚本 执行 编程 Oracle NET | 更新日期: 2023-09-27 18:23:51
我想对C#中的oracle数据库进行一些编程模式操作。因此,我很难解决一些基本问题。
ddl-sql语句位于脚本文件中。我不想使用sqlplus.exe,但我想在ODP.NET程序集(System.Oracle.DataAccess)之外使用OracleCommand
script.sql:
DROP TABLE ABCDEF;
DROP TABLE GHIJKL;
我想指出:
- 脚本包含DDL语句(数据定义语言)
- 脚本包含空行
- 脚本包含多个语句
以下代码应该执行我的脚本:
var content = File.ReadAllText("script.sql");
using (var oracleConnection = new OracleConnection(_connectionString))
{
oracleConnection.Open();
using (var command = new OracleCommand(content) { Connection = oracleConnection })
{
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
执行此代码时,我确实得到了一个预言错误:
Oracle.DataAccess.Client.OracleException:ORA-00911:无效字符
我认为,也许这些语句的格式有问题。任何提示都将不胜感激。非常感谢。
---编辑---
用一种简单的方式总结我的需求:我搜索一种方法来执行任何sql/ddl脚本,该脚本可由sql Plus通过C#编程执行。
只需将其包裹在BEGIN和END中,就会顺利工作
var content =string.Format("BEGIN {0} END;", File.ReadAllText("script.sql"));
using (var oracleConnection = new OracleConnection(_connectionString))
{
oracleConnection.Open();
using (var command = new OracleCommand(content) { Connection = oracleConnection })
{
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
感谢分号提示!
我运行oracle脚本的最后一段代码!
1) 它接受:-空行/注释(--)行-以;结尾的多行DDl/DML命令;
2) 如果出现错误,它会抛出一个带有行号和sql命令的异常!
public async Task ExecuteScript(string _connectionString, string script)
{
using (StringReader sr = new StringReader(script))
{
var connection = new OracleConnection(_connectionString);
connection.Open();
string sqlCommand = "";
string sqlLine; byte lineNum = 0;
while ((sqlLine = sr.ReadLine()) != null)
{
sqlLine = sqlLine.Trim(); ++lineNum;
if (sqlLine.Length > 0 && !sqlLine.StartsWith("--"))
{
sqlCommand += (sqlCommand.Length > 0 ? Environment.NewLine : "") + sqlLine; // Accept multiline SQL
if (sqlCommand.EndsWith(";"))
{
sqlCommand = sqlCommand.Substring(0, sqlCommand.Length - 1);
var command = new OracleCommand(sqlCommand, connection);
try
{
await command.ExecuteNonQueryAsync();
}
catch (OracleException ex)
{
connection.Close();
var e2 = new Exception($"{lineNum} - {sqlCommand} <br/> {ex.Message}");
throw e2;
}
}
}
}
connection.Close();
return;
}
}
正如@Steve所说,分号导致了您的错误。而且,您不能将整个文件包装成一个execute immediate
命令,因为它一次只能执行一条语句。您将需要解析文件,并单独执行每个命令,删除使命令脱钩的分号。正如您所指出的,您的解析将必须处理字符串文字,这些文字除了包含分号外,还可能在字符串文字的开头和结尾的单引号(')中包含双单引号('')。
我将尝试一次执行一行,看看是否有任何奇怪的字符阻止执行。(我也不确定你是否可以在一次通话中同时发送所有命令)。
您还应该删除行末尾的分号
int lineNum = 0;
try
{
string[] cmdTexts = File.ReadAllLines("script.sql");
using (var oracleConnection = new OracleConnection(_connectionString))
{
oracleConnection.Open();
OracleCommand command = new OracleCommand();
command.Connection = oracleConnection;
foreach(string cmd in cmdTexts)
{
lineNum++;
if(cmd.Trim().Length > 0)
{
if(cmd.EndsWith(";"))
cmd = cmd.Substring(0, cmd.Length - 1);
command.CommandText = cmd;
command.ExecuteNonQuery();
}
}
}
}
catch(Exception ex)
{
MessageBox.Show("Exception on line: " + lineNum + " message: " + ex.Message);
}