sql - 无论如何要测试SQL中的函数吗?
问题描述
我有以下问题。我做了一个检查日期、仓库是否已满等的功能。
这是代码,我添加了注释,因此更清晰易懂:
SET SERVEROUTPUT ON
CREATE OR REPLACE
PROCEDURE Anlieferung (P_Artikelbezeichnung VARCHAR, P_Datum date, P_Stueck INT) AS
_inputQuantity int;
_currentQuantity int;
_inputItem int;
_articleNummber int;
_quanitityToInput int:=P_Stueck;
_maximumLnr int;
BEGIN
FOR v_rec IN (SELECT * FROM lager) LOOP -- implicit cursor
_currentQuantity:=0;
SELECT artikel.anr -- Adding our article nummber in our variable called "_articleNummber"
INTO _articleNummber
FROM artikel
WHERE artikel.bezeichnung = P_Artikelbezeichnung;
FOR buchung IN(SELECT * FROM lagerbuchung lag --Checking the lnr and the date
WHERE lag.lnr = v_rec.lnr AND P_Datum >= lag.datum)
LOOP
--Menge in _currentQuantity einfügen
_currentQuantity:=_currentQuantity + buchung.stueck; --Adding our current quantity in our variable called "_currentQuantity"
END LOOP;
IF(v_rec.stueckkap > _currentQuantity OR _quanitityToInput >0) --Checking our capacity
THEN
_inputItem:=v_rec.stueckkap - _currentQuantity;
IF(_inputItem <= _quanitityToInput)
THEN
_inputQuantity:= _inputItem;
_quanitityToInput:=_quanitityToInput - _inputItem;
ELSE
_inputQuantity:= _quanitityToInput;
_quanitityToInput:=0;
END IF;
SELECT COALESCE(MAX(lfndnr),0) -- If we have null in our table, we will also get null in return
INTO _maximumLnr
FROM lagerbuchung;
_maximumLnr:=_maximumLnr +1;
--Inserting our new values in our table
INSERT INTO lagerbuchung (lfndnr, datum, stueck, anr, lnr) VALUES (_maximumLnr, P_Datum, _inputQuantity, _articleNummber, v_rec.lnr);
END IF;
END LOOP;
END Anlieferung;
/
SELECT l.LNR, SUM(lb.STUECK) FROM LAGER l JOIN LAGERBUCHUNG lb on l.lnr = lb.lnr group by l.lnr order by l.lnr;
EXEC Anlieferung('Apfel', '27.11.2015', 160);
SELECT l.LNR, SUM(lb.STUECK) FROM LAGER l JOIN LAGERBUCHUNG lb on l.lnr = lb.lnr group by l.lnr order by l.lnr;
所以基本上如果我只运行这个函数,我不会得到任何错误。但是当我使用测试日期运行它时,我收到以下错误:
Fehler beim Start in Zeile : 166 in Befehl -
EXEC Anlieferung('Apfel', '27.11.2015', 160)
Fehlerbericht -
ORA-06550: line 1, column 7:
PLS-00905: object IF4EBIHORACM.ANLIEFERUNG is invalid
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
我试图调试它并输入不同的测试日期,但仍然是同样的错误。
解决方案
编译该过程后,请运行:
SHOW ERRORS
或(假设您将其作为拥有用户而不是作为 DBA 用户进行编译;如果您不是拥有用户,则使用ALL_ERRORS
):
SELECT * FROM USER_ERRORS;
要么会为您提供程序中的错误列表,然后您可以对其进行调试并修复错误,以便程序正常工作。
更新
从评论:
2/1 PLS-00103: Encountered the symbol "_" when expecting one of the following: begin function pragma procedure subtype type <an identifier> <a double-quoted delimited-identifier> current cursor delete exists prior external language
可能是因为我的变量?它们以下划线开头
从数据库对象名称和限定符文档中:
数据库对象命名规则
每个数据库对象都有一个名称。在 SQL 语句中,您使用带引号的标识符或不带引号的标识符来表示对象的名称。
- 带引号的标识符以双引号 (") 开头和结尾。如果您使用带引号的标识符命名架构对象,则在引用该对象时必须使用双引号。
- 不带引号的标识符不被任何标点符号包围。
...
- 不带引号的标识符必须以数据库字符集中的字母字符开头。带引号的标识符可以以任何字符开头。
您有许多以下划线开头的变量标识符。这告诉您解决方案是将变量名称更改为以字母字符开头(或使用带引号的标识符并用双引号将标识符括起来;但不要使用带引号的标识符,只需在下划线):
CREATE OR REPLACE PROCEDURE Anlieferung (
P_Artikelbezeichnung VARCHAR,
P_Datum date,
P_Stueck INT
)
AS
v_inputQuantity int;
v_currentQuantity int;
v_inputItem int;
v_articleNummber int;
v_quanitityToInput int:=P_Stueck;
v_maximumLnr int;
BEGIN
...
另外,不要使用:
SELECT COALESCE(MAX(lfndnr),0) -- If we have null in our table, we will also get null in return
INTO _maximumLnr
FROM lagerbuchung;
_maximumLnr:=_maximumLnr +1;
因为如果同时调用该过程两次,它可能会生成重复值。
相反,为该列创建一个序列并从该序列中获取下一个值。
CREATE SEQUENCE lagerbuchung__lfndnr__seq START WITH 213 INCREMENT BY 1;
(从当前最大值多 1 开始。)
然后在您的程序中使用:
INSERT INTO lagerbuchung (
lfndnr,
datum,
stueck,
anr,
ln
) VALUES (
lagerbuchung__lfndnr__seq.NEXTVAL,
P_Datum,
v_inputQuantity,
v_articleNummber,
v_rec.lnr
);
推荐阅读
- email - 带有附件问题的电子邮件
- javascript - THREE.js 中的 Shadertoy
- sql - SQL查询执行计划和优化(索引)
- node.js - 使用 firebase 通过 ejs 部分登录
- php - 如何使用 phpLDAPadmin 在 OpenLDAP 中输入已经散列的密码?
- groovy - Groovy:点击与使用
- javascript - 如何使用 php 甚至 javascript 将新的 csv 文件作为新列合并到现有的 csv 文件中
- ios - 如何在 Azure 构建/发布管道上替换 IPA 文件上的端点?
- android-studio - 广告无法在 android studio 中加载
- node.js - Mongoose 在没有 ref 的情况下查找其他集合