我正在研究C#的大型解决方案。该解决方案使用不同的oracle数据库,并已在TFS中签入。实际上,我开发了一个小型库,该库可以将解决方案中的SQL脚本部署到使用的数据库。应用程序的部署由TFS处理,将来我的工具应该包含在构建过程中。对于Oracle Connection,执行语句使用Oracle.ManagedDataAccess.Client。
如果SQL文件中只有几个DDL或DML语句,则第一个测试成功。但是我必须处理一些特殊的特殊事项,例如SET DEFINE OFF。这不是真正的SQL语句,如果我使用ORacle SQL * PLus运行脚本,则没有问题。在一开始,我尝试执行整个脚本,但是这不起作用,因为我的应用程序将多条语句放在一行中,而我发现的唯一解决方案是文件分割和一次执行。
示例:
/*************************************************************************************************************************
##NAME ScriptName.sql
##DESCR ScriptDescription
*************************************************************************************************************************/
Create table tmp_thm_Test
( tmp_thm_Test_id number(8)
, text varchar2(200));
Create table tmp_thm_Test2
( tmp_thm_Test2_id number(8)
, text varchar2(200));
这是脚本的示例内容。也可以有插入(在字符串中带有&的情况下需要关闭Set Define),更新语句。还要开始/结束脚本。
如果只有DDL和DML语句,我可以拆分它们,但是Begin / End部分不能拆分。一开始我以为我可以像过去一样使用SQL * Plus(@ Scriptname.sql)部署脚本。阅读整个脚本并执行。
有什么想法吗?
答案 0 :(得分:1)
自从我在C#中与Oracle一起工作以来,即使缺乏具体示例,我还是对您有所了解。
SET DEFINE OFF
从未在C#中为我工作过,因此我只使用query = query.Replace("'","''");
。您还可以使用以下命令参数来避免异常。
string query = string.Format(
@"UPDATE CardStatus
SET DateExpired = @dateExpired,
ModifiedBy = @modifiedBy,
ModifiedOn = @modifiedOn
WHERE
IDNo = @idNo");
List<OracleParameter> parameters = new List<OracleParameter>();
OracleParameter pIdNo = new OracleParameter("idNo", OracleDbType.Varchar2);
pIdNo.Value = idNo;
OracleParameter pDateExpired = new OracleParameter("dateExpired", OracleDbType.Date);
pDateExpired.Value = dateExpired;
OracleParameter pModifiedBy = new OracleParameter("modifiedBy", OracleDbType.Varchar2);
pModifiedBy.Value = "SIS";
OracleParameter pModifiedOn = new OracleParameter("modifiedOn", OracleDbType.Date);
pModifiedOn.Value = DateTime.Now;
parameters.Add(pIdNo);
parameters.Add(pDateExpired);
parameters.Add(pModifiedBy);
parameters.Add(pModifiedOn);
bool result = _DAL.ExecuteNonQuery(query, parameters.ToArray());
_DAL
只是我的数据访问帮助类,它管理查询执行,将其放置在单个事务中,以便我决定是提交还是回滚单个到多个查询的更改。
public bool ExecuteNonQuery(string query, object[] parameters, [CallerMemberName] string callerMemberName = "")
{
bool success = false;
try
{
using (OracleCommand command = new OracleCommand())
{
command.Connection = _connection;
command.Transaction = _transaction;
command.CommandText = query;
command.CommandType = CommandType.Text;
command.Parameters.AddRange(parameters);
command.ExecuteNonQuery();
}
this.AuditSQL(query, string.Empty);
success = true;
}
catch (OracleException ex)
{
this.AuditSQL(query, ex.Message, callerMemberName);
if (ex.Number == 54) // SELECT .. FOR UPDATE NOWAIT failed.
{
throw new RowLockException();
}
}
return success;
}
我不确定您是否有兴趣参加我的_DAL
课程,但是我为您提供了一段代码,以帮助您了解可以做什么。
编辑:由于您已经提到脚本已经存在,所以它很容易,您只需要确保脚本中没有'
字符就可以使oracle请求一个变量值和所有批处理查询必须具有BEGIN
和END;
。
示例:
BEGIN
-- INSERT
-- UPDATE
-- INSERT
... etc.
END;
现在,您到底是什么问题?您可以从文件中读取查询,并将所有SET DEFINE OFF
(以及您认为不必要的其他语句)替换为string.Empty
,并根据需要将所有'
替换为''
。最坏的情况是,您将使用正则表达式来识别和删除不需要的语句。