【问题标题】:DB2 SELECT from UPDATE Options从 UPDATE 选项中选择 DB2
【发布时间】:2022-01-09 10:29:58
【问题描述】:

我目前正在尝试做一个

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 中是否有任何替代方法可以返回所需的结果?在一个查询中我们可以在哪里更新和返回结果?

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

【问题讨论】:

  • 我认为您无法在任何数据库中执行此操作。不要误以为select ... for update 它有不同的目的。您可以选择 .. 插入。但是仅通过存储过程或匿名块更改某些内容并返回数据
  • ibm.com/docs/en/db2/… 它在某些版本的 DB2 上提供它,其中 FINAL Table 允许插入/更新。
  • 样本数据和预期结果。
  • 已编辑以添加示例数据和预期结果。
  • 您使用的确切 db2 平台和版本是什么?

标签: sql database db2 db2-400


【解决方案1】:

您不能像在 DB2 for LUW 中那样在 DB2 IBM i 7.3(甚至目前在 7.4 中)的 table-reference 中指定 UPDATE
只有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@
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

【讨论】:

  • 感谢您告诉我。尝试执行类似任务是否有其他选择?
  • 查看更新后的答案。
【解决方案2】:

虽然您目前无法在 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 - 可重复读取意味着整个表将被锁定,直到您发出提交。如果您了解/控制使用该表的任何其他进程,则可以使用较低的 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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-16
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多