从UPDATE选项执行DB2 SELECT

mkshixfv  于 2022-11-07  发布在  DB2
关注(0)|答案(2)|浏览(520)

我目前正在尝试

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中是否有其他方法可以返回所需的结果?在一个查询中,我们可以在哪里更新并返回结果?
EDIT -Select叙述句应该会传回服务器应用程序要开始行程的值。发生这种情况时,会更新数据栏,以指出此数据列的行程已经开始。稍后的命令会在数据列行程完成时再次更新数据列。

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

乐观选择/更新查询之后

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应用程序调用的,因此它将被转换为表对象的列表。

41ik7eoe

41ik7eoe1#

在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 ---+

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

--#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@

| 识别码|列|旗标|
| - -|- -|- -|
| 一个|任务1| Y型|
| 2个|任务2| Y型|
| 三个|任务3| Y型|
| 四个|任务4| Y型|

SELECT * FROM SESSION.UPDRES@

| 识别码|
| - -|
| 一个|
| 2个|
| 三个|

oxf4rvwz

oxf4rvwz2#

虽然您目前无法在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 read意味着整个表将被锁定,直到您发出提交为止。如果您了解/控制使用该表的任何其他进程,则可以使用较低的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提供程序技术参考(IBMACSWindows应用程序包的一部分)中的iDB2DataAdapter

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红皮书中找到一些有用的信息。

相关问题