【发布时间】:2021-07-15 13:42:28
【问题描述】:
如何在 Firebird 存储过程中使用索引变量?我的意思是,我有输出参数 ODATE1、ODATE2、ODATE3,我可以用作 ':ODATE' || COUNTER 循环设置值?
我有 2 个这样的表:
1. T_EMPLOYEE
---------------
| ID_E | NAME |
---------------
| 1 | Anne |
---------------
| 2 | Bob |
---------------
2. T_WORK
----------------------------
| ID_W | DATE_W | ID_E |
----------------------------
| 1 | 2021-01-01 | 1 |
----------------------------
| 2 | 2021-01-01 | 2 |
----------------------------
| 3 | 2021-01-02 | 1 |
----------------------------
| 4 | 2021-01-03 | 2 |
----------------------------
我想从那个表中创建一个存储过程来得到这个结果:
DASHBOARD
-----------------------------------------------------------
| OID_E | ONAME | ODATE1 | ODATE2 | ODATE3 |
----------------------------------------------------------
| 1 | Anne | 1 | 1 | 0 |
-----------------------------------------------------------
| 2 | Bob | 1 | 0 | 1 |
-----------------------------------------------------------
我尝试在存储过程中像这样使用EXECUTE STATEMENT:
DECLARE VARIABLE COUNTER INT;
BEGIN
FOR
SELECT ID_E, NAME FROM T_EMPLOYEE
INTO :OID_E, :ONAME
D0
BEGIN
COUNTER = 1;
WHILE (COUNTER<=3) DO
BEGIN
EXECUTE STATEMENT 'SELECT COUNT(*) FROM T_WORK WHERE DATE_W = ''2021-01-0' || COUNTER ||
''' AND ID_E = ' || :OID_E || ' INTO :ODATE' || COUNTER;
COUNTER = COUNTER + 1;
END
SUSPEND;
END
END /*procedure*/
程序无法编译。 然后我尝试了这样简单的没有 COUNTER 索引替换:
DECLARE VARIABLE COUNTER INT;
BEGIN
FOR
SELECT ID_E, NAME FROM T_EMPLOYEE
INTO :OID_E, :ONAME
D0
BEGIN
COUNTER = 1;
WHILE (COUNTER<=3) DO
BEGIN
EXECUTE STATEMENT 'SELECT COUNT(*) FROM T_WORK WHERE ID_E = :OID_E ' ||
' AND DATE_W =''2021-01-02'' INTO :ODATE2';
COUNTER = COUNTER + 1;
END
SUSPEND;
END
END /*procedure*/
程序可以编译,但是执行时会报这个错误:
SQL Error: Dynamic SQL Error SQL error code = @1 Token unknown - line @1, column @2 @1. Error Code: -104. Invalid token
请给我一些见解。如何使用 EXECUTE STATEMENT 进行灵活循环来设置索引变量。 或者您有其他解决方案来满足我的需求。
附加信息:Firebird v2.5
【问题讨论】:
-
您到底想达到什么目的?以及您是如何执行此操作的,因为显然您使用的任何东西都没有正确呈现 Firebird 错误消息。无论如何,问题之一是您在传递给
EXECUTE STATEMENT的语句文本中有一个INTO子句。传递给EXECUTE STATEMENT的语句应该是DSQL,而INTO只在PSQL 中有效。您需要使用INTO作为EXECUTE STATEMENT本身的子句。 -
在任何情况下,查看表和所需的输出,您甚至不需要
EXECUTE STATEMENT,您可以使用单个查询来完成此操作(即使不使用存储过程)。 -
转置(数据透视表,象在苏联调用的象棋表)在客户端应用程序(报告生成器等)中比 RDBMS 更好。这只是应用程序适合的任务,而不是数据库引擎
-
嗨@MarkRotteveel,实际上我想制作一个每月31天的表格,显示我员工的工作时间。我在这里展示的示例使用t_work中的单个日期列,但是在这里,我有两列包含开始日期和结束日期。感谢您在下面的简单回答,我将尝试适应检查日期是否在 t_work 中的日期之间。非常感谢..我会尽快通知结果..
-
这正是您在数据库服务器中不应该做的事情。它在工作中使用了错误的工具,例如用叉子喝茶。这个问题实际上似乎与 stackoverflow.com/questions/48262968/… 和 stackoverflow.com/questions/55449169/… 以及许多其他问题重复
标签: stored-procedures firebird firebird2.5 firebird-psql