2

I would like to know if it is possible in Firebird to assign and reference a variable in SQL Editor context.

To be clear, I present a code sample in MySQL that do what I want.

SET @var = 10;
SELECT @var;

2 Answers 2

3

Firebird only supports variables in PSQL (Procedural SQL), including anonymous procedures (EXECUTE BLOCK). There is no direct equivalent of using variables like in MySQL in DSQL (Dynamic SQL, the normal 'SQL' you use with Firebird).

The closest alternative is to use the context variables using RDB$GET_CONTEXT and RDB$SET_CONTEXT. The near equivalent of your code would be

select RDB$SET_CONTEXT('USER_TRANSACTION', 'var', 10) from RDB$DATABASE; 
select RDB$GET_CONTEXT('USER_TRANSACTION', 'var') from RDB$DATABASE;

Be aware, a context variable is stored and retrieved as VARCHAR(255), so if you need to retrieve an integer, you will need to explicitly cast it.

Instead of 'USER_TRANSACTION', with scope limited to the current transaction, you can also use 'USER_SESSION', with scope limited to the current connection.

Sign up to request clarification or add additional context in comments.

2 Comments

Which version U_T scope was introduced in? I think that 2.1 did not have it. Might be wrong, do not have computer at hands now.
@Arioch'The USER_TRANSACTION has existed since the introduction of this feature in Firebird 2.0, see Firebird 2 release notes, New System Functions to Retrieve Context Variables
1

There is no such thing as "Editor context". Notepad, Word, SynWrite - you can edit anything in them, SQL or not. An editor is just an editor, there is no special context, SQL-wise, in it.

In editor you edit all the SQL texts. DSQL statements, PSQL scripts, everything. Editor does not matter, only difference between DSQL vs PSQL matters here, so read about them in the documentation. Editor has no its own SQL context.


Language-native variables only exist in PSQL context, that is "Procedural" SQL, language used for writing stored procedures, triggers, execute blocks, etc. Also, SQL functions, starting with Firebird 3.

Example from https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-psql.html

CREATE OR ALTER PROCEDURE DEPT_BUDGET (
    DNO CHAR(3))
RETURNS (
    TOT DECIMAL(12,2))
AS
    DECLARE VARIABLE SUMB DECIMAL(12,2);
    DECLARE VARIABLE RDNO CHAR(3);
    DECLARE VARIABLE CNT  INTEGER;
BEGIN
  TOT = 0;

  SELECT
      BUDGET
  FROM
      DEPARTMENT
  WHERE DEPT_NO = :DNO
  INTO :TOT;

  SELECT
      COUNT(BUDGET)
  FROM
      DEPARTMENT
  WHERE HEAD_DEPT = :DNO
  INTO :CNT;

  IF (CNT = 0) THEN
    SUSPEND;

  FOR
      SELECT
          DEPT_NO
      FROM
          DEPARTMENT
      WHERE HEAD_DEPT = :DNO
      INTO :RDNO
  DO
  BEGIN
    EXECUTE PROCEDURE DEPT_BUDGET(:RDNO)
    RETURNING_VALUES :SUMB;
    TOT = TOT + SUMB;
  END

  SUSPEND;
END

Apart from PSQL in Firebird there are more languages ("contexts"): DSQL (Dynamic SQL), ESQL (Embedded SQL) and pre-SQL native query language. Of those only DSQL is of any general use nowadays.

In DSQL you have no language-level variables, but you have functions to set/fetch parts of context: RDB$GET_CONTEXT() and RDB$SET_CONTEXT().

https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-functions-scalarfuncs.html#fblangref25-functions-workcontext

select rdb$set_context('USER_SESSION', 'MyVar', 493) from rdb$database

and later

select rdb$get_context('USER_SESSION', 'MyVar') from rdb$database

You can not change 'USER_SESSION' here, as that is the only context you are allowed to write something, other contexts for reading only. But you are free to change the 2nd parameter as you like - that is the name of textual environment variable you set and retrieve.

UPD. I was wrong, there is one more writable context, 'USER_TRANSACTION', see 2.0.7 Release Notest at https://firebirdsql.org/file/documentation/release_notes/html/rlsnotes207.html#dml-dsql-context-ns

Read docs by the two links above and also read the file situated like

  • c:\Program Files (x86)\Firebird\Firebird_2_1\doc\sql.extensions\README.context_variables2.txt

adjust the path for specific Firebird version on your computer. You can see there full list of contexts (first parameter allowed values) available in your FB version.

However, since you want to use language-native variables, think about, using PSQL instead - see EXECUTE BLOCK in Firebird documentation and my first example. If you do not need to return more than one different datasets from your script, then wrapping it all into one EB for the sake of having variables may suit you better.

3 Comments

@Ana_Souza you can use back-ticks in comment, just like in question itself. When you edit comment - there is a "help" link near edit box, click it and read.
Thx. I mean "SQL Editor context" as where we edit the scripts to run a query. My goal is to find out how to declare a variable in the beggining of the SQL Editor and then reffer it along the page, avoiding mend all the queries developed to analize a specific situation. It works to me in MySQL SET @var_name = 'value'; Select * from table where id = @var_name; I saw the commands rdb$set_context/ rdb$get_context, although it was not clear if is equivalent, and hot may I fill the parameter 'USER_SESSION'. Now@MarkRotteveel fully explained.
I expect (but i did not try to measure) context working a bit slower than native vars, also AFAIR context uses binary string, of CHARACTER SET NONE in most FB versions. This probably would have little consequences for 99,9% of queries, but one better still remember. So all in all, personally, i would still explore PSQL route first, using Execute Block and where possible. Also, for some tasks, GTTs may be of help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.