Use an MS SQL Server function as a column alias - sql

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

Related

How to pass column names in a SQL query as parameters using report builder 3.0

I am using "Microsoft SQL Server Report Builder 3.0" on "SQL Server Reporting Services 2012".
From a main report main.rdl I am calling a drillthrough report detail.rdl
The main.rdl report has a table and each text box of this table is clickable and drillthrough action. When user clicks on any text box the detail.rdl report is called. One parameter that is passed to detail.rdl report is used as a column name in the SQL. This SQL fetches data needed for detail.rdl report
When I run the SQL query for detail.rdl report that is built using parameters, it is not showing any error but doesn't fetch any data either. I think what is happening is that as the parameter has data type Text, it's replaced in SQL with quotes which might be causing it not to fetch any data.
When I run the same SQL directly on DB after replacing the column name with parameter value (without quotes) it does fetch data.
Is there any specific way to pass parameters that will be used as column names that I am missing here?
SQL that I am trying from report builder:
SELECT
table_name.column1
,table_name.column21
,table_name.column15
,table_name.column6
,table_name.column9
,table_name.column2
,table_name.column19
,#column --the value in this variable is an existing column name from table table_name
FROM
table_name
WHERE
table_name.column1 LIKE #company
AND table_name.column21 LIKE #platform
AND (#column is null OR #column = '' OR #column = 'N/A' OR #column = 'Unknown');--I want to use same variable here as well
UPDATE:
I was able to get the SQL working by adding
DECLARE #company varchar(10)
SET #company = ''company_name''
DECLARE #platform varchar(10)
SET #platform = ''platform_name''
after the line
SET #SQL =
'
Unfortunately "Microsoft SQL Server Report Builder 3.0" is not able to execute this SQL as it asks for value of variable #SQL even though it's value is defined. I did try Declaring and setting the value of #SQL in same line as:
DECLARE #SQL varchar(5000) = 'DECLARE #company varchar(10)
But report builder still asks for value of #SQL and report doesn't run :-(
It's hard to tell what the problem is without seeing your code but you can't just swap a string in the SQL like (I think) you are trying to do.
To test your SQL just do something simple in Management Studio like
DECLARE #MyParm varchar(256) = 'myColumnName'
SELECT *, #MyParm FROM myTable
This will return all columns from MyTable, plus a string value of 'myColumnName' as the final column.
If this is what you are trying to do then you'll probably need to change your SQL to use dynamic SQL, something like this.
DECLARE #MyParm varchar(256) = 'myCOlumnName'
DECLARE #SQL varchar(max)
SET #SQL = 'SELECT *, ' + #MyParm + ' FROM myTable'
EXEC (#SQL)
If I've got this completely wrong, please post some sample code so we can see what you are attempting.
EDIT: here is a specific answer based on your sample code
DECLARE #Column sysname = 'Column999'
DECLARE #SQL varchar(max)
SET #SQL =
'SELECT
table_name.column1 ,table_name.column21 ,table_name.column15 ,table_name.column6
,table_name.column9 ,table_name.column2 ,table_name.column19
,' + #column +
' FROM table_name
WHERE table_name.company LIKE #company
AND table_name.platform LIKE #platform
AND (' + #column + ' is null OR ' + #column + ' = '''' OR ' + #column + ' = ''N/A'' OR ' + #column + ' = ''Unknown'')'
-- uncomment below to check SQL statement is correct
--print #sql
-- exec the SQL statement
exec (#sql)
As it stands, this will execute the following sql
SELECT
table_name.column1 ,table_name.column21 ,table_name.column15 ,table_name.column6
,table_name.column9 ,table_name.column2 ,table_name.column19
,Column999 FROM table_name
WHERE table_name.company LIKE #company
AND table_name.platform LIKE #platform
AND (Column999 is null OR Column999 = '' OR Column999 = 'N/A' OR Column999 = 'Unknown')

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 Loop through list of tables to perform alter statement

My SQL is quite limited and I have a number of databases within my server, I'm wondering whether its possible to write an SQL Query to loop through a listing of table names and then alter a particular table within the database name to modify a table in that database ?
Im simply wishing to add a new column to a table called site_settings.
Does MSSQL have this ability ?
You can use the script below. It returns an alter statement for each user table (you need to change your new column type as you didn't specify it) and then executes the query.
declare #sql nvarchar(max) = ''
select #sql = #sql + 'alter table ' + name + ' add site_settings int null;'
from sys.tables where type ='U'
exec sp_executesql #sql

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

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.