我知道有人问before但这些解决方案似乎与我无关。
我目前正在尝试这样做:
所以#3点似乎到目前为止工作,如果我打开SQL Developer并展开程序树列表然后我实际上可以看到程序,但是用红色圆圈表示虽然运行相同的代码但它有编译器错误,非常小,在SQL Developer查询窗口中工作正常并编译它。我不确定SQL Developer是否会做一些事情,因为运行“CREATE PROCEDURE”脚本不会抛出任何错误,然后我可以看到并执行该过程,但不是这样从C#进行。
我在开头发布的链接中读到我应该调用IDBCommand.Prepare()
,但只有当你的SQLCommand.CommandType类型为StoredProcedure并且我实际上没有调用过程时,该方法才有意义。运行纯sql来创建程序然后这不起作用,尽管如此,我只是为了测试,创建了一个新命令,我分配给StoredProcedure然后在该命令上调用Prepare()方法,最后{{ 1}}抛出异常的对象(存储过程)的方法,因为它还没有被编译,所以这是有意义的...
所以,我想知道是否有人真的知道你如何创建一个程序并从C#编译它,我们目前正在使用企业库,但我不介意直接向oracle提供者“硬编码”的东西,只要它有效
顺便说一下,在告诉我从代码中创建一个程序是一个不好的做法我告诉你,不幸的是这是一个客户的项目,我们没有做出决定,实际上我们正在尝试将事物从SQL Server迁移到甲骨文。答案 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,并查看该程序单元是否报告错误。