How do I name a column as a date value - sql

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

Related

SQL Server Dynamic SQL - Get output from list of tables

I am trying to loop through a temp table variable that contains a list of table names. I want to simply count the rows in each table where a DateTracked column is greater than 30 days. I am having trouble dynamically changing the FROM #tblName variable to store the record count and then insert it into my tracking table. Eventually I will use a cursor to loop through each, but I just want to get this logic down first for a single table. Here is my test code:
DECLARE #tblName as NVARCHAR(MAX)
DECLARE #q as NVARCHAR(MAX)
SET #q = 'Select Count(DateTracked) FROM Audit.' + #tblName + ' WHERE DateTracked > DATEADD(dd, -30, CAST(GETDATE() as date))'
--DECLARE #tblNameTable TABLE
--(
-- tableName NVARCHAR(MAX)
--)
--INSERT INTO #tblNameTable VALUES (N'myTestTable')
DECLARE #ExpectedRecordsToMove AS TABLE (col1 int)
INSERT INTO #ExpectedRecordsToMove EXECUTE sp_executesql #q, N'#tblName nvarchar(500)', #tblName = 'myTestTable'
SELECT * FROM #ExpectedRecordsToMove
Found solution.
DECLARE #tblName as NVARCHAR(MAX) = 'tblAutoDispatch_DispatchStatus_Map_Tracking'
DECLARE #q as NVARCHAR(MAX) = 'SELECT Count(DateTracked) FROM Audit.' + #tblName + ' WHERE DateTracked > DATEADD(dd, -30, CAST(GETDATE() as date))'
DECLARE #ExpectedRecordsToMove TABLE
(
ExpectedRecordsToMove Int
)
INSERT INTO #ExpectedRecordsToMove
EXECUTE sp_executesql #q
SELECT * FROM #ExpectedRecordsToMove
Note: Answer provided by OP on question.
sp_executesql also allows for output parameters. It is possible to assign variable inside the inner query and return the value.
DECLARE #tblName AS NVARCHAR(MAX) = N'tblAutoDispatch_DispatchStatus_Map_Tracking';
DECLARE #q AS NVARCHAR(MAX)
= N'SELECT #rowcount = COUNT(DateTracked) FROM Audit.' + #tblName
+ N' WHERE DateTracked > DATEADD(dd, -30, CAST(GETDATE() as date))';
DECLARE #rowcount INT;
EXECUTE sp_executesql
#query = #q,
#parameters = N'#rowcount INT OUTPUT',
#rowcount = #rowcount OUTPUT;
SELECT
#rowcount;
You can actually do this without a cursor, by building up the query in one go
You must use QUOTENAME to ensure table names do not cause syntax errors
You cannot parameterize a table name, it must be inserted directly into dynamic SQL
DECLARE #tablenames TABLE (schemaName sysname, tblName sysname);
-- insert schema and table names
DECLARE #sql nvarchar(max) = N'
SELECT
ISNULL(tblName, ''Grand Total'') AS tblName,
SUM(rowcount) AS rowcount
FROM (
' +
(
SELECT STRING_AGG(CAST(
N' SELECT ' + QUOTENAME(tn.schemaName, '''') + N'.' + QUOTENAME(tn.tblName, '''') + N' AS tblName,
Count(DateTracked) AS rowCount
FROM ' + QUOTENAME(tn.schemaName) + N'.' + QUOTENAME(tn.tblName) + N'
WHERE DateTracked > DATEADD(dd, -30, CAST(GETDATE() as date))'
AS nvarchar(max)), N'
UNION ALL
')
FROM #tablenames tn
JOIN sys.tables t ON tn.schemaName = SCHEMA_NAME(t.schema_id) AND tn.tblName = t.name
) + N'
) AS tables
GROUP BY ROLLUP(tblName);
';
PRINT #sql; -- for testing
EXEC (#sql);
If you don't have STRING_AGG on your version of SQL Server, you must use FOR XML instead

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

How to extract a value from Dynamic SQL result?

I'm trying to get a few values from a dynamic SELECT
This is my code:
DECLARE #sqlCommand varchar(1000)
DECLARE #colName varchar(20)
DECLARE #tableName varchar(20)
DECLARE #myNum int
DECLARE #varDate varchar(19)
DECLARE #myTime datetime2
set #varDate = getdate()
SET #colName = 'col1'
SET #tableName = 'table'
SET #sqlCommand = 'SELECT top 1 #myTime=mytime, #myNum=' + #colName + ' FROM ' + #tableName + ' WHERE mytime>=''' + #varDate + ''' ORDER BY mytime'
PRINT #sqlCommand
EXEC(#sqlCommand)
When I print the SQL command, this is what I get:
SELECT top 1 #myTime=mytime, #myNum=col1
FROM table
WHERE mytime>='Jul 25 2017 4:40PM'
ORDER BY mytime
When I try to EXEC it, I get this error:
Must declare the scalar variable "#myTime".
If I do this:
SET #sqlCommand = 'SELECT top 1 mytime, ' + #colName + ' FROM ' + #tableName + ' WHERE mytime>=''' + #varDate + ''' ORDER BY mytime'
It works well, but I need to use that data.
Thanks in advance.
Use sp_executesql:
exec sp_executesql #sqlCommand,
N'#myNum int output, #myTime datetime2 output, #vardate datetime2',
#myNum = #myNum output,
#myTime = #myTime output,
#vardate = #vardate;
This is a much better way to run SQL code, because handling parameters is built-in.
Simple...use the Variable passing features, make to identify the Output variables last in the list of variables
Rough signature but should get you started #o_sdate, #o_edate, and #o_resp are variables declared outside of the dynamic sql
exec sp_executesql #sql
, N'#sdate date, #edate date, #resp smallint OUTPUT'
, #sdate = #o_sdate, #edate = #o_edate, #resp = #o_resp OUTPUT
You should use "insert exec" to get your variable out off the dynamic sql. Or use a "double-hash"-table.
DECLARE #sqlCommand varchar(1000)
DECLARE #colName varchar(20)
DECLARE #tableName varchar(20)
DECLARE #myNum int
DECLARE #varDate varchar(19)
DECLARE #myTime datetime2
set #varDate = getdate()
SET #colName = 'col1'
SET #tableName = 'table'
SET #sqlCommand = 'SELECT top 1 mytime, ' + #colName + ' FROM ' + #tableName + ' WHERE mytime>=''' + #varDate + ''' ORDER BY mytime'
PRINT #sqlCommand
create table #t1 (mytime datetime, col1 varchar(20))
insert #t1 (mytime, col1) EXEC(#sqlCommand)
select #mytime=mytime, #col1=col1 from #t1
I hope you got the idea.

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