如何使用 OracleCommand C# 执行不同的多条 SQL 语句
Posted
技术标签:
【中文标题】如何使用 OracleCommand C# 执行不同的多条 SQL 语句【英文标题】:How to execute different multiple SQL statements using OracleCommand C# 【发布时间】:2019-04-10 16:52:35 【问题描述】:我正在尝试使用 OracleCommand 执行不同的 SQL 语句。
var conn = new OracleConnection("User Id=SYSTEM;Password=mw;Data Source=SampleDataSource");
// Open the connection
if (conn.State != ConnectionState.Open)
conn.Open();
string sql = @"
DROP TABLE CUSTOMERS;
CREATE TABLE CUSTOMERS (
ID INT NOT NULL PRIMARY KEY,
NAME VARCHAR(12) NOT NULL,
AGE INT,
ADDRESS VARCHAR(12)
);
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (1, 'Mark', 28, 'NY');
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (2, 'John', 39, 'LA');
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (3, 'Andy', 48, 'CA');
INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (4, 'Allan', 53, 'LA');
";
var cmd = new OracleCommand(sql, conn);
try
cmd.ExecuteNonQuery();
catch (OracleException e)
error = e.Message;
finally
if (conn.State == ConnectionState.Open)
conn.Close();
我收到以下异常。
ORA-00933:SQL 命令未正确结束
当我在 BEGIN、END 块中包含多个语句时,我得到以下异常。
ORA-06550:第 2 行,第 1 列: PLS-00103:在预期以下情况之一时遇到符号“DROP”:
( begin case declare exit for goto if loop mod null pragma raise return select update while with
【问题讨论】:
你能创建一个存储过程并使用立即执行吗?您必须使用 execute immediate 来删除表。 你也可以试试这个***.com/questions/31917301/… 立即执行是调用多个语句所需要的 可能与 Oracle 无关,但在 MS SQL Server 中,您不能在同一批次中执行删除、创建表和查询。如果 Oracle 有像 MSSQL 的GO
这样的批处理分隔符,请尝试将其放在两者之间。
通常您不会在运行时删除或创建表。你的目的是什么?
【参考方案1】:
立即执行将使您能够执行多个语句。
OracleConnection con = new OracleConnection("User Id=SYSTEM;Password=mw;Data Source=SampleDataSource");
if (con.State != ConnectionState.Open)
con.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = con;
cmd.CommandText =
"begin " +
" execute immediate 'DROP TABLE CUSTOMERS';" +
" execute immediate 'CREATE TABLE CUSTOMERS (ID INT NOT NULL PRIMARY KEY,NAME VARCHAR(12) NOT NULL, AGE INT, ADDRESS VARCHAR(12))';" +
" execute immediate 'INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (1, 'Mark', 28, 'NY')';" +
" execute immediate 'INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (2, 'John', 39, 'LA')';" +
" execute immediate 'INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (3, 'Andy', 48, 'CA')';" +
" execute immediate 'INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (4, 'Allan', 53, 'LA')';" +
"end;"
cmd.CommandType = CommandType.Text;
try
cmd.ExecuteNonQuery();
catch (OracleException e)
error = e.Message;
finally
if (con.State == ConnectionState.Open)
con.Close();
【讨论】:
INSERT INTO ...
不需要execute immediate
不,它也不能仅与 Drop 和 Create 语句一起使用【参考方案2】:
也许对每条语句都使用一个命令会更好。 以下是dapper 的示例。
const string dropTableCustomers = "DROP TABLE CUSTOMERS";
const string createTableCustomers = @"
CREATE TABLE CUSTOMERS (
ID INT NOT NULL PRIMARY KEY,
NAME VARCHAR(12) NOT NULL,
AGE INT,
ADDRESS VARCHAR(12))";
const string insertCustomerMark = "INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (1, 'Mark', 28, 'NY')";
const string insertCustomerJohn = "INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (2, 'John', 39, 'LA')";
using (var connection = new OracleConnection("User Id=SYSTEM;Password=mw;Data Source=SampleDataSource"))
connection.Open();
connection.Execute(dropTableCustomers);
connection.Execute(createTableCustomers);
connection.Execute(insertCustomerMark);
connection.Execute(insertCustomerJohn);
如果您需要交易,您可以执行以下操作:
public static class DbConnectionFactory
public static IDbConnection Create(string connectionString)
var connection = new OracleConnection(connectionString);
connection.Open();
return connection;
const string dropTableCustomers = "DROP TABLE CUSTOMERS";
const string createTableCustomers = @"
CREATE TABLE CUSTOMERS (
ID INT NOT NULL PRIMARY KEY,
NAME VARCHAR(12) NOT NULL,
AGE INT,
ADDRESS VARCHAR(12))";
const string insertCustomerMark = "INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (1, 'Mark', 28, 'NY')";
const string insertCustomerJohn = "INSERT INTO CUSTOMERS (ID,NAME,AGE,ADDRESS) VALUES (2, 'John', 39, 'LA')";
using (var connection = DbConnectionFactory.Create("User Id=SYSTEM;Password=mw;Data Source=SampleDataSource"))
using (var transaction = connection.BeginTransaction())
connection.Execute(dropTableCustomers);
connection.Execute(createTableCustomers);
connection.Execute(insertCustomerMark);
connection.Execute(insertCustomerJohn);
transaction.Commit();
【讨论】:
【参考方案3】:strSQL = @"Insert all into NEW1(a,b) VALUES(1,2) "
+ "INTO NEW1(a,b) VALUES(2, 3) "
+ "INTO NEW1(a,b) VALUES(3, 4) "
+ "INTO NEW2(a,b) VALUES(9, 9) "
+ "INTO NEW2(a,b) VALUES(6, 6) "
+ "SELECT * FROM DUAL";
【讨论】:
【参考方案4】:我使用包含 DbScript 类的 DevArt 库解决了这个问题,您可以在以下 URL 找到使用示例:DbScript Class
【讨论】:
以上是关于如何使用 OracleCommand C# 执行不同的多条 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章
OracleCommand ExecuteScalar 有时返回 null
OracleCommand.CommandText 中的查询文本是不是有最大长度?
简单的 Oracle 查询返回 OracleCommand.CommandText 无效