使用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
@
答案 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(CONTINUE
和EXCEPTION
的内容至少) - 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'工作而创建的,所以在该范例中编写语句。 是需要循环的场合,但这不是其中之一。