How to write an attribute name to the select query dynamically - sql

I have a table including:
ID Name Period0Id Period1Id Period2Id
What I would like to receive data based on a user-defined parameter #check.
Lets assume:
declare #check int = 1;
In this case I need to get Period1Id value from the table. So I need to have something like that:
Select ID, Name, StatusId = Period + #check + Id -- #check is the parameter
From mytable
However, my query is not working. How can I fix this?

Your table looks like it is not in first normal form.
Instead of three columns for Period0Id to Period2Id you could have a column for PeriodIndex with values of (0,1,2) and a single column for PeriodId and then it would be just a WHERE PeriodIndex = #Check
You can't select a column using string interpolation with a variable as you are attempting. You can use dynamic SQL to create the SQL String dynamically. Or simply hardcode the options if they all have the same dataype.
Select ID,
Name,
StatusId = CASE #Check WHEN 0 THEN Period0Id
WHEN 1 THEN Period1Id
WHEN 2 THEN Period2Id
END
From mytable

Here is an alternative way that will create dynamic columns, which is essentially using your original query:
DECLARE #check VARCHAR = 1
DECLARE #sqlquery NVARCHAR(MAX)
SET #sqlquery = N'SELECT ID, Name, StatusId = Period'+#check+'Id
FROM mytable'
EXEC sp_executesql #sqlquery

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%'));

Get multiple variables from table and store them in some variables

For this example, the query and result are:
Query:
select name from sys.parameters where object_id = ##PROCID;
Result:
name
#BKP_TBL
#Filter
I want to store the actual value of #BKP_TBL and #Filter in another variable. Therefore, I am using string_agg to aggregate the result into a single row and store it in new variable as shown below:
DECLARE #PARAMS_DER VARCHAR(MAX);
select #PARAMS_DER = string_agg(name,'+') from sys.parameters where object_id = ##PROCID group by object_id;
The problem is that #PARAMS_DER is storing #BKP_TBL+#Filter instead of their values.

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)

How to assign SQL query result to variable?

I need assign the following SQL Server's query result value to the variable called #value1
SELECT *
FROM customer
WHERE apo_id = '2589';
How can I do this in SQL Server?
1 - First declare your variable of type table.
declare #value1 table(
--YOUR TABLE DEFINITION ex: ValueId int,
)
2 - Insert into your variable
insert into #value1 select * from customer WHERE apo_id = '2589';
Hope that helps, thanks.
It won't really be a variable but a table because you are selecting multiple fields (e.g. Select *) but, you can select INTO a temporary table like this:
SELECT *
INTO #myTempTable
FROM customer
WHERE apo_id = '2589';

Using column variables in my WHERE clause

I have two tables (tableA and tableB) both with a name column. tableA's name column might be called NAME, tableB's column might be called FULLNAME, but they both are supposed to have the same value.
I am to write a query that pulls member id's (from either table) where these two column values are not the same. However, I'd like to pass the column names I'm checking via parameter, as this will be going in an SSRS report and in the future i'd like to be able to use it to compare any other column between these two tables.
Something like this:
DECLARE #COLUMN_A VARCHAR(50), #COLUMN_B VARCHAR(50)
/* COLUMN PARAMS WILL BE PASSED IN VIA SSRS */
SELECT
DISTINCT(MEMBER_ID)
FROM
TABLE_A
JOIN TABLE_B
ON (TABLE_A.MEMBER_ID = TABLE_B.MEMBER_ID)
WHERE
#COLUMN_A <> #COLUMN_B
Is something like this possible?
edit:
Or might something like this work?
DECLARE
#column VARCHAR(50)
SELECT #column = 'FIRST_NAME';
SELECT DISTINCT
MEMBR_ID,
case
when #column='FIRST_NAME' then MEMBR_FIRST_NAME
when #column='LAST_NAME' then MEMBR_LAST_NAME
end TABLE_1,
case
when #column='FIRST_NAME' then FIRSTNAME
when #column='LAST_NAME' then LASTNAME
end TABLE_2,
#column
FROM
TABLE_1
JOIN TABLE_2
ON (TABLE_1.MEMBR_ID = TABLE_2.MEMBR_ID)
WHERE
TABLE_1.#column <> TABLE_2.#column
Is something like this possible?
Technically, the syntax is fine. The where will be comparing two constant strings. The results will be either all rows or no rows, depending on whether the two strings are the same.
Do these evaluate to the columns? No, they do not. You cannot pass parameters into a SQL statement for identifiers -- column names, table names, schema names, database names, function names, or operators (for example).
You can do this using dynamic SQL, but you have to plug the names in:
DECLARE #sql NVARCHAR(MAX);
SET #sql = '
SELECT DISTINCT A.MEMBER_ID
FROM TABLE_A A JOIN
TABLE_B B
ON A.MEMBER_ID = B.MEMBER_ID
WHERE A.#COLUMN_A <> B.#COLUMN_B
';
SET #sql = REPLACE(#sql '#COLUMN_A', COLUMN_A);
SET #sql = REPLACE(#sql '#COLUMN_B', COLUMN_B);
exec sp_executesql #sql;