How to select alias name from a table in sql server? - sql-server

I have a language table and I want to select aliases from that table according to the specified language.
ALTER PROCEDURE sp_executesql
(#parameter1 NVARCHAR(MAX)
,#parameter2 NVARCHAR(MAX)
,#code NVARCHAR(MAX),#language NVARCHAR(MAX))
DECLARE #sql NVARCHAR(MAX)
SET #sql = 'SELECT '+#parameter1+' AS (SELECT #language FROM Languages WHERE code=somecolumn) '+#paramter2+' AS (SELECT #language FROM Languages WHERE code='+#code+') FROM mytable'
EDIT:
in Stored Procedure, I need something like that.
Thanks for answers..

You cannot use a subquery to build an alias in that way, you would need to use dynamic sql to do this.
DECLARE #language NVARCHAR(255) -- or whatever type your field is
SELECT #language=language FROM Languages WHERE code=#code
DECLARE #sql NVARCHAR(MAX) = 'SELECT ' + #parameter1 + ' AS ' + QUOTENAME(#language) + ' FROM MyTable'
EXEC sp_executesql #sql
(Note the inclusion of QUOTENAME around the alias - this is a safety feature in case of your alias names having invalid characters.)
You can repeat the code above for the second parameter inside your stored procedure.

Try this:
CREATE PROCEDURE sp_NameOfSP
(#parameter1 NVARCHAR(MAX)
,#parameter2 NVARCHAR(MAX)
,#code NVARCHAR(MAX)
,#language NVARCHAR(MAX))
AS
BEGIN
DECLARE #sql NVARCHAR(MAX)
SELECT TOP(1) #language=LanguageColumn FROM Languages WHERE code=somecolumn
SET #sql = 'SELECT '+#parameter1+' AS '+#language+', '
SELECT TOP(1) #language=LanguageColumn FROM Languages WHERE code=#code
SET #sql=#sql+#paramter2+' AS '+#language+' FROM mytable'
EXEC(#SQL)
END
Replace LanguageColumn with proper column name from Languages table

Related

Table name placeholder - TSQL

Is there a way to do something like this? People is the name of the table.
declare #placeholder varchar(20) = 'People'
select * from #placeholder
Or something like this where the table name is People_Backup.
declare #placeholder varchar(20) = '_Backup'
select * from People#placeholder
And is there a way to add in dynamic sql the value of a variable?
something like this:
declare #placeholder nvarchar(20) = 'people'
declare #name nvarchar(30) = 'antony'
declare #query nvarchar(1000) = 'select * from ' + #placeholder + ' where
first_name=' + #name
exec sp_executesql #query
I mean: without do this
exec sp_executesql #query, N'#name varchar(30)', #name
Thank you for the answers.
Not without dynamic SQL.
Parameters in SQL are placeholders for data, and can't be used as placeholders for anything else (which includes commands such as select, update etc' and identifiers such as database name, schema name, table name, column name etc').
The only way to parameterize table names is to use dynamic SQL - meaning you must build a string containing the SQL you want to execute, and then execute it.
Beware - dynamic SQL might be an open door for SQL injection attacks - so you must do it wisely - here are some ground rules:
Always white-list your identifiers (using system tables or views such as sys.Tables or Information_schema.Columns)
Always use sysname as the datatype for identifiers.
The sysname data type is used for table columns, variables, and stored procedure parameters that store object names. The exact definition of sysname is related to the rules for identifiers. Therefore, it can vary between instances of SQL Server.
Never pass SQL commands or clauses in parameters - set #placeholder = 'select a, b, c' or set #placeholder = 'where x = y' is a security hazard!
Always use parameters for data. Never concatenate parameters into your sql string: set #sql = 'select * from table where x = '+ #x is a security hazard. Always create your dynamic SQL to use parameters as parameters: set #sql = 'select * from table where x = #x'
Always use sp_executeSql to execute your dynamic SQL statement, not EXEC(#SQL).
For more information, read Kimberly Tripp's EXEC and sp_executesql – how are they different?
Always wrap identifiers with QUOTENAME() to ensure correct query even when identifiers include chars like white-spaces
To recap - a safe version of what you are asking for (with an additional dynamic where clause to illustrate the other points) is something like this:
#DECLARE #TableName sysname = 'People',
#ColumnName sysname = 'FirstName'
#Search varchar(10) = 'Zohar';
IF EXISTS(
SELECT 1
FROM Information_Schema.Columns
WHERE TABLE_NAME = #TableName
AND COLUMN_NAME = #ColumnName
)
BEGIN
DECLARE #Sql nvarchar(4000) =
'SELECT * FROM +' QUOTENAME(#TableName) +' WHERE '+ QUOTENAME(#ColumnName) +' LIKE ''%''+ #Search +''%'';'
EXEC sp_executesql #Sql, N'#Search varchar(10)', #Search
END
-- you might want to raise an error if not
To answer your question after edited directly:
I mean: without do this exec sp_executesql #query, N'#name varchar(30)', #name
Yes, you can do it without using sp_executeSql, but it's dangerous - it will enable an attacker to use something like '';DROP TABLE People;-- as the value of #name, so that when you execute the sql, your People table will be dropped.
To do that, you will need to wrap the #name with ' -
declare #placeholder nvarchar(20) = 'people'
declare #name nvarchar(30) = 'antony'
declare #query nvarchar(1000) = 'select * from ' + QUOTENAME(#placeholder) + ' where
first_name=''' + #name +''''
exec(#query)
I mean: without do this exec sp_executesql #query, N'#name varchar(30)', #name
Yes, you can do that as
--Use MAX instead of 1000
DECLARE #SQL nvarchar(MAX) = N'SELECT * FROM ' + #placeholder + ' WHERE first_name = '''+#name +'''';
EXECUTE sp_executesql #SQL;

How to use variable as table name in select into statement?

I have a problem with treating table name as variable as I need to put the results to different table each month automatically (without using any advanced procedures to make this query dynamic). Can somebody help me to modify this code and make it work?
declare #exp_dte as date;
set #exp_dte='2015-12-31';
print (#exp_dte);
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
print (#tab_mth);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
print (#tab_name);
IF OBJECT_ID (N'#tab_name', N'U') IS NOT NULL
begin
drop table #tab_name
end
select distinct
*
into #tab_name
from table_x
You have to use dynamic SQL to set name at runtime:
DECLARE #exp_dte DATE = '2015-12-31';
DECLARE #tab_name SYSNAME = '[dbo].' + QUOTENAME('BIK_' + FORMAT(#exp_dte, 'yyyyMM'));
IF OBJECT_ID (#tab_name, N'U') IS NOT NULL
BEGIN
EXEC('DROP TABLE' + #tab_name);
END
DECLARE #sql NVARCHAR(MAX) = N'SELECT DISTINCT *
INTO #tab_name
FROM table_x';
SET #sql = REPLACE(#sql, '#tab_name', #tab_name);
EXEC [dbo].[sp_executesql] #sql;
LiveDemo
Remarks:
Try to be more conscise
You could use FORMAT to get yyyyMM (SQL Server 2012+)
Always QUOTENAME generated identifiers to avoid SQL Injection attacks
I strongly recommend to read The Curse and Blessings of Dynamic SQL especially CREATE TABLE #tbl.
use dynamic sql ,you cant user table names as variables
declare #exp_dte as date;
set #exp_dte='2015-12-31';
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
declare #sql1 nvarchar(max)
set #sql1='drop table '+#tab_name;
IF exists(select 1 from information_schema.tables where table_name=#tab_name)
begin
exec(#sql1);
end
declare #sql nvarchar(max)
set #sql='
select distinct
*
into '+#tab_name+'
from table_x'
exec (#sql)

Column name not working when placed inside a variable in SQL Server [duplicate]

create procedure sp_First
#columnname varchar
AS
begin
select #columnname from Table_1
end
exec sp_First 'sname'
My requirement is to pass column names as input parameters.
I tried like that but it gave wrong output.
So Help me
You can do this in a couple of ways.
One, is to build up the query yourself and execute it.
SET #sql = 'SELECT ' + #columnName + ' FROM yourTable'
sp_executesql #sql
If you opt for that method, be very certain to santise your input. Even if you know your application will only give 'real' column names, what if some-one finds a crack in your security and is able to execute the SP directly? Then they can execute just about anything they like. With dynamic SQL, always, always, validate the parameters.
Alternatively, you can write a CASE statement...
SELECT
CASE #columnName
WHEN 'Col1' THEN Col1
WHEN 'Col2' THEN Col2
ELSE NULL
END as selectedColumn
FROM
yourTable
This is a bit more long winded, but a whole lot more secure.
No. That would just select the parameter value. You would need to use dynamic sql.
In your procedure you would have the following:
DECLARE #sql nvarchar(max) = 'SELECT ' + #columnname + ' FROM Table_1';
exec sp_executesql #sql, N''
Try using dynamic SQL:
create procedure sp_First #columnname varchar
AS
begin
declare #sql nvarchar(4000);
set #sql='select ['+#columnname+'] from Table_1';
exec sp_executesql #sql
end
go
exec sp_First 'sname'
go
This is not possible. Either use dynamic SQL (dangerous) or a gigantic case expression (slow).
Create PROCEDURE USP_S_NameAvilability
(#Value VARCHAR(50)=null,
#TableName VARCHAR(50)=null,
#ColumnName VARCHAR(50)=null)
AS
BEGIN
DECLARE #cmd AS NVARCHAR(max)
SET #Value = ''''+#Value+ ''''
SET #cmd = N'SELECT * FROM ' + #TableName + ' WHERE ' + #ColumnName + ' = ' + #Value
EXEC(#cmd)
END
As i have tried one the answer, it is getting executed successfully but while running its not giving correct output, the above works well
You can pass the column name but you cannot use it in a sql statemnt like
Select #Columnname From Table
One could build a dynamic sql string and execute it like EXEC (#SQL)
For more information see this answer on dynamic sql.
Dynamic SQL Pros and Cons
As mentioned by MatBailie
This is much more safe since it is not a dynamic query and ther are lesser chances of sql injection . I Added one situation where you even want the where clause to be dynamic . XX YY are Columns names
CREATE PROCEDURE [dbo].[DASH_getTP_under_TP]
(
#fromColumnName varchar(10) ,
#toColumnName varchar(10) ,
#ID varchar(10)
)
as
begin
-- this is the column required for where clause
declare #colname varchar(50)
set #colname=case #fromUserType
when 'XX' then 'XX'
when 'YY' then 'YY'
end
select SelectedColumnId from (
select
case #toColumnName
when 'XX' then tablename.XX
when 'YY' then tablename.YY
end as SelectedColumnId,
From tablename
where
(case #fromUserType
when 'XX' then XX
when 'YY' then YY
end)= ISNULL(#ID , #colname)
) as tbl1 group by SelectedColumnId
end
First Run;
CREATE PROCEDURE sp_First #columnname NVARCHAR(128)--128 = SQL Server Maximum Column Name Length
AS
BEGIN
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT ' + #columnname + ' FROM Table_1'
EXEC(#query)
END
Second Run;
EXEC sp_First 'COLUMN_Name'
Please Try with this.
I hope it will work for you.
Create Procedure Test
(
#Table VARCHAR(500),
#Column VARCHAR(100),
#Value VARCHAR(300)
)
AS
BEGIN
DECLARE #sql nvarchar(1000)
SET #sql = 'SELECT * FROM ' + #Table + ' WHERE ' + #Column + ' = ' + #Value
--SELECT #sql
exec (#sql)
END
-----execution----
/** Exec Test Products,IsDeposit,1 **/

SQL, Assign Select Column to Variable

I am using SQL Server 2012, I am going to Create Store Procedure which copies a column from a table in a variable, Could any one please tell me what is Wrong with this code?
alter Procedure Id_Fetch
#Col varchar(50)=null,
#Table VARCHAR(50)=Null,
#OrdrBy Varchar(40)=null
as
Begin
declare #TempCol nvarchar (100)
Exec(' SELECT '+#TempCol+' = '+#Col+' from ' + #Table +' order by '+#OrdrBy )
its showing error "Incorrect Syntax near '='
A little modification ...... Use TOP 1 in your select as if more than one value is returned by your select it will throw an error.
Use SYSNAME datatype for your Column names and table names.
Use QUOTENAME() function around your object name parameters, which puts square brackets [] around the passed parameter value and forces it to be treated as an object name (Protection against Sql Injection attack).
Use sp_executesql instead of EXEC and concatenating parameter values into string and executing again protects you against Sql Injection attack.
ALTER PROCEDURE Id_Fetch
#Col SYSNAME,
#Table SYSNAME,
#OrdrBy SYSNAME,
#Col_Value NVARCHAR(100) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sql NVARCHAR(MAX);
SET #Sql = N' SELECT TOP 1 #Col_Value = ' + QUOTENAME(#Col)
+ N' FROM ' + QUOTENAME(#Table)
+ N' ORDER BY ' + QUOTENAME(#OrdrBy)
EXECUTE sp_executesql #Sql
,N'#Col_Value NVARCHAR(100) OUTPUT'
,#Col_Value OUTPUT
END

Variable table name in select statement

I have some tables for storing different file information, like thumbs, images, datasheets, ...
I'm writing a stored procedure to retrieve filename of a specific ID. something like:
CREATE PROCEDURE get_file_name(
#id int,
#table nvarchar(50)
)as
if #table='images'
select [filename] from images
where id = #id
if #table='icons'
select [filename] from icons
where id = #id
....
How can I rewrite this procedure using case when statement or should I just use table name as variable?
You can't use case .. when to switch between a table in the FROM clause (like you can in a conditional ORDER BY). i.e. so the following:
select * from
case when 1=1
then t1
else t2
end;
won't work.
So you'll need to use dynamic SQL. It's best to parameterize the query as far as possible, for example the #id value can be parameterized:
-- Validate #table is E ['images', 'icons', ... other valid names here]
DECLARE #sql NVARCHAR(MAX)
SET #sql = 'select [filename] from **TABLE** where id = #id';
SET #sql = REPLACE(#sql, '**TABLE**', #table);
sp_executesql #sql, N'#id INT', #id = #id;
As with all dynamic Sql, note that unparameterized values which are substituted into the query (like #table), make the query vulnerable to Sql Injection attacks. As a result, I would suggest that you ensure that #table comes from a trusted source, or better still, the value of #table is compared to a white list of permissable tables prior to execution of the query.
Just build SQL string in another variable and EXECUTE it
DECLARE #sql AS NCHAR(500)
SET #sql=
'SELECT [filename] '+
' FROM '+#table+
' WHERE id = #id'
EXECUTE(#sql)
CREATE PROCEDURE get_file_name(
#id int,
#table nvarchar(50)
)as
DECLARE #SQL nvarchar(max);
SET #SQL = 'select [filename] from ' + #table + ' where id = ' + #id
EXECUTE (#SQL)

Resources