Using a variable to name query results column - sql

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

Related

Scalar variable must be declared in SQL variable

I'm creating a report using sql scripts through management studio and I'm getting the error " Must Declare the scalar variable "#Account". I've been reading other similar questions on this portal but they are related to c#
I'm currently trying to reduce the code on the script so I decided to put a sql script into a variable because depending on a condition the where condition will change. Below is an example of the code
Declare #Account int = 1 , #SQL varchar(max)=''
Select #SQL = N'Select ColumnA,ColumnB, ColumnC from Table1 where ColumnA =1'
if #Account IS NULL
Begin
exec(#SQL)
end
--Here is where the error is hapening
else
begin
--This is the line causing the error
Select #SQL = #SQL + 'AND ColumnB=#Account"
exec(#SQL)
end
If I type manually the value of the variable next to "ColumnB=" it works but the account number will be selected by the user executing the script. I'm thinking on maybe building a temp table to capture the variable value and then do a sub query on the where condition but maybe the solution to this error may be more easier
You want sp_executesql:
select #SQL = #SQL + 'AND ColumnB=#Account';
exec sp_executesql #SQL, N'#Account int', #Account=#Account;
This is how you pass parameters into a dynamic SQL statement in SQL Server. I strongly recommend that you only use sp_executesql to execute SQL statements -- even when you don't have parameters. Using it makes it easy to implement parameters when you need them.
You are passing in '#Account' into the #SQL variable -- the underlying EXEC cannot see that variable.
One way of fixing this would instead be to do this:
Select #SQL = #SQL + 'AND ColumnB=' + CAST(#Account as varchar)

T-SQL: Variable Scope

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

Use an MS SQL Server function as a column alias

I've created a function for retrieving the translations of database columns in MS SQL Server 2005, depending on the selected language code (e.g. 'el-GR'). The function itself works correctly, but I am unable to use its result as the Alias for the retrieved columns.
This is the code I'm using:
SELECT
tblAuditors.[Full Name] as dbo.GetLocalizedGridTranslation('Auditor Name', #languageCode)
FROM tblCompanyAuditors
Does anyone know how I can trick the SQL Server into allowing me to use the function as an Alias name?
Wrap the alias in brackets []:
SELECT
[dbo.GetLocalizedGridTranslation('Auditor Name', #languageCode)] = tblAuditors.[Full Name]
FROM tblAuditors
Apart from that, is it a typo that you've queried a table tblCompanyAuditors but the column is from table tblAuditors?
Edit: I've only just noticed that the column alias itself should be the result of a function.
Does that make sense? An alias is a column for all records, and a function will be executed on every record. If that's a stored-procedure i would recommend to store the result in a variable and use that as column alias in dynamic sql.
DECLARE #column_alias VARCHAR(30)
SET #column_alias = dbo.GetLocalizedGridTranslation('Auditor Name', #languageCode);
-- Use dynamic SQL
DECLARE #sql VARCHAR(1000)
SET #sql = 'SELECT tblAuditors.[Full Name] AS ' + #column_alias + ' FROM tblAuditors'
EXEC sp_executesql #sql
I think you're going to need to use dynamic SQL
ie
declare #sql nvarchar(max)
select #sql = 'SELECT tblAuditors.[Full Name] as ['
+ dbo.GetLocalizedGridTranslation('Auditor Name', #languageCode)
+ '] FROM tblCompanyAuditors'
exec sp_executesql #sql

How can I get tables name from sys.tables and store the output in a variable?

I have written a stored procedure where a table name and database name collect
using cursor from different two tables.
But my problem is when I run a query to find out a table exists in a database or not, then show a error.
Now how can I run the query and store output into a variable?
Declare #table_exist nvarchar(200),#val1 nvarchar(200),#return1 nvarchar(200);
SET #table_exist=
'SELECT 1 FROM '+#db_name+'.sys.tables
where name='+#table_name+'';
EXEC sp_executesql #table_exist,#return1 OUTPUT;
select #return1;
ERROR:
Invalid column name 'table name'
You should use quotename when building dynamic query:
SET #table_exist=
'SELECT 1 FROM '+ quotename(#db_name)+'.sys.tables
where name='+quotename(#table_name)+'';
When facing such an error the best would be to print #table_exists and see what is actually built.
I haven't looked properly at your query. You are missing apostrophes:
SET #table_exist=
'SELECT 1 FROM '+ quotename(#db_name)+'.sys.tables
where name=''' + #table_name +'''';
UPDATE:
When using output variable you should set it in a query:
SET #table_exist=
'SELECT #return1 = 1 FROM ' + quotename(#db_name) + '.sys.tables
where name='''+#table_name+'''';
To prevent result set from returning to client, create temporary table and insert result set into it. In this case this will leave only one result set, the result of select #return1:
declare #tbl table (exist bit)
insert into #tbl
EXEC sp_executesql #table_exist, N'#return1 nvarchar(200) out', #return1 OUT;
select #return1;
It is best to write your query by using ' and " properly . Which makes less mistakes while writing query.
The error on you code is that you are confused by using only '. Best to use ' for variable only.
Write your code as:
"SELECT 1 FROM ' "+#db_name+" '.sys.tables
where name=' "+#table_name+" ' ";

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.