从C#/ .Net创建并编译oracle中的“on the fly”存储过程

时间:2011-05-14 03:13:01

标签: c# .net sql oracle

我知道有人问before但这些解决方案似乎与我无关。

我目前正在尝试这样做:

  1. 为oracle
  2. 构建“CREATE PROCEDURE”脚本字符串
  3. 使用企业库5.0创建SQL命令,并将此字符串作为参数
  4. 传递
  5. 将程序保存在oracle数据库中
  6. 所以#3点似乎到目前为止工作,如果我打开SQL Developer并展开程序树列表然后我实际上可以看到程序,但是用红色圆圈表示虽然运行相同的代码但它有编译器错误,非常小,在SQL Developer查询窗口中工作正常并编译它。我不确定SQL Developer是否会做一些事情,因为运行“CREATE PROCEDURE”脚本不会抛出任何错误,然后我可以看到并执行该过程,但不是这样从C#进行。

    我在开头发布的链接中读到我应该调用IDBCommand.Prepare(),但只有当你的SQLCommand.CommandType类型为StoredProcedure并且我实际上没有调用过程时,该方法才有意义。运行纯sql来创建程序然后这不起作用,尽管如此,我只是为了测试,创建了一个新命令,我分配给StoredProcedure然后在该命令上调用Prepare()方法,最后{{ 1}}抛出异常的对象(存储过程)的方法,因为它还没有被编译,所以这是有意义的...

    所以,我想知道是否有人真的知道你如何创建一个程序并从C#编译它,我们目前正在使用企业库,但我不介意直接向oracle提供者“硬编码”的东西,只要它有效

    顺便说一下,在告诉我从代码中创建一个程序是一个不好的做法我告诉你,不幸的是这是一个客户的项目,我们没有做出决定,实际上我们正在尝试将事物从SQL Server迁移到甲骨文。

3 个答案:

答案 0 :(得分:2)

我有点生疏,现在没有Oracle访问权限,但我想我知道你要求的是什么。您希望使用ADO.NET OracleCommand类和Oracle EXECUTE IMMEDIATE语句。像这样:

        OracleConnection conn = new OracleConnection("Data Source=something; user id=something; Password=something;");
        conn.Open();
        OracleCommand command = new OracleCommand();
        command.CommandType = CommandType.Text;
        command.CommandText = "execute immediate 'create or replace procedure [...you know this part...]' ";
        command.Connection = conn;
        command.ExecuteNonQuery();
        conn.Close();
    }

那应该有用。但请注意,我总是使用ODP.NET(Oracle自己的数据提供程序)而不是ADO.NET库存,所以如果您只是使用库存库,可能会有一些细微差别。

正如Pete建议你也可以使用动态SQL来达到同样的效果。您将整个CREATE PROCEDURE语句作为参数传递给现有存储过程,然后为您调用EXECUTE IMMEDIATE。但是,我不相信你必须这样做。如果你想保持最低限度,上述情况应该有效。

另一件事。我不知道为什么会发生这种情况,但如果Oracle告诉你程序无效,即使你知道它没问题,也可以尝试执行

EXECUTE IMMEDIATE ALTER PROCEDURE schemaname.procedurename COMPILE;

我经常发现Oracle在不必要地使对象无效方面有点脆弱。

答案 1 :(得分:1)

如果要在SQL Server或Oracle中动态执行DDL语句,则必须将在C#中创建的DDL传递给Oracle中的过程,然后使用EXECUTE IMMEDIATE将字符串作为命令运行并创建过程

来自Oracle的

This page提到如果“您想要执行纯静态SQL程序中不支持的DDL语句和其他SQL语句”,则必须使用动态SQL。

我希望这会对你有所帮助。

答案 2 :(得分:0)

最后一个角色是什么?

Oracle的原始SQL * Plus使用斜杠字符来执行当前命令。许多IDE要么使用相同的,要么将斜杠解释为不属于过程/包

因此,如果您在“CREATE ...”字符串的末尾有一个斜杠(在新行上),那么这将是一个错误。但是,如果由IDE加载并重新编译,IDE可能会为您删除它。

在C#加载后检查USER_ERRORS,并查看该程序单元是否报告错误。