Background
Once again, I am working in a very restricted T-SQL environment, an application where one may only define the "body" of a VIEW
: presumably the ...
in
CREATE VIEW My_View AS ...
under the hood. The ...
must be written (as SQL) within its own text field in the application's GUI, which imposes certain inflexibilities described under Note.
Here is my @@VERSION
:
Microsoft SQL Server 2019 (RTM-CU19) (KB5023049) - 15.0.4298.1 (X64)
Jan 27 2023 16:44:09
Copyright (C) 2019 Microsoft Corporation
Web Edition (64-bit) on Linux (Amazon Linux 2) <X64>
Note
The body (...
) is limited to a single SQL statement!
Furthermore, stored PROCEDURE
s are out of play.
Goal
I wish to "simulate" the presence of "local" variables, so certain criteria can be dynamically updated, rather than hardcoded as literals throughout the query. Specifically, I want these "variables" to be at the top, so they can be easily adjusted.
Issue
Unfortunately, variables of the form @x
are unavailable in views.
Approach
I have postulated this approach, with a vars
CTE whose "fields" are the variables. Their values can be accessed as a subquery of the form (SELECT x FROM vars)
:
/*********************
** Variable Scalars **
**********************/
WITH vars AS (SELECT
'Greg' AS c_name, -- A client named "Greg".
GETDATE() AS t_date -- Transactions occurring today.
/**********
** Query **
**********/
) SELECT
*
FROM
Transactions
WHERE
-- |-------- 'Greg' -------|
Client_Name = (SELECT c_name FROM vars) AND
Transaction_Date = (SELECT t_date FROM vars)
-- |--------- Today -------|
I further suggest that variable lists of values can be specified as further CTEs, derived via STRING_SPLIT()
:
/*********************
** Variable Scalars **
**********************/
WITH vars AS (SELECT
'Greg' AS c_name
/******************
** Variable List **
*******************/
), vars_dates AS (SELECT DISTINCT CAST([Value] AS DATE) AS vals FROM STRING_SPLIT('
2023-06-28
2023-06-01
2023-01-01
', Char(10)) WHERE [Value] <> ''
/**********
** Query **
**********/
) SELECT
*
FROM
Transactions
WHERE
-- |----------- 'Greg' ----------|
Client_Name = (SELECT c_name FROM vars ) AND
Transaction_Date IN (SELECT vals FROM vars_dates)
-- |-----------------------------|
-- {1/1/23, 6/1/23, 6/28/23}
Notice now the values in vars_dates
are listed each on a separate line, so the user need not worry about punctuation (commas, etc.) clashing with any delimiter.
Question
So far, I have been able to call (SELECT x FROM vars)
wherever I need the value of x
. Indeed, both vars
and vars_dates
have worked perfectly throughout my use cases.
But are there any situations where these expressions will not work, in place of literal values and lists? More generally, what are the limitations of this approach?