Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 循环中的DB2更新不执行_Loops_Db2_Sql Update_Execute - Fatal编程技术网

Loops 循环中的DB2更新不执行

Loops 循环中的DB2更新不执行,loops,db2,sql-update,execute,Loops,Db2,Sql Update,Execute,我有以下代码: BEGIN DECLARE cmd VARCHAR(1024); DECLARE attr CHAR(10); DECLARE attr2 CHAR(10); DECLARE at_end INTEGER DEFAULT 0; DECLARE not_found CONDITION FOR SQLSTATE '02000'; DECLARE updstr1 VARCHAR(1024); DECLARE updstr2 VARCHAR(1024); DECLARE c1

我有以下代码:

  BEGIN
DECLARE cmd VARCHAR(1024); DECLARE attr CHAR(10); 
DECLARE attr2 CHAR(10); 
DECLARE at_end INTEGER DEFAULT 0;
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE updstr1 VARCHAR(1024);
DECLARE updstr2 VARCHAR(1024);


DECLARE c1 CURSOR FOR SELECT cmd, attr, attr2 
                      FROM commandtbl2;

DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;

SET updstr1 = 'update commandtbl3 t2 set t2.XXXX = attr where t2.cmd=cmd';
SET updstr2 = 'update commandtbl3 t2 set t2.XXXX= attr2 where t2.cmd=cmd';
OPEN c1;

ins_loop: LOOP

  FETCH c1 INTO cmd, attr, attr2; 

  IF at_end = 1 THEN
    LEAVE ins_loop;
  ELSEIF cmd != '' THEN
    ITERATE ins_loop;
  END  IF;

  set updstr1= REPLACE(updstr1,'XXXX','attr');
  set updstr2= REPLACE(updstr2,'XXXX','attr2');

  EXECUTE IMMEDIATE updstr1;
  EXECUTE IMMEDIATE updstr2;


END LOOP;

CLOSE c1;
END@
它运行时没有错误,但当我检查commandtbl3时,没有任何更新。所有值均为空,但应替换。两个表中都有7行,其中5行具有匹配的cmd值,因此这5行应该更新

我不确定替换是否不起作用或立即执行

通过调试,我发现updstr1和2个变量在替换后是空的。。。但是为什么呢

你能帮我吗? 谢谢 流浪汉

根据要求,以下是commandtbl3和CommandTBL2的定义:

CREATE TABLE "TEST"."COMMANDTBL3" (
    "ID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY ( START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 NO CYCLE CACHE 2 NO ORDER ), 
    "CMD" VARCHAR(1024 OCTETS) NOT NULL, 
    "ATTR" CHAR(10 OCTETS), 
    "ATTR2" CHAR(10 OCTETS), 
    CONSTRAINT "CC1455789123996" PRIMARY KEY
    ("ID")
)

CREATE TABLE "TEST"."COMMANDTBL2" (
    "ID" INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY ( START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 NO CYCLE CACHE 2 NO ORDER ), 
    "CMD" VARCHAR(1024 OCTETS) NOT NULL, 
    "ATTR" CHAR(10 OCTETS), 
    "ATTR2" CHAR(10 OCTETS), 
    CONSTRAINT "CC1455789123996" PRIMARY KEY
    ("ID")
)
COmmandtbl3的CMD等于commandtbl2,但有2行(共7行)除外,COmmandtbl3中的attr和attr2为NMULL。我希望commandtbl2 attr和attr2的值通过更新并替换命令写入commandtbl3,这样我就可以有占位符XXXX

以下是工作代码:

如果有人有相同的问题,这里是工作代码,即使从开始的代码更改(while loop now,等等):


代码中有一些逻辑错误

  • 在您的循环中:

    IF at_end = 1 THEN
      LEAVE ins_loop;
    ELSEIF cmd != '' THEN
      ITERATE ins_loop;
    END  IF;
    
    ELSEIF
    语句告诉DB2,如果
    cmd
    (from
    commandtbl2
    )不是空字符串,它应该跳过循环迭代中的其余步骤(即,它什么也不做,只需跳回循环开始时的
    FETCH
    语句)

    这可能就是你没有看到任何事情发生的原因

  • 正如@mustaccio在上面的评论中提到的,您似乎假设在执行
    executeimmediate
    语句时,DB2会神奇地用变量的值替换变量。你的声明:

    update commandtbl3 t2 set t2.XXXX = attr where t2.cmd=cmd
    
    update commandtbl3 t2 set t2.attr = attr where t2.cmd=cmd
    update commandtbl3 t2 set t2.attr2 = attr2 where t2.cmd=cmd
    
    您的代码将替换XXXX,但看起来确实是假定
    =attr
    =cmd
    也将替换为
    FETCH
    语句中设置的值。事实并非如此

    请参见此示例:

    DECLARE GLOBAL TEMPORARY TABLE t1 (c1 int) 
    ON COMMIT PRESERVE ROWS WITH REPLACE
    @
    
    BEGIN
        DECLARE v1 INT;
        DECLARE vSQL VARCHAR(128);
    
        SET vSQL = 'INSERT INTO SESSION.T1 values (v1)';
        SET v1 = 12;
    
        EXECUTE IMMEDIATE vSQL;
    END
    @
    
    当数据库到达
    executeimmediate
    语句时,它不会在运行时将v1替换为v1的值。它将执行准确的语句
    插入SESSION.T1值(v1)
    。这当然会失败,因为v1对数据库没有任何意义

    在您的情况下,
    executeimmediate
    语句不会失败,因为
    attr
    cmd
    对数据库有一定的意义–它们是表
    commandtbl3
    中的列名。因此,执行的update语句将是(在REPLACE语句之后):

    这些基本上没有操作,比如
    更新T1集合C1=C1,其中C2=C2

    这是一个很好的例子,说明了为什么不应该使用与数据库中的列相同的名称来声明变量。它增加了混乱,并且可以隐藏逻辑错误


  • 再次查看手册,了解如何在动态语句中使用参数。提示:将有一个
    PREPARE
    语句,
    EXECUTE
    将有一个
    USING
    子句。我知道PREPARE语句来自嵌入sql的其他编码语言,如果我也只使用SQL,并且没有参数标记,我只需要替换一个字符串。您确实希望
    中的
    cmd
    ,其中t2.cmd=cmd
    中的后一个
    会被您先前获取的变量神奇地替换,不是吗?不会发生的。我希望XXXX被替换为attr和attr2。替换前的命令是正确的,替换后的变量是空的。那是在执行之前。变量本身在替换之后是空的。我研究了替换、翻译、准备、执行和使用。。。在如何更改子字符串并让它按照IBM在其页面上所写的内容来执行这一点上,我被打败了
    
    update commandtbl3 t2 set t2.attr = attr where t2.cmd=cmd
    update commandtbl3 t2 set t2.attr2 = attr2 where t2.cmd=cmd