sql dates as column name - sql

I want a table with columns named after dates.
example:
SELECT * AS GETDATE() FROM mytable;
From what I've read on the internet, it looks as though I will need to use dynamic SQL (?) something in the lines of this:
DECLARE #dt smalldatetime
SET #dt = GETDATE()
DECLARE #str varchar(100)
SET #str = 'SELECT * AS ' + convert(varchar(100), GETDATE(), 120) + ' FROM mytable'
EXEC(#str);
But this doesn't work. says "incorrect syntax near the keyword 'AS'

All I had to do was change from SELECT * to SELECT [the thing i needed]
DECLARE #dt smalldatetime
SET #dt = GETDATE()
DECLARE #str varchar(100)
SET #str = 'SELECT Item AS ' + convert(varchar(100), GETDATE(), 120) + ' FROM mytable'
EXEC(#str);
this works.

Try this:
DECLARE #dt smalldatetime
SET #dt = GETDATE()
DECLARE #str varchar(100)
SET #str = 'SELECT Item AS '+'''' + convert(varchar(100), GETDATE(), 120) +'''' + ' FROM mytable'
EXEC(#str);

Related

Dynamic query based on datetime parameter

I have a SQL Server database with date representation name like below & each database contains table A (table A having column like id, datetime, value, value1 etc).
Jan2018
Feb2018
Mar2018 and so on..
My search condition is user selected date (eg. from 01-Jan-2018 to 01-Jun-2018) which I am passing to a stored procedure (max range 6 month). I want to generate dynamic query to get data from these database based on datetime passed.
How to achieve this functionality as I found difficult to implement.
Can you try this query
CREATE PROCEDURE Myproc #FromDate DATE,
#ToDate DATE
AS
BEGIN
DECLARE #SQL NVARCHAR(max)='',
#unionall VARCHAR(10)=''
WITH cte
AS (SELECT #FromDate dt,
1 mont
UNION ALL
SELECT Dateadd(month, 1, dt) dt,
mont + 1 mont
FROM cte
WHERE mont < Datediff(month, #FromDate, #ToDate)
)
SELECT #SQL += #unionall + '
select * from ['
+ LEFT (CONVERT(VARCHAR, Datename (month, dt )), 3)
+ CONVERT (VARCHAR, Year (dt))
+ '].[dbo].[tablename]',
#unionall = ' union all '
FROM cte
PRINT #SQL
EXECUTE( #SQL)
END
You should query sys.databases to find a database you need.
Then, as you can only use static declarations of databases, you should create a textual select statement and execute it.
I tried it on my dbs and it worked.
This is my code:
declare #date varchar(20) = '2018'
declare #dbName varchar(20)
declare #sSql varchar(200)
declare #sConditions varchar(20) = ''
Set #dbName = (SELECT name FROM master.sys.databases
where name like '%' + #date + '%')
print #dbName
Select #sSql = 'Select * From ' + #dbName + '.dbo.MyDB '
--+ ' Where ' + #sConditions
Execute (#sSql)
if you need to query all that fit year. do like this:
declare #date varchar(20) = 'a'
SELECT name Into #dbnames
FROM master.sys.databases
where name like '%' + #date + '%'
this brings a table of all sutable dbs. then query each one of them using loop. like cursor
Are you looking for
CREATE PROCEDURE MyProc
#FromDate DATE,
#ToDate DATE,
#Target SysName
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX)= N'SELECT * FROM [' +
#Target +
'] WHERE [Dates] >= #FromDate AND [Dates] <= #ToDate';
EXECUTE sp_executesql #SQL,
N'#FromDate DATE, #ToDate DATE',
#FromDate,
#ToDate;
END
Demo
As I now understand what you are trying to do, you can
CREATE PROCEDURE ProcName
#FromDate DATE,
#ToDate DATE
AS
BEGIN
--Declare a variable to hold the Dynamic SQL
DECLARE #SQL NVARCHAR(MAX) = N'';
--Generate the databases names
WITH CTE AS
(
SELECT #FromDate D,
1 N
UNION ALL
SELECT DATEADD(Month, N, #FromDate),
N + 1
FROM CTE
WHERE N <= DATEDIFF(Month, #FromDate, #ToDate)
)
--Build the SELECT statement
SELECT #SQL = #SQL+
N'SELECT * FROM ['+
CONVERT(VARCHAR(3), D, 100)+
CAST(YEAR(D) AS VARCHAR(4))+
'].dbo.TableName UNION ALL ' --Or UNION as you want
FROM CTE;
--Remove the last UNION ALL
SET #SQL = LEFT(#SQL, LEN(#SQL) - 10); --If UNION then just -6
--Execute the statement
EXECUTE sp_executesql #SQL;
END

Comma seperated values to SQL IN STATEMENT

If i have a comma separated list of values:
A1,B2,B3
How do i pass this into a variable and then form it into an SQL IN statement.
DECLARE #DATE AS VARCHAR(50)
SELECT #DATE = CONVERT(VARCHAR(8), Getdate(), 112)
--PRINT #DATE
DECLARE #TIME AS VARCHAR(50)
--PRINT TIME
SELECT #TIME = Replace(CONVERT(VARCHAR(5), Getdate(), 108), ':', '')
DECLARE #ID AS VARCHAR(50)
SELECT #ID = Replace(W0128001, 32322, 32323, 3232323, 2323232, ',', ',')
--PRINT #ID
DECLARE #QUERY NVARCHAR(MAX);
SET #QUERY = 'SELECT * INTO BACKUPTABLE_' + #DATE + #TIME
+ '
FROM TABLE
WHERE ID IN (' + '''' + #ID + ''')'
--EXEC #query
PRINT #QUERY
I have tried to do a replace above but i want it so that an end user can PASTE into the values and my script will take care of the commas and properly form it. It should also strip out the last commas from the end.
My output needs to read:
SELECT * INTO BACKUPTABLE_201606061503
FROM TABLE
WHERE ID IN ('W0128001','32322','32323','3232323','2323232')
For one thing, you don't surround it with single quotes:
SET #QUERY = 'SELECT * INTO BACKUPTABLE_' + #DATE + #TIME + '
FROM TABLE
WHERE ID IN (' + #ID + ')';
There are other ways to pass comma-delimited values to a SQL statement, including using a split() function or XML.
CREATE PROCEDURE [dbo].[CreateBackupTable]
#ID varchar(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #DATE VARCHAR(50)= CONVERT(VARCHAR(8), Getdate(), 112);
DECLARE #TIME VARCHAR(50) = Replace(CONVERT(VARCHAR(5), Getdate(), 108), ':', '')
declare #xml xml,#SQL NVARCHAR(MAX);
set #xml = N'<root><r>' + replace(#ID,',','</r><r>') + '</r></root>'
SET #SQL = N' SELECT * INTO ' + QUOTENAME('BACKUPTABLE_' + #DATE + #TIME)
+ N' from TableName '
+ N' where ID IN (
select r.value(''.'',''varchar(max)'') as item
from #xml.nodes(''//root/r'') as records(r)
)'
exec sp_executesql #sql
, N'#ID varchar(100), #xml XML'
, #ID
, #Xml
END

concatenate datetime with string

i am getting an error when trying to concatenate date and string.
declare #select varchar(max)
declare #where varchar(max)
set #select = 'select * from tbl Emp........'
#where = ' where Emp.date >='+ cast((cast(getdate() as date)) as varchar(20))
exec(#select+#where)
I also tried to do like below but didn't work:
declare #today varchar(20)
#today = cast((cast(getdate() as date))
#where = 'where Emp.date> =' + '#today'
Try something like this...
declare #select varchar(max)
declare #where varchar(max)
set #select = 'select * from tbl Emp '
set #where = ' where Emp.date >= ''' + CONVERT(varchar(8),getdate(),112) + ''''
exec(#select+#where)
Or an even better option would be something like this.....
DECLARE #Sql nvarchar(max);
DECLARE #Date DATE = GETDATE();
SET #Sql = N' select * from tbl Emp '
+ N' where Emp.date >= #Date'
Exec sp_executesql #Sql
,N'#Date DATE'
,#Date
But why do you even need dynamic sql for this simple query why cant you simply do
DECLARE #Date DATE = GETDATE();
select * from tbl Emp
where Emp.date >= #Date

How to use DATETime Column in dynamic query in sql server?

I have a Stored Proc which is using for Search Applicants is written as below:
/*
AUTHOR :
CREATION DATE :
NOTES :
PURPOSE :
MODIFIED BY :
MODIFICATION DATE :
*/
ALTER PROCEDURE USP_GET_ApplicantByFilter
(
#ApplicantName VARCHAR(100)='Ram',
#AgeFrom INT=0,
#AgeTo INT=0,
#Experience INT=0,
#ExperienceMonths INT=0,
#City VARCHAR(100)='',
#QualificationID INT=0,
#PositionID INT=0,
#ApplyDateFrom DATETIME='2010-06-29 00:00:00.000',
#ApplyDateTo DATETIME=NULL,
#SortColumn Varchar(128)='ApplicantID',
#SortDirection Varchar(56)='desc',
#Page int=1,
#RecsPerPage int =10
)
AS
DECLARE #SQL VARCHAR(MAX)
DECLARE #DSQL VARCHAR(MAX)
DECLARE #whereCondition VARCHAR(1024)
DECLARE #FirstRec int, #LastRec int
SET #FirstRec = (#Page - 1) * #RecsPerPage
SET #LastRec = (#Page * #RecsPerPage + 1)
Declare #SectionCount int;
Set NoCount On
Begin
SET #SQL='Select ROW_NUMBER() over( order by '+#SortColumn + ' ' +#SortDirection +') rownum, tblApplicants.ApplicantID, tblApplicants.ApplicantName, tblApplicants.FatherName, tblApplicants.DateOfBirth, tblApplicants.QualificationID, tblApplicants.EMailID, tblApplicants.Address, tblApplicants.City, tblApplicants.State, tblApplicants.Phone,
tblApplicants.ApplyDate, tblApplicants.PositionID, tblApplicants.isActive, tblPositionMaster.PositionName
FROM tblApplicants INNER JOIN tblPositionMaster ON tblApplicants.PositionID = tblPositionMaster.PositionID
WHERE 1=1 AND tblApplicants.isActive=1 '
if #ApplicantName!=''
begin
SET #sql +=' AND tblApplicants.ApplicantName like ''%'+ #ApplicantName +'%'''
end
if #AgeFrom!=0
begin
SET #SQL+=' AND DATEDIFF(YEAR,tblApplicants.DateOfBirth, GETDATE()) >= '+#AgeFrom
end
if #AgeTo!=0
begin
SET #SQL+=' AND DATEDIFF(YEAR,tblApplicants.DateOfBirth, GETDATE()) <= '+#AgeTo
end
if #ApplyDateFrom IS NOT NULL
begin
SET #SQL+= ' AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ CONVERT(DATETIME,#ApplyDateFrom,101)
end
SET #DSQL ='SELECT * from (' + #SQL +') AS tbl'
print #DSQL
DECLARE #TEMPResult TABLE(RowNum INT,
ApplicantID int,
ApplicantName varchar(100),
FatherName varchar(200),
DateOfBirth DATETIME,
QualificationID int,
EMailID varchar(200),
Address varchar(200),
City varchar(200),
State varchar(200),
Phone varchar(200),
ApplyDate DATETIME,
PositionID int,
isActive int,
PositionName varchar(200)
)
INSERT INTO #TEMPResult EXEC(#DSQL)
SELECT (Select Count(*) from #TEMPResult) as Count, * FROM #TEMPResult WHERE RowNum > #FirstRec AND RowNum < #LastRec
RETURN
END
i want to apply "=>" and "<=" operators on ApplyDate. every time i got "*Conversion failed when converting date and/or time from character string.
*"
please help me how can apply these operators on ApplDate
SET #SQL+= ' AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ CONVERT(DATETIME, #ApplyDateFrom, 101)
change it to:
SET #SQL+= ' AND CONVERT(DATETIME, tblApplicants.ApplyDate, 101) = CONVERT(DATETIME, ''' + cast(#ApplyDateFrom as nvarchar) + ''', 101)'
Replace this line
AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ CONVERT(DATETIME,#ApplyDateFrom,101)
Updated
AND DATEDIFF(DD,tblApplicants.ApplyDate, CAST(''' + CAST(#ApplyDateFrom as varchar) + ''' as datetime)) = 0
for more look this query
DECLARE #ApplyDateFrom DATETIME='2010-06-29 00:00:00.000'
DECLARE #QUERY varchar(max)
SET #QUERY =
'SELECT DATEDIFF(DD,GETDATE(), CAST(''' + CAST(#ApplyDateFrom as varchar) + ''' as datetime))'
PRINT #QUERY
#AgeFrom is an int. You need to convert it to a varchar before concatentating it to a string.
'AND DATEDIFF(YEAR,tblApplicants.DateOfBirth, GETDATE()) >= '+convert(varchar(5),#AgeFrom)
Not that this will work, of course, as datediff(year... won't give you an age. eg:
select DATEDIFF(YEAR,'2000-12-25','2013-10-01')
will return 13, not 12.
Similarly for ApplyDate convert that to a string
CONVERT(DATE,tblApplicants.ApplyDate,101) = ''' + CONVERT(varchar(20),#ApplyDateFrom,111) + ''''
To be honest though, this whole approach looks like a bad idea to me.
you just need to make sure the parameter before it come into your stored procedured is in this format yyyy-MM-dd HH:mm:ss
then you're save to compare using "<=" and ">=" and doesn't need to convert it to other format just compare like this
tblApplicants.ApplyDate >='2013-10-01 18:00:00'
You need to cast applydate to string before concatenate to dynamics sql.
Mean
SET #SQL+= ' AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ cast (CONVERT(DATETIME,#ApplyDateFrom,101) AS VARCHAR)

How do I name a column as a date value

the results look like this but wher the column name says 'Today' I want it to be todays date.
Try this technique:
declare #dt datetime
declare #sql varchar(100)
set #dt = getdate()
set #sql = 'select 1 as [ ' + convert( varchar(25),#dt,120) + ']'
exec (#sql)
In your Case:
declare #dt datetime
declare #sql varchar(100)
set #dt = getdate()
set #sql = 'select 0 as [ ' + convert( varchar(25),#dt,120) + ']'
exec (#sql)
I would return an integer representing a day offset and parse it in the client, failing that you are going to have to use dynamic SQL or do something with the underlying column name itself;;
declare #sql nvarchar(128) = '
select
col1,
col2,
0 as [' + cast(getdate() as nvarchar(32)) + ']
from T'
exec(#sql)
Or
--today
declare #now varchar(32) = cast(getdate() as varchar(32))
--result to temp table
select col1, col2, 0 as [Now] into #T from TheTable
--rename col
exec tempdb..sp_rename '#T.Now', #now, 'COLUMN'
--select
select * from #T