Plsql 如何返回insert语句以通过java代码而不是存储过程执行它

Plsql 如何返回insert语句以通过java代码而不是存储过程执行它,plsql,Plsql,我有一个存储过程,它有10个select语句和一个insert语句。Insert语句将数据插入由10 select语句设置的表中。但我希望这个insert语句不应该在存储过程本身中执行,但我希望10个select语句应该将这10个选定值发送回java代码,然后在java代码中执行insert语句。下面是存储过程,请为我提供java代码 Java代码: CallableStatement objStatement= null; Connection objConnection = g

我有一个存储过程,它有10个select语句和一个insert语句。Insert语句将数据插入由10 select语句设置的表中。但我希望这个insert语句不应该在存储过程本身中执行,但我希望10个select语句应该将这10个选定值发送回java代码,然后在java代码中执行insert语句。下面是存储过程,请为我提供java代码

Java代码:

      CallableStatement objStatement= null; 
Connection objConnection = getConnection(); 
try { objStatement = objConnection.prepareCall("{call test_proc(?)}"); objStatement.setDate(1 , new java.sql.Date( sysdate1.getTime())); objStatement.executeUpdate();   
} catch (SQLException e) { e.printStackTrace(); 
log.info("There is some problem in Data Generation : Exception"+e); 
程序:

CREATE OR REPLACE
PROCEDURE "test_proc"(
    p_fromdate DATE)
AS
  fromdate DATE;
  todate DATE;
  emp_id            NUMBER := 0;
  emp_address       NUMBER := 0;
  emp_dob           NUMBER := 0;
  emp_doj           NUMBER := 0;
  emp_msisdn        NUMBER := 0;
  emp_name          NUMBER := 0;
  emp_vehicl_number NUMBER := 0;
  emp_vehicl_type   NUMBER := 0;
  emp_middle_name   NUMBER := 0;
  emp_last_name     NUMBER := 0;
BEGIN
  SELECT id INTO emp_id FROM employee ;
  SELECT address INTO emp_address FROM employee ;
  SELECT dob INTO emp_dob FROM employee ;
  SELECT doj INTO emp_doj FROM employee ;
  SELECT msisdn INTO emp_msisdn FROM employee ;
  SELECT name INTO emp_name FROM employee ;
  SELECT vehicle_number INTO emp_vehicl_number FROM employee ;
  SELECT vehicle_type INTO emp_vehicl_type FROM employee ;
  SELECT middlename INTO emp_middle_name FROM employee ;
  SELECT lastNAme INTO emp_last_name FROM employee ;
  INSERT
  INTO test
    (
      idofEmp,
      Empaddress,
      Empdob,
      Empdoj,
      Empmsisdn,
      Empname,
      Empvehicle_number,
      Empvehicle_type,
      Empmiddlename,
      EmplastNAme
    )
    VALUES
    (
      emp_id,
      emp_address,
      emp_dob,
      emp_doj,
      emp_msisdn,
      emp_name,
      emp_vehicl_number,
      emp_vehicl_type,
      emp_middle_name,
      emp_last_name
    );
END;
请忽略数据类型:


我只希望最后一条insert语句应该由java代码执行,而不是由过程执行。我不希望将insert语句保留在存储过程中。请建议

无需执行10个单独的SELECT语句来从EMPLOYEE检索10个单独的字段;您可以在一条语句中执行此操作:

SELECT ID, ADDRESS, DOB, DOJ,
       MSISDN, NAME, VEHICLE_NUMBER,
       VEHICLE_TYPE, MIDDLENAME, LASTNAME
  INTO emp_id, emp_address, emp_dob, emp_doj,
       emp_msisdn, emp_name, emp_vehicl_number,
       emp_vehicl_type, emp_middle_name, emp_last_name
  FROM EMPLOYEE;
但是,由于没有WHERE子句来限制返回的行数,如果EMPLOYEE表中有多行,则原始的10语句和上述语句都将失败,并出现“太多行”异常

就“返回”INSERT语句而言,一种方法是返回INSERT语句的文本,以便可以从Java执行它。比如:

CREATE OR REPLACE FUNCTION test_func(p_fromdate DATE)
  RETURN VARCHAR2
AS
  fromdate DATE;
  todate DATE;
  emp_id            NUMBER := 0;
  emp_address       NUMBER := 0;
  emp_dob           NUMBER := 0;
  emp_doj           NUMBER := 0;
  emp_msisdn        NUMBER := 0;
  emp_name          NUMBER := 0;
  emp_vehicl_number NUMBER := 0;
  emp_vehicl_type   NUMBER := 0;
  emp_middle_name   NUMBER := 0;
  emp_last_name     NUMBER := 0;
  strInsert_stmt    VARCHAR2(2000);
BEGIN
  SELECT id, address, dob, doj,
         msisdn, name, vehicle_number,
         vehicle_type, middlename, lastname
    INTO emp_id, emp_address, emp_dob, emp_doj,
         emp_msisdn, emp_name, emp_vehicl_number,
         emp_vehicl_type, emp_middle_name, emp_last_name
    FROM employee;

  strInsert_stmt := 'INSERT INTO test ' ||
                      '(idofEmp, Empaddress, Empdob, Empdoj, ' ||
                      'Empmsisdn, Empname, Empvehicle_number, ' ||
                      'Empvehicle_type, Empmiddlename, EmplastNAme) ' ||
                    'VALUES (' ||
                       emp_id || ',' ||
                       emp_address || ',' ||
                       emp_dob || ',' ||
                       emp_doj || ',' ||
                       emp_msisdn || ',' ||
                       emp_name || ',' ||
                       emp_vehicl_number || ',' ||
                       emp_vehicl_type || ',' ||
                       emp_middle_name || ',' ||
                       emp_last_name || ')';

  RETURN strInsert_stmt;
END TEST_PROC;
最后一点建议-在Oracle中,您不应该创建具有小写或混合大小写名称的对象,就像您将“test_proc”放在双引号中所做的那样。这样做会导致问题,因为大多数人不希望对象的命名使用默认(大写)以外的任何形式,并且因为这些对象的任何未来使用都将要求名称包含在双引号中。例如,我认为要从Java调用过程名“test_proc”(小写),您需要发送包含在双引号中的名称,如下所示:

objConnection.prepareCall("{call \"test_proc\"(?)}");
如果为了正确解析名称,必须在过程中添加大写模式名称,那么它会变得更加丑陋:

objConnection.prepareCall("{call SOME_SCHEMA.\"test_proc\"(?)}");
根据我的经验,创建对象时最好不要将它们的名称放在双引号中——名称将使用大写字母存储,但您仍然可以用小写或混合大写字母引用它们,因为如果混合大写或小写字母的名称不在双引号中,Oracle会将混合大写或小写字母的名称转换为大写字母

分享和享受

编辑 如果您喜欢使用过程而不是函数,请尝试:

CREATE OR REPLACE FUNCTION test_func(p_fromdate     IN  DATE,
                                     p_insert_stmt  OUT VARCHAR2)
  RETURN VARCHAR2
AS
  fromdate DATE;
  todate DATE;
  emp_id            NUMBER := 0;
  emp_address       NUMBER := 0;
  emp_dob           NUMBER := 0;
  emp_doj           NUMBER := 0;
  emp_msisdn        NUMBER := 0;
  emp_name          NUMBER := 0;
  emp_vehicl_number NUMBER := 0;
  emp_vehicl_type   NUMBER := 0;
  emp_middle_name   NUMBER := 0;
  emp_last_name     NUMBER := 0;
BEGIN
  SELECT id, address, dob, doj,
         msisdn, name, vehicle_number,
         vehicle_type, middlename, lastname
    INTO emp_id, emp_address, emp_dob, emp_doj,
         emp_msisdn, emp_name, emp_vehicl_number,
         emp_vehicl_type, emp_middle_name, emp_last_name
    FROM employee;

  p_insert_stmt  := 'INSERT INTO test ' ||
                      '(idofEmp, Empaddress, Empdob, Empdoj, ' ||
                      'Empmsisdn, Empname, Empvehicle_number, ' ||
                      'Empvehicle_type, Empmiddlename, EmplastNAme) ' ||
                    'VALUES (' ||
                       emp_id || ',' ||
                       emp_address || ',' ||
                       emp_dob || ',' ||
                       emp_doj || ',' ||
                       emp_msisdn || ',' ||
                       emp_name || ',' ||
                       emp_vehicl_number || ',' ||
                       emp_vehicl_type || ',' ||
                       emp_middle_name || ',' ||
                       emp_last_name || ')';
END TEST_PROC;

祝你好运。

谢谢你的帮助。但是否可以从过程本身返回插入字符串。我不想创建函数。请提供建议。已添加如何从过程返回INSERT语句字符串的示例。非常感谢您。。。它对我有用。我只是想了解更多关于p_insert_stmt的数据类型的详细信息。因为我的返回字符串将非常大。(请建议使用最大的数据类型来存储值)如果insert语句字符串的大小超过32767个字符,则需要使用CLOB。CLOB的最大大小取决于创建数据库时使用的DB_BLOCK_size参数,范围从8TB到128 TB。谢谢。是否可以并行执行此类单独的select语句。甚至没有一条语句依赖于另一条语句。因此,程序的执行时间将非常快。现在我的表有数百万条记录。