【问题标题】:How do I select the row which I modified in Oracle SQL如何选择我在 Oracle SQL 中修改的行
【发布时间】:2018-12-10 17:53:56
【问题描述】:

我想更新一行,之后我想在 Oracle SQL 中检索整行。我正在使用的表和相应的查询如下所示。我想避免两次查询数据库。因此,我在更新后进行了选择,但我遇到了查询后显示的错误。知道如何解决这个问题吗?

CREATE TABLE mytable (
    sid NUMBER NOT NULL,
    eid VARCHAR(18) NOT NULL,
    first TIMESTAMP,
    updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    created TIMESTAMP,
    status VARCHAR(30),
    tid VARCHAR(18),
    wid VARCHAR(18),
    CONSTRAINT mytable_pk PRIMARY KEY (sid, eid)
    ENABLE
);

BEGIN
UPDATE mytable SET wid=?, status=? WHERE sid=?;
SELECT * FROM mytable WHERE sid=?;
END;

错误:

java.sql.SQLException
ORA-06550: line 3, column 7:
PLS-00428: an INTO clause is expected in this SELECT statement

对应的Java代码片段:

PreparedStatement statement = prepareStatement(sql);
int index = 0;
statement.setString(index++, newWid);
statement.setString(index++, newStatus);
statement.setInt(index++, sid);
statement.setInt(index++, sid);
ResultSet results = statement.executeQuery();
if (results.next()) {
    Record rec = new Record();
    fill(rec, results);
}
return record;

【问题讨论】:

  • 在您的示例中,您仍在查询数据库两次,只是在匿名 PL/SQL 块中。您打算从哪里调用它,您将如何处理返回的行?
  • PL/SQL 要求您 SELECT STUFF INTO 一个变量。这就是错误消息告诉您的内容。

标签: sql oracle plsql sql-update sql-returning


【解决方案1】:

您可以使用returning into 子句,如下所示:

SQL> set serveroutput on;
SQL> DECLARE
  v_sid      mytable.sid%type;
  v_eid      mytable.eid%type;
  v_first    mytable.first%type;
  v_updated  mytable.updated%type;    
  v_created  mytable.created%type;
  v_status   mytable.status%type;
  v_tid      mytable.tid%type;
  v_wid      mytable.wid%type;        
BEGIN
  UPDATE mytable 
     SET wid=v_wid, status=v_status
   WHERE sid = v_sid
   RETURNING sid, eid, first, updated,
             created, status, tid, wid 
        INTO v_sid, v_eid, v_first, v_updated,
             v_created, v_status, v_tid, v_wid;
   dbms_output.put_line(' sid :' ||v_sid);  
   dbms_output.put_line(' eid :' ||v_eid);  
   dbms_output.put_line(' first :' ||v_first);  
   dbms_output.put_line(' updated :' ||v_updated);      
   dbms_output.put_line(' created :' ||v_created);  
   dbms_output.put_line(' status :' ||v_status);  
   dbms_output.put_line(' tid :' ||v_tid);  
   dbms_output.put_line(' wid :' ||v_wid);    
END;

【讨论】:

  • 非常感谢您的帮助。我尝试使用上面的响应并遇到以下错误:Cannot perform fetch on a PLSQL statement: next
  • @Jared 不客气。我认为您在应用程序代码中为您的statement 使用executeQuery() 方法,请尝试使用execute() 方法。
  • 谢谢@Barbaros。如果我使用执行,那么我将不会得到一个 ResultSet。如何检索我想要的所有值?
  • @Jared stackoverflow.com/questions/19443213/… 作为 JDBC 代码可能会有所帮助。
  • 我可以在这里使用 %ROWTYPE 吗?
【解决方案2】:

在匿名的 PL/SQL 块中,您可以使用 UDPATE 进行数据修改,但要选择数据,您需要将其选择到某物中。具有与您选择的数据相对应的行类型的变量,显式或隐式游标或类似的东西。 示例:

BEGIN
   UPDATE mytable SET wid=?, status=? WHERE sid=?;
   FOR R in (SELECT * FROM mytable WHERE sid=?) LOOP
       DMBS_OUTPUT.PUT_LINE(r.sid ||' ' || r.wid);
       ... do something here
   END LOOP;
END:

【讨论】:

    猜你喜欢
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2014-07-11
    • 2020-05-29
    • 2018-06-24
    • 1970-01-01
    相关资源
    最近更新 更多