来自 UPDATE 选项的 DB2 SELECT

DB2 SELECT from UPDATE Options

我目前正在尝试做一个

SELECT DISTINCT * FROM FINAL TABLE 
(UPDATE mainTable SET value = 'N' WHERE value2 = 'Y')

不过我的DB2版本好像不支持这个

SQL Error [42601]: [SQL0199] Keyword UPDATE not expected. Valid tokens: INSERT.

在 DB2 中是否有任何替代方案可以 return 获得所需的结果?在一个查询中,我们可以在哪里更新和 Return 结果?

编辑 - Select 语句应该 return 服务器应用程序开始处理的值。发生这种情况时,将更新一列以指示该行的处理已经开始。稍后的命令将在完成后再次更新该行。

ORIGINAL DATA
ROW ID | COLUMN TWO | PROCESSING FLAG
-------------------------------------------
1      | TASK 1     |      N
2      | TASK 2     |      N
3      | TASK 3     |      N
4      | TASK 4     |      N

乐观后Select/Update查询

Data Table returned as:
ROW ID | COLUMN TWO | PROCESSING FLAG
-------------------------------------------
1      | TASK 1     |      Y
2      | TASK 2     |      Y
3      | TASK 3     |      Y
4      | TASK 4     |      Y

这是由 .NET 应用程序调用的,因此这将被转换为 Table 对象的列表。

您不能在 DB2 IBM i 7.3(现在甚至是 7.4)中的 table-reference 中指定 UPDATE,因为您可以在 Db2 for LUW 中指定。
只有 INSERT 个可用。

data-change-table-reference
-+-- FINAL -+- TABLE (INSERT statement) correlation-clause
 |          |
-+-- NEW ---+

一种可能的模拟是使用动态复合语句、定位更新和临时 table 来保存更新行的信息。

--#SET TERMINATOR @
DECLARE GLOBAL TEMPORARY TABLE SESSION.MAINTABLE 
(
  ID INT, COL VARCHAR (10), FLAG CHAR (1) 
) WITH REPLACE ON COMMIT PRESERVE ROWS NOT LOGGED@

INSERT INTO SESSION.MAINTABLE (ID, COL, FLAG)
VALUES
  (1, 'TASK 1', 'N')
, (2, 'TASK 2', 'N')
, (3, 'TASK 3', 'N')
, (4, 'TASK 4', 'Y')
@

DECLARE GLOBAL TEMPORARY TABLE SESSION.UPDRES AS 
(
SELECT ID FROM SESSION.MAINTABLE
) DEFINITION ONLY WITH REPLACE ON COMMIT PRESERVE ROWS NOT LOGGED@


BEGIN
  FOR F1 AS C1 CURSOR FOR
    SELECT ID FROM SESSION.MAINTABLE WHERE FLAG = 'N' FOR UPDATE
  DO
    UPDATE SESSION.MAINTABLE SET FLAG = 'Y' WHERE CURRENT OF C1;
    INSERT INTO SESSION.UPDRES (ID) VALUES (F1.ID);
  END FOR;
END@

SELECT * FROM SESSION.MAINTABLE@
ID COL FLAG
1 TASK 1 Y
2 TASK 2 Y
3 TASK 3 Y
4 TASK 4 Y
SELECT * FROM SESSION.UPDRES@
ID
1
2
3

虽然您目前无法在 Db2 for IBM i 上使用 SELECT FROM FINAL TABLE(UPDATE ...)...

你可以在事务的上下文中做
UPDATE mainTable SET value = 'Y' WHERE value2 = 'N' with RR
SELECT * FROM mainTable WHERE value2 = 'Y'
COMMIT

使用 RR - Repeatable 读取意味着整个 table 将被锁定,直到您发出提交。如果您有 knowledge/control 个使用 table.

的任何其他进程,您可以使用较低的 isolation level

或者如果您愿意做一些额外的工作...下面只锁定返回的行。
UPDATE mainTable SET value = '*' WHERE value2 = 'N' with CHG
SELECT * FROM mainTable WHERE value2 = '*'
UPDATE mainTable SET value = 'Y' WHERE value2 = '*' with CHG
COMMIT

直接 SQL 方法是通过光标和 UPDATE WHERE CURRENT OF CURSOR ....

最后,由于您使用的是 .NET,我建议您查看 IBM .NET Provider Technical Reference(IBM ACS Windows 的一部分)中的 iDB2DataAdapter class应用程序包)

public void Example()
{
    //create table mylib.mytable (col1 char(20), col2 int)
    //insert into mylib.mytable values('original value', 1)

    iDB2Connection cn = new iDB2Connection("DataSource=mySystemi;");
    iDB2DataAdapter da = new iDB2DataAdapter();
    da.SelectCommand = new iDB2Command("select * from mylib.", cn);
    da.UpdateCommand = new iDB2Command("update mylib.mytable set col1 = @col1 where col2 = @col2", cn);

    cn.Open();

    //Let the provider generate the correct parameter information
    da.UpdateCommand.DeriveParameters();

    //Associate each parameter with the column in the table it corresponds to
    da.UpdateCommand.Parameters["@col1"].SourceColumn = "col1";
    da.UpdateCommand.Parameters["@col2"].SourceColumn = "col2";

    //Fill the DataSet from the DataAdapter's SelectCommand
    DataSet ds = new DataSet();
    da.Fill(ds, "table");

    //Modify the information in col1

    DataRow dr = ds.Tables[0].Rows[0];
    dr["col1"] = "new value";

    //Write the information back to the table using the DataAdapter's UpdateCommand
    da.Update(ds, "table");
    cn.Close();
}

您还可以在 Integrating DB2 Universal Database for iSeries with Microsoft ADO .NET 红皮书中找到一些有用的信息。