sql - Firebird 程序中的错误
问题描述
我必须做一个查询才能得到一个参数(我需要一个“1”),但是这个参数可以在不同的单元格中,例如:
+--------------+--------------+--------------+
|....cell1.....|.....cell2....|....cell3.....|
+--------------+--------------+--------------+
|....here......|.....here.....|....or here...|
+--------------+--------------+--------------+
我必须捕获,然后,如果它等于一个,则执行其他查询以获得我想要的。我尝试用这段代码做一个程序:
SET TERM !! ;
CREATE PROCEDURE GET_CASH(
TICKET VARCHAR(15))
RETURNS ( TOTAL integer
)
AS
BEGIN
FOR SELECT a.ID_FPAY1, a.FPAY1_IMPORT, a.ID_FPAY2, a.FPAY2_IMPORT, a.ID_FPAY3, a.FPAY3_IMPORT
FROM TB_TICKETS_HIS a WHERE a.ID_TICKET = TICKET
DO
BEGIN
IF a.ID_FPAY1 = 1 THEN TOTAL = a.FPAY1_IMPORT;
IF a.ID_FPAY2 = 1 THEN TOTAL = a.FPAY2_IMPORT;
IF a.ID_FPAY3 = 1 THEN TOTAL = a.FPAY3_IMPORT;
SUSPEND;
END
END!!
SET TERM ; !!
执行查询时出现此错误:
SQL Message : -104
Invalid token
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 11, column 5
DO
我尝试删除 FOR 和 Do 的工作,出现此错误:
SQL Message : -104
Invalid token
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 11, column 5
BEGIN
有人可以帮助我完成此程序或向我解释失败的原因吗?
解决方案
如果要FOR SELECT .. DO
在 Firebird 存储过程中使用(或单例选择),则需要使用INTO
来填充参数值。
另请参阅 Firebird 参考FOR SELECT
:
- 需要一个
INTO
位于规范末尾的子句SELECT ... FROM ...
。在循环的每次迭代中,当前行中的字段值都被复制到INTO
子句中指定的变量列表中。[..]
换句话说,根据这个存储过程的目的,你需要声明额外的返回变量或局部变量来保存 select 的相关字段,例如:
CREATE PROCEDURE GET_CASH(
TICKET VARCHAR(15))
RETURNS ( TOTAL integer
)
AS
declare id_fpay1 integer;
declare fpay1_import integer;
declare id_fpay2 integer;
declare fpay2_import integer;
declare id_fpay3 integer;
declare fpay3_import_integer
BEGIN
FOR SELECT a.ID_FPAY1, a.FPAY1_IMPORT, a.ID_FPAY2, a.FPAY2_IMPORT, a.ID_FPAY3, a.FPAY3_IMPORT
FROM TB_TICKETS_HIS a WHERE a.ID_TICKET = TICKET
into id_fpay1, fpay1_import, id_fpay2, fpay2_import, id_fpay3, fpay3_import
DO
BEGIN
IF a.ID_FPAY1 = 1 THEN TOTAL = a.FPAY1_IMPORT;
IF a.ID_FPAY2 = 1 THEN TOTAL = a.FPAY2_IMPORT;
IF a.ID_FPAY3 = 1 THEN TOTAL = a.FPAY3_IMPORT;
SUSPEND;
END
END
但是,您可以通过在 select 语句中执行该逻辑来简化这一点:
CREATE PROCEDURE GET_CASH(
TICKET VARCHAR(15))
RETURNS ( TOTAL integer
)
AS
BEGIN
FOR SELECT case
when a.id_pay3 = 1 then a.fpay3_import
when a.id_pay2 = 1 then a.fpay2_import
when a.id_pay1 = 1 then a.fpay1_import
end as total
FROM TB_TICKETS_HIS a WHERE a.ID_TICKET = TICKET
into total
DO
BEGIN
SUSPEND;
END
END
相反的顺序只是为了保留与原始代码段中相同的逻辑。从技术上讲,要保留该逻辑,它需要额外的处理来保留之前的值,total
就像您编写的代码所做的那样,但我认为这是您代码中的一个错误。
推荐阅读
- jupyter-notebook - 有没有办法让 SAS 只打印频率表的前 10 行?
- sql-server - SQL Server在while中双重录制
- php - 手动安装 laravel/ui 会报错
- airflow-scheduler - 如何在 Airflow 的 on_dag_failure 函数中获取标签?
- python - 使用 DataFrame 等效的 R 和 Python
- c++ - 隐式转换为基础类型
- python - 如何在 Python 中使用 Openpyxl 在现有 excel 文件中保留图表格式和文本框?
- node.js - Nodejs无法读取docker镜像中的文件夹“没有这样的文件或目录”
- java - LaunchDarkly:在离线模式下从客户端刷新数据
- javascript - 如何在放置回调时更新元素文本?