我是Firebird DML的新手。
在TransactSQL中,我可以自由而简单地声明和使用变量,如
declare @myID int
select @myID = 42
并在SELECT语句中使用这些变量
select * from mytable where id = @myID
并在不同语句之间传递值。
我的问题是,如何在客户端Firebird DML脚本中声明和使用局部变量?
使用FlameRobin,我可以一次执行一系列DML语句,例如
update mytable set price = 2 * price;
select * from mytable;
但我完全不知道如何声明和使用局部变量在它们之间传递值。
谷歌搜索,我已经看到Firebird的PSql的EXECUTE BLOCK结构,显然支持DECLARE VARIABLE,但它看起来很麻烦,似乎包含了我从未遇到的一些奇怪的限制TransactSQL似乎并不打算用于我试图做的客户端DML脚本。
答案 0 :(得分:2)
在过去的几天里,我一直在努力解决这个问题,试图完成对这个q的回答:sql and fifo simple select;我花了大约半个小时来编写和测试TransactSQL做OP所要求的方式。
我会走向已建议给你的EXECUTE BLOCK
路线,但我一直在遇到显然不允许进入DML的事情,所以我放弃了政治上正确的做法。
所以相反,我这样做可能会让Firebird纯粹主义者骇然:不要试图声明变量,只需创建一个临时表,其中包含与您将使用的变量相对应的列,以及一个ID,以便于从中提取值,然后将变量的值存储在其中的一行中。类似的东西:
create table variables(ID int, myID int, myStringVar charchar(80), [etc...])
显然,您可以根据需要初始化此表并更新列值。访问其中的值比访问变量的值更麻烦,但不是很多,如
update mytable set somecolumn = 666 where id = (select myID from variables where ID = 1)
我相信你明白了。 这是我用这种方式做的唯一的轻微刺激,而且我不确定它是Firebird还是FlameRobin,它似乎有必要在一个事务中包装像表和视图这样的db对象的创建在尝试使用它们的语句块之前已经提交。
答案 1 :(得分:1)
拥有真实变量的唯一方法 - 正如您已经发现的那样 - 是使用execute block
(其中所有意图和目的都是匿名存储过程),或者 - 当然 - 是正常的存储过程。
如answer by MartynA所示,您也可以使用表格来设置变量,但我建议您使用global temporary table,因为这会保留变量' private&# 39;连接或交易。
另一个选项(我之前完全忘记了)是使用rdb$get_context
and rdb$set_context
使用上下文变量,尽管这可能会变得有点麻烦。例如,要设置变量x
,您可以使用:
select rdb$set_context('USER_SESSION', 'x', 5) from rdb$database;
如果变量是新创建的,则返回值为0
;如果变量已存在,则返回1
。值将转换为VARCHAR(255)
,因此它们必须是可以转换为VARCHAR(255)
的类型。您可以通过将变量设置为NULL
来删除变量。您可以使用USER_SESSION
而不是USER_TRANSACTION
。
USER_SESSION
上下文绑定到当前连接。USER_TRANSACTION
中的变量仅存在于已设置它们的事务中。当事务结束时,上下文及其中定义的所有变量都将被销毁。
可以使用
获取变量select rdb$get_context('USER_SESSION', 'x') from rdb$database;
如果变量不存在,则返回NULL
,否则返回VARCHAR(255)
的值。