【问题标题】:Send PL/SQL to Oracle without creating a stored procedure在不创建存储过程的情况下将 PL/SQL 发送到 Oracle
【发布时间】:2017-01-02 09:46:39
【问题描述】:

我是 PL/SQL Oracle 的新手。我习惯于使用 JDBC 框架和标准 SQL。

例如下一个PL/SQL:

IF EXISTS (SELECT * FROM Table1 WHERE Column1=’SomeValue’)
    UPDATE Table1 SET (…) WHERE Column1=’SomeValue’
ELSE
    INSERT INTO Table1 VALUES (…)

这句话必须从oracle中的存储过程中执行,所以你必须在数据库中创建一个过程并调用它,但为什么我不能像“select”语句那样将这句话发送到数据库并且没有执行必须先创建一个存储过程?

【问题讨论】:

  • 您实际上并不需要 PL/SQL,您可以使用 MERGE。或者使用匿名 PL/SQL 块。不需要存储过程。
  • 我知道,谢谢。我的意思是为什么我不能像选择语句一样向数据库发送 pl/sql。
  • 因为您要求它执行一个不完整的 PL/SQL 块。至少,您需要将其转换为有效的匿名 PL/SQL 块:begin <insert_pl_sql_code_here> end;
  • 您没有向我们展示您的实际代码,因此我们无法说明它失败的原因。

标签: java stored-procedures jdbc plsql


【解决方案1】:

实际上,您可以使用客户端直接对数据库执行 PL/SQL,并将您的代码嵌入到“begin ... end”结构中。

例如使用sqlplus 这将如下所示(永远不要忘记以/ 结束plsql 语句 - 最后一行/第一个字符):

begin
  IF EXISTS (SELECT * FROM Table1 WHERE Column1=’SomeValue’) 
  THEN
    UPDATE Table1 SET (…) WHERE Column1=’SomeValue’
    ;
  ELSE
    INSERT INTO Table1 VALUES (…) 
    ;
  END IF;
end;
/

(我为您的if / else 结构添加了正确的语法)

【讨论】:

  • OP 中的 if exists (implicit cursor) 构造实际上并不是 PL/SQL。可能他正在考虑其他一些语言。
【解决方案2】:

您可以使用可调用语句执行匿名 PL/SQL 块。您需要使用准备好的语句,因为它可以提高 Oracle 的性能并防止 SQL 注入。

PL/SQL 块使用 BEGIN 和 END 嵌套,或者如果您有局部变量,则使用 DECLARE / BEGIN / END。

String plsqlBlock =
    "begin " +
    "  update Table1 " +
    "    set val1 = :v1, val2 = :v2 " +
    "    where primary_key = :pk; " +
    "  if sql%rowcount = 0 then " +
    "    insert into Table1 (primary_key, val1, val2) " +
    "      values (:pk, :v1, :v2); " +
    "  end if; " +
    "end;";

CallableStatement cs = connection.prepareCall(plsqlBlock);
cs.setInt("pk", 12345);
cs.setString("v1", "abc");
cs.setString("v2", "def");
cs.execute();

【讨论】:

    猜你喜欢
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 2013-10-07
    • 1970-01-01
    相关资源
    最近更新 更多