is it Possible to set variable inside a View in Sql Server? - sql

I want to set a variable in Sql Server that is selecting date from a view the query I am using is
declare #var varchar(20)
set #var = (SELECT Current_Period_SID FROM dbo.VW_Current_Period_SID_USNT)
just wondering is there a way to set variable in a view something like
CREATE VIEW mp_test AS
declare #var varchar(20)
set #var = (SELECT Current_Period_SID FROM dbo.VW_Current_Period_SID_USNT)
GO
Doing this gives Error

No. You can't do that in a view. I'm not even sure what the point of the above view would be since it doesn't return any value. Even if you could, you wouldn't want to. A variable like this can only store one varchar(20) value. Without an "order by" and top statement you would either get an error or a non-deterministic value unless your table happens to only have a single record.

You can easily fake a variable in your view using CTE. You can test-run it in your version of SQL Server.
CREATE VIEW vwImportant_Users AS
WITH params AS (
SELECT
varType='%Admin%',
varMinStatus=1)
SELECT status, name
FROM sys.sysusers, params
WHERE status > varMinStatus OR name LIKE varType
SELECT * FROM vwImportant_Users
yielding output:
status name
12 dbo
0 db_accessadmin
0 db_securityadmin
0 db_ddladmin
also via JOIN
WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name
FROM sys.sysusers INNER JOIN params ON 1=1
WHERE status > varMinStatus OR name LIKE varType
also via CROSS APPLY
WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name
FROM sys.sysusers CROSS APPLY params
WHERE status > varMinStatus OR name LIKE varType

Related

Anything like template literals while writing a search query in SQL?

I am writing a stored procedure to get a particular value.
declare #num int
set #num = (SELECT Id
FROM [sometable]
WHERE Name like '%today%')
-- returns #num = 1
Select Value
FROM [anothertable]
where name like 'days1'
In the last line of the query I want to add "1" or any other number after 'days', depending on the variable #num.
How can I do it, sort of like how we use template literals in Javascript, using the ${} syntax but in SQL?
You can just use the first query as a sub-query of the second:
select [Value]
from anothertable
where [name] = Concat('days', (select Id from sometable where [Name] like '%today%'));

BigQuery "KEYS.KEYSET_CHAIN must be a literal or query parameter" when try to create a view

I have a table which some fields are encrypted using Tink which normally worked well with BigQuery's AEAD function (https://cloud.google.com/bigquery/docs/reference/standard-sql/aead_encryption_functions#aeaddecrypt_string)
When I ran a normal query to decrypt data. I can use
DECLARE KMS_RESOURCE_NAME STRING;
DECLARE FIRST_LEVEL_KEYSET BYTES;
SET KMS_RESOURCE_NAME= "<kms-uri>";
SET FIRST_LEVEL_KEYSET = from_base64("<encrypted-keyset>");
select
id,
encrypted_col,
AEAD.DECRYPT_STRING(
KEYS.KEYSET_CHAIN(KMS_RESOURCE_NAME, FIRST_LEVEL_KEYSET),
from_base64(encrypted_col),
"") as decrypted_col
from table
which will output the decrypted data that work fine.
But now I want to create a view on top of this table in which this view will show the decrypted value and view not accept the variable so I hard code into the select statement like this:
create view view_table as
select
id,
encrypted_col,
AEAD.DECRYPT_STRING(
KEYS.KEYSET_CHAIN("<kms-uri>", from_base64("<encrypted-keyset>") ),
from_base64(encrypted_col),
"") as decrypted_col
from table;
which basically hardcode the value from the declared variable into a select statement
But I got this error
Argument 2 to KEYS.KEYSET_CHAIN must be a literal or query parameter
How should I change this query to make it work with view?
Edit:
I also tried to select it first with this as well (a bit weird)
create view view_table as
select
id,
encrypted_col,
AEAD.DECRYPT_STRING(
KEYS.KEYSET_CHAIN("<kms-uri>", (select from_base64("<encrypted-keyset>")) ),
from_base64(encrypted_col),
"") as decrypted_col
from table;
but its also not working. (with the same error)

How to use the EXEC command

I am trying to get a result from a database that will be selected after knowing the country of a user given his email.
I tried using EXEC() but now I get too many results from different users when I clearly indicate that I only want the result from certain user in the 'where' clause.
I first tried making the query with pure inner joins but it failed, it indicated that there was a syntax error, but if i ran it separately without the exec it worked.
After that I decided to use sub-queries, but as I mentioned above, it is returning all of the values, as if it wasn't considering the 'where'
What am I doing wrong?
Here is a sample of the query:
DECLARE #email nvarchar(150) = 'name.lastname#mx.company.com'
--Getting the country code of user
DECLARE #country_code nvarchar(3) = (SELECT country_code FROM general.countries WHERE id_country = (SELECT fk_country FROM databases_access.staff WHERE email = #email))
--Setting user database to search for job title & department
DECLARE #dbname NVARCHAR(25)
SET #dbname = 'dsv_global_' + #country_code
Declare #query nvarchar(500)
-- Query to be run to to get the user department and job title
SET #query =
'
USE '+#dbname+'
SELECT
id_staff,
email,
(SELECT complete_name_dept FROM dsv_global.departments WHERE id_department = fk_department),
(SELECT CONCAT(title,'' '',description) FROM dsv_global.job_titles WHERE id_job_title = (SELECT fk_title FROM dsv_global.staff_information WHERE fk_staff = id_staff)) ,
(SELECT COUNT(fk_staff) FROM dsv_global.staff_managers WHERE fk_manager = fk_staff)
FROM dsv_global.staff
WHERE email = '''+#email+''' AND status = ''ACTIVE''
'
----Storing department & title from user in temp table
--DECLARE #user_info TABLE (id_staff int, email nvarchar(200),complete_name_dept nvarchar(100), title nvarchar(200),num_of_errors int)
--INSERT INTO #user_info
EXEC(#query)
Edit:
I expect to receive:
But I receive:
It's worth to use Common Table Expressions when you deal with complex queries. You can put WITH to define a temporary named result set that available temporarily in the execution scope of a statement. And, by another hand, put GROUP BY for your COUNT function. Also, you need to put id_staff inside the WITH block, it looks like:
WITH cte_titles ( job_title)
AS (
SELECT CONCAT(title,'' '',description)
FROM dsv_global.job_titles
WHERE id_job_title IN
(SELECT fk_title
FROM dsv_global.staff_information
WHERE fk_staff = id_staff)
),
cte_staff (count_staff) AS
(
SELECT COUNT(fk_staff)
FROM dsv_global.staff_managers
WHERE fk_manager = fk_staff
GROUP BY fk_staff
)
SELECT
dsv.id_staff,
dsv.email,
job_title,
count_staff,
FROM dsv_global.staff dsv
cte_staff,
cte_titles
WHERE email = '''+#email+''' AND status = ''ACTIVE''
The problem is that i was not assigning enough space to store the query inside a string :
I had:
Declare #query nvarchar(500)
i changed it to :
Declare #query nvarchar(500)

Replace Any Occurrence of "P" in String With A Value From Another Table

I have a column, sort_order in a table that contains a string of numbers, a delimiter and some P values:
1150||P||1168||1144||1149||1147||1164||1152||P||1148||1162||1163||P||1156||1157||1154||
I would like to replace any P values in this string with another value from the event_tile_id column of another table.
So far I've drafted this SQL below with no luck. What changes can I make to this Query to get the effect I need?
`SELECT sort_order,
(
REPLACE(sort_order,'P',
(SELECT TOP 1 event_tile_id
FROM daily_email_sales_today)
)
)
as sort_order
FROM daily_email_preview`
Removed "default_SaleID" from Query. Replace should now have 4 arguments.
This is how I would do it.
Since you don't have any joins, why not do a simpler update query using a static value?
DECLARE #update VARCHAR(100)
SET #update = (SELECT TOP 1 event_tile_id FROM daily_email_sales_today)
update daily_email_preview
SET sort_order = replace(sort_order,'P', #update)
Or even,
update daily_email_preview
SET sort_order = replace(sort_order,'P', '<new value>')
Assuming you are using SQL Server.
Along the same thought process as #Eric_Hauenstein if you are running this in a TSQL process:
declare #rSTR as varchar(50)
SELECT TOP 1 #rSTR = event_tile_id FROM daily_email_sales_toda
SELECT sort_order, REPLACE(sort_order,'P', #rSTR) as sort_order
FROM daily_email_preview

Set a parameter in select statement

I am trying to set a parameter in the select statement and then pass it to a user defined function in the same statement. Is this possible? If yes, where is my mistake? If no, then I guess I will have to write a cursor and some temporary tables which I want to avoid.
declare #param varchar(1000)
select Pincode, Name,( #param = AlternateName) as AlternateName
,(select Top(1) part from SDF_SplitString (#param,',')) as NewName from PinCodeTable
You can either get all of the fields out as variables, or get the usual set of rows, but you can't mix and match in a single SELECT. Variables are limited to queries that return no more than one row. (Why do I feel like I'm about to learn something frightening?)
If you are writing a stored procedure and doing something like header/trailer rowsets, you can always return a rowset built from variables:
SELECT #Foo = Foo, #Bar = Bar, ... from Headers where Id = 42
SELECT #Foo as Foo -- Return the first rowset.
SELECT Size, Weight, Color from Trailers where Bar = #Bar -- Return second rowset.