SQL0206N“SQLSTATE”在使用它的上下文中无效。 SQLSTATE = 42703

时间:2012-01-30 23:59:52

标签: cursor db2

使用db2 -td @ -f./sql/update_product.sql执行时的以下代码 给出错误: SQL0206N“SQLSTATE”在使用它的上下文中无效。线 NUMBER = 53。 SQLSTATE = 42703

请帮忙......

  SET SERVEROUTPUT ON
  @
  CREATE OR REPLACE PROCEDURE UPLOADPRODUCTATTRIBUTES
  BEGIN 
  DECLARE   v_eisidentifier VARCHAR(100);
  DECLARE   v_categoryGuid DECIMAL(19,0); 
  DECLARE   v_localeGuid DECIMAL(19,0);
  DECLARE   v_realmGuid DECIMAL(19,0);
  DECLARE   v_catchingPhrase VARCHAR(120) ;
  DECLARE   v_genericName VARCHAR(80);
  DECLARE   v_ingredients VARCHAR(900);
  DECLARE   v_quantity VARCHAR (60);
  DECLARE   v_dose VARCHAR(40);
  DECLARE   v_nutritionFacts VARCHAR (900);
  DECLARE   v_productDescription VARCHAR(900);
  DECLARE   v_recommendedFor VARCHAR(200);
  DECLARE   v_promotionMessage VARCHAR(200);
  DECLARE   v_message VARCHAR (4500);
  DECLARE   v_proudctGuid DECIMAL(19,0);
  DECLARE   C1 CURSOR FOR
SELECT 
        EISIDENTIFIER,
        CATEGORY_GUID,
        LOCALEGUID,
        REALMGUID,
        CATCHING_PHRASE,
        GENERIC_NAME,
        INGREDIENTS,
        QUANTITY,
        DOSE,
        NUTIRITION_FACTS,
        PRODUCT_DESCRIPTION,
        RECOMMENDED_FOR,
        PROMOTION_MESSAGE,
        MESSAGE
    FROM 
        TEMP_UPLOAD_PRODUCT_ATTRIBUTES;

        OPEN C1;
        FETCH C1 into v_eisidentifier,  
                      v_categoryGuid, 
                      v_localeGuid,
                      v_realmGuid,
                      v_catchingPhrase,
                      v_genericName,
                      v_ingredients,
                      v_quantity,
                      v_dose,
                      v_nutritionFacts,
                      v_productDescription,
                      v_recommendedFor,
                      v_promotionMessage,
                      v_message
        ;
        WHILE (SQLSTATE = '00000') 
        DO
            IF EXISTS (SELECT 1 FROM PRD_PRODUCT WHERE EISIDENTIFIER = v_eisidentifier)
            THEN
                SELECT GUID INTO v_productGuid FROM PRD_PRODUCT WHERE EISIDENTIFIER = v_eisidentifier;

                UPDATE PRD_PRODUCT_L10N
                SET CATEGORY_GUID = v_categoryGuid,
                    REALMGUID = v_realmGuid,
                    CATCHING_PHRASE =v_catchingPhrase,
                    GENERIC_NAME =v_genericName,
                    INGREDIENTS =v_ingredients,
                    QUANTITY=v_quantity,
                    DOSE=v_dose,
                    NUTIRITION_FACTS=v_nutritionFacts,
                    PRODUCT_DESCRIPTION=v_productDescription,
                    RECOMMENDED_FOR=v_recommendedFor,
                    PROMOTION_MESSAGE=v_promotionMessage,
                    MESSAGE=v_message
                WHERE PRODUCTGUID =v_proudctGuid and LOCALGUID =v_categoryGuid;

                IF NOT EXISTS (SELECT 1 FROM PRD_PRODUCT_CATEGORY WHERE CATEGORY_GUID=v_categoryGuid AND PRODUCT_GUID=v_productGuid)
                THEN
                    INSERT INTO PRD_PRODUCT_CATEGORY (CATEGORY_GUID, PRODUCT_GUID) VALUES (v_categoryGuid,v_productGuid);
                ELSE 
                    -- do nothing
                END IF;
            ELSE 
                --  INSERT INTO --- should not be the case....
            END IF;


            FETCH C1 into v_productGuid,    
                      v_categoryGuid, 
                      v_localeGuid,
                      v_realmGuid,
                      v_catchingPhrase,
                      v_genericName,
                      v_ingredients,
                      v_quantity,
                      v_dose,
                      v_nutritionFacts,
                      v_productDescription,
                      v_recommendedFor,
                      v_promotionMessage,
                      v_message
            ;
        END WHILE;
    CLOSE c1;           
  END 
  @

2 个答案:

答案 0 :(得分:3)

存储过程告诉您没有声明SQLSTATE变量。 尽管SQLSTATE是一个特殊变量,其值由数据库(存储过程解释器或编译器)隐式维护,但是当您想要使用它时仍需要声明它:

DECLARE SQLSTATE CHAR(5);

顺便说一下,SQLCODE变量也是如此:

DECLARE SQLCODE INTEGER DEFAULT 0;

Here's the documentation适用于旧版本,但仍应适用。

重要:SQLSTATE的值仅适用于前一个语句。 如果使用处理程序来处理警告和异常,并且希望在处理程序中使用SQLSTATE值,并且处理程序包含多个语句,则需要在执行任何其他操作之前保存SQLSTATE值。

只要循环体中的最后一个语句是确定SQLSTATE值的语句,示例中的WHILE循环才有效。另一种方法是使用专用布尔值done,并根据您的逻辑,将continue handler for not found设置为TRUE。

答案 1 :(得分:0)

尽管我能说,但SQLSTATE并不存在于您所考虑的格式中;并且至少,你不能用它来控制你的循环执行(这里)。相反,您需要使用名为HANDLER s(CONTINUEEXCEPTION的内容至少) - SQLSTATE可用 整个程序(......很多)。

除此之外,您使用的循环没有明显的好处 - 整个过程可以重写为几个标准INSERT。您需要完成该程序,但您的陈述相当于:

UPDATE Prd_Product_L10N as a
SET (category_guid, realmGuid, catching_phrase, 
     generic_name, ingredients, quantity, dose, 
     nutrition_facts, product_description, recommended_for, 
     promotion_message, message) = 
               (SELECT b.category_guid, b.realmGuid, b.catching_phrase, 
                       b.generic_name, b.ingredients, b.quantity, b.dose, 
                       b.nutrition_facts, b.product_description, b.recommended_for, 
                       b.promotion_message, b.message
                 FROM Temp_Upload_Product_Attributes as b
                 JOIN Prd_Product as c
                 ON c.eisIdentifier = b.eisIdentifier
                 AND c.guid = a.productGuid
                 WHERE b.category_guid = a.localGuid)

WHERE EXISTS (SELECT '1' 
              FROM Temp_Upload_Product_Attributes as b
              JOIN Prd_Product as c
              ON c.eisIdentifier = b.eisIdentifier
              AND c.guid = a.productGuid
              WHERE b.category_Guid = a.localGuid);

INSERT INTO Prd_Product_Category (category_guid, product_guid)
SELECT a.localGuid, a.productGuid
FROM Prd_Product_L10N as a
WHERE NOT EXISTS (SELECT '1'
                  FROM Prd_Product_Category as b
                  WHERE b.category_guid = a.localGuid
                  AND b.product_guid = a.productGuid);

请注意,由于优化程序的工作方式,这些可能更快 (多少,甚至如果没有,运行分析仪)。让我们面对现实:循环和使用游标是如何真正意图使用SQL - SQL是为了做'Set'工作而创建的,所以在该范例中编写语句。 需要循环的场合,但这不是其中之一。