T-SQL: Variable Scope - sql

I am trying to store the results of an SQL query into a variable.The query simply detects the datatype of a column, hence the returned result is a single varchar.
SET #SQL =
'declare ##x varchar(max) SET ##x = (select DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE Table_name = ' +char(39)+#TabName+char(39) +
' AND column_name = ' +char(39)+#colName+char(39) + ')'
EXECUTE (#SQL)
Anything within the 'SET declaration' cannot access any variables outside of it and vice versa, so I am stuck on how to store the results of this query in a varchar variable to be accessed by other parts of the stored procedure.

You dont need a dynamic query to achieve what you want, below query will give the same result as yours.
declare #x varchar(max)
declare #tableName varchar(100), #ColumnName varchar(50)
set #tableName = 'Employee'
set #ColumnName = 'ID'
select #x = DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
where
Table_Name = #tableName
and column_name = #ColumnName
select #x

All user-defined variables in T-SQL have private local-scope only. They cannot be seen by any other execution context, not even nested ones (unlike #temp tables, which can be seen by nested scopes). Using "##" to try to trick it into making a global-variable doesn't work.
If you want to execute dynamic SQL and return information there are several ways to do it:
Use sp_ExecuteSQL and make one of the parameters an OUTPUT parameter (recommended for single values).
Make a #Temp table before calling the dynamic SQL and then have the Dynamic SQL write to the same #Temp table (recommended for multiple values/rows).
Use the INSERT..EXEC statement to execute your dynamic SQL which returns its information as the output of a SELECT statement. If the INSERT table has the same format as the dynamic SQL's SELECT output, then the data output will be inserted into your table.
If you want to return only an integer value, you can do this through the RETURN statement in dynamic SQL, and receive it via #val = EXEC('...').
Use the Session context-info buffer (not recommended).
However, as others have pointed out, you shouldn't actually need dynamic SQL for what you are showing us here. You can do just this with:
SET #x = ( SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE Table_name = #TabName
AND column_name = #colName )

You may want to consider using the sp_executesql stored procedure for dynamic sql.
The following link provides a good usage example of sp_executesql procedure with output parameters:
http://support.microsoft.com/kb/262499

Related

query inside the variable

Is it possible in SQL to use a variable to store query.
For example to save time when subquery is used multiple times inside the main query.
Example:
DECLARE #my_query as varchar(250) = select x from my_table where my_table = y.your_table
SELECT
a,b,c,(#my_query),d,e,f
FROM my_table_1
Is it possible in SQL to use a variable to store query.
Depend on your definition of "query". If you mean store the text which we use to execute the command, then the answer is YES. If you mean an object type query, then the answer is not - since there is no data type that fit this.
What I mean is that a variable can store a value which is string. The string can be any query command that you want. Therefore, you can store for example the text "select col1,col2 from table1".
Next you need to ask how can we use this text in order to execute it as part of a query, which is done using dynamic query.
We can execute a text of a query using the build-in stored procedure sp_executesql, which is build for such needs.
For example:
-- DECLARE VARIABLE
DECLARE #MyQuery NVARCHAR(MAX)
-- SET the value of the variable
SET #MyQuery = 'SELECT ''Yes I can'''
-- Executing a dynamic query
EXECUTE sp_executesql #MyQuery
Here is another example which look more close to your question:
-- First let's create a table
CREATE TABLE T(ID INT)
INSERT T(ID) VALUES (1),(2)
GO
-- And here is what you sked about:
-- DECLARE VARIABLE
DECLARE #MyQuery NVARCHAR(MAX)
-- SET the value of the variable
SET #MyQuery = 'select ID from T where ID = ''1'''
-- Let's combine the text to a full query now
DECLARE #FullQuery NVARCHAR(MAX)
SET #FullQuery = '
SELECT
ID,(' + #MyQuery + ')
FROM T
'
PRINT #FullQuery
-- Executing a dynamic query
EXECUTE sp_executesql #FullQuery
NOTE! Your specific sample of query will return error, which is not related to the question "Is it possible in SQL to use a variable to store query". This is a result of the "query" is not well formatted.
Important! It is HIGHLY recommended to read the document about this stored procedure and learn a bit more of the options it provides us.
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-ver15

how to add custom column in SQL string query with variable

I am using string query in sql and executing it with Execute method. I have to add an additional column with default value. that default value is contained in a variable. When i add that default valued column in the query string and execute it I get an error "Invalid column name 'dafaultValue' ".
Is there any other solution to do this ?
Here is my code:
Declare #variable Varchar(Max);
Declare #variableQuery Varchar(Max);
set #variable = 'Test';
set #variableQuery = 'select '+#variable+' as dest ,* from myTable ';
execute (#variableQuery);
Your issue is that you need to contain the variable in single quotes:
set #variableQuery = 'select '+ ''''+#variable+'''' +' as dest ,* from myTable';
Otherwise it thinks it is a column name in the table, which it isn't, hence the error.
I would strongly encourage you to learn to use sp_executesql and pass in parameters. This is much safer than munging query strings:
Declare #variable Varchar(Max);
Declare #variableQuery Varchar(Max);
set #variable = 'Test';
set #variableQuery = 'select #variable as dest, t.* from myTable t';
exec sp_executesql #variableQuery,
N'#variable varchar(max)',
#variable = #variable;
This method also allows you to pass values back from the query, so for processing queries, it is more powerful than exec.
The query variable would often be declared to be nvarchar(), just to be as general as possible.

Using a variable to name query results column

Is there a way to use a variable to name a column in SQL query results? My example below gives an "Incorrect syntax" error?
declare #ColumnName varchar(100) = 'Column 1'
Select CustomerNumber as #ColumnName
from Customers
Generally, SQL isn't going to handle defining variables to use as column aliases. This means you'll likely have to resort to using dynamic SQL, which involves building your query and then executing it manually via the sp_executesql procedure.
The following is an example of your existing query executed dynamically using SQL Server :
-- Define your variable
DECLARE #ColumnName VARCHAR(100) = 'Column 1'
-- Define your SQL query
DECLARE #SQL NVARCHAR(200) = 'SELECT CustomerNumber AS ' + #ColumnName + ' FROM Customers'
-- Execute your query dynamically
EXEC sp_executesql #SQL

MSSQL: given a table's object_id, determine whether it is empty

For a bit of database-sanity checking code, I'd like to determine whether a particular object_id corresponds to an empty table.
Is there some way to (for instance) select count(*) from magic_operator(my_object_id) or similar?
I'd strongly prefer a pure-sql solution that can run on MS SQL server 2008b.
You can get a rough idea from
SELECT SUM(rows)
FROM sys.partitions p
WHERE index_id < 2 and p.object_id=#my_object_id
If you want guaranteed accuracy you would need to construct and execute a dynamic SQL string containing the two part object name. Example below though depending on how you are using this you may prefer to use sp_executesql and return the result as an output parameter instead.
DECLARE #DynSQL nvarchar(max) =
N'SELECT CASE WHEN EXISTS(SELECT * FROM ' +
QUOTENAME(OBJECT_SCHEMA_NAME(#my_object_id)) + '.' +
QUOTENAME(OBJECT_NAME(#my_object_id)) +
') THEN 0 ELSE 1 END AS IsEmpty'
EXECUTE (#DynSQL)
Well it depends on what do you consider as Pure sql
I've come up with the following solution. It is purely written in T-SQL but uses dynamically built query
-- Using variables just for better readability.
DECLARE #Name NVARCHAR(4000)
DECLARE #Schema NVARCHAR(4000)
DECLARE #Query NVARCHAR(4000)
-- Get the relevant data
SET #Schema = QUOTENAME(OBJECT_SCHEMA_NAME(613577224))
SET #Name = QUOTENAME(OBJECT_NAME(613577224))
-- Build query taking into consideration the schema and possible poor object naming
SET #Query = 'SELECT COUNT(*) FROM ' + #Schema + '.' + #Name + ''
-- execute it.
EXEC(#Query)
EDIT
The changes consider the possible faulty cases described in the comments.
I've outlined the variables, because this is a convenient approach for me. Cheers.

SQL: Select dynamic column name based on variable

I have a Microsoft SQL stored procedure whose column name I want to set via a variable that is passed into it:
CREATE PROCEDURE [My_Procedure]
#myDynamicColumn varchar(50)
AS BEGIN
SELECT 'value' AS #myDynamicColumn
END
This does not work ("Incorrect syntax"). If I wrap the column name with [ ]:
SELECT 'value' AS [#myDynamicColumn]
The column name literally outputs as '#myDynamicColumn' instead of the actual value. Is there any way to do this? I've looked into dynamic SQL articles but nothing is quite what I'm asking for.
EXEC ('SELECT ''value'' AS ' + #myDynamicColumn)
You could build your query into a string and use exec
CREATE PROCEDURE [My_Procedure]
#myDynamicColumn varchar(50)
AS BEGIN
EXEC('SELECT ''value'' AS ' + #myDynamicColumn)
END
Both the upvoted answers are very dangerous here, both are wide open to injection attacks and should not be used.
When injecting dynamic object names you must ensure you properly quote your object names. SQL Server has a built in function for that, QUOTENAME. Thus what you should actually be doing is the following:
CREATE PROCEDURE [My_Procedure] #myDynamicColumn sysname
AS BEGIN
DECLARE #SQL nvarchar(MAX) = N'SELECT ''value'' AS ' + QUOTENAME(#myDynamicColumn) + N';';
EXEC sys.sp_executesql #SQL;
END
You'll note I also change the data type of the parameter to sysname, a synonym for nvarchar(128) NOT NULL, which is the data type SQL Server uses internally for object names.