Create a new table every time though a stored procedure - sql

I want create a new table every time though a stored procedure.
declare #datetime datetime
declare #date varchar(20)
select #datetime = (GETDATE() - 1)
select #date = convert(varchar(10), #datetime, 112)
print #datetime
print #date
create table #businessmster+'_'+#date
(
contentid int
)
Table name which I want is #businessmaster_20171103

You can use this query.
Declare #strTableName varchar(500)
SET #strTableName = 'create table businessmster_' + #date +'( contentid int )
GO
INSERT INTO businessmster_' + #date +' Select Field FROM <<YourTable>> WHERE <<Condition>>
GO'
Print #strTableName
Exec(#strTableName)

You can use dynamic query as:
DECLARE #TableName NVARCHAR(MAX);
SET #TableName = N'CREATE TABLE businessmaster_'+
CONVERT(VARCHAR(10),GetDate()-1,112)+
N' ( contentid int )';
SELECT #TableName
EXEC(#TableName);
According to your comment I remove the # symbol.

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

Assigning values returned by function in Dynamic SQL

I am trying to generate a dynamic SQL to assign variables with values from a function. I am trying to generate SQL something like
Select #StartDate=#EID_Dept
from dbo.WorkHistory(#today,#EID )
The function returns a date (#EID_dept will be the name of the column returned by the function) which I need to assign to #StartDate. And #EID_Dept is generated by concatenating #EID and #dept.
If I manually write the SQL it would appear as
Select #StartDate = amaan_IT
from dbo.WorkHistory('2016-10-10', amaan)
My code is below:
DECLARE #EID varchar(5), #StartDate VARCHAR(MAX),
#today DATETIME, #dept VARCHAR(10), #EID_dept varchar(20);
Select #today = SYSDATETIME()
Select #dept = dept from dbo.Dept(#EID)
Select #EID_Dept = CONCAT(#EID, #dept)
DECLARE #SQL Varchar(max);
SET #SQL = N'Select #StartDate = #EID_Dept
from dbo.PeriodHistory(#today, #EID)';
EXEC Sp_executesql
#SQL,
N'#StartDate VARCHAR(MAX) out,#EID_dept varchar(max),#today datetime,#EID Varchar',
#StartDate out,
#EID_Dept=#EID_Dept,
#today=#today
I changed your query a little bit. Hope this will work fine:
DECLARE #EID nvarchar(5),
#StartDate nvarchar(MAX),
#today datetime = SYSDATETIME(),
#dept nvarchar(10),
#EID_dept nvarchar(20),
#SQL nvarchar(max),
#params nvarchar(max) = N'#StartDate nvarchar(MAX) out, #today datetime, #EID nvarchar(5)'
Select #dept = dept from dbo.Dept(#EID)
Select #EID_Dept = CONCAT(#EID, #dept)
SET #SQL = N'Select #StartDate = ' + QUOTENAME(#EID_dept) + ' from dbo.PeriodHistory(#today, #EID);';
EXEC sp_executesql #SQL,
#params,
#StartDate = #StartDate out,
#today = #today,
#EID = #EID
SELECT #StartDate
I used nvarchar(max) for #SQL (you are using varchar but adding N when assign value to variable). sp_executesql awaits nvarchar in statement part
Is a Unicode string that contains a Transact-SQL statement or batch.
All parameters I put in #params variable.
As I understood you need to get another columns based on #EID_dept, so I add QUOTENAME and used this variable in SQL statement building directly. You can not send column name as variable.

Sum up values from databases and parametrize it. [SQL Server]

I want to sum up values from several databases. At this moment I have three databases: SPA_PROD, SPB_PROD and SPC_PROD.
My SQL query:
IF EXISTS (SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[TESTSUM]')
AND TYPE IN (N'P',N'PC'))
DROP PROCEDURE [dbo].[TESTSUM]
GO
CREATE PROC TESTSUM
AS
BEGIN
DECLARE #dbName SYSNAME,
#ObjectSUM INT,
#d datetime
SET #d = '20141113'
DECLARE #SQL NVARCHAR(MAX)
DECLARE #DBObjectStats TABLE (
--DBName SYSNAME,
DBObjects INT)
DECLARE curAllDBs CURSOR FOR
SELECT name
FROM MASTER.dbo.sysdatabases
WHERE name like '%PROD'
ORDER BY name
OPEN curAllDBs
FETCH curAllDBs INTO #dbName
WHILE (##FETCH_STATUS = 0) -- db loop
BEGIN
--SQL QUERY
SET #SQL = 'select #dbObjects = sum(doctotal) from ' +
QuoteName(#dbName) + '..Invoice
where DocDate = ''' + cast(#d as varchar(25)) + ''''
PRINT #SQL -- Debugging
EXEC sp_executesql #SQL, N'#dbObjects int output',
#dbObjects = #ObjectSUM output
INSERT #DBObjectStats
SELECT #ObjecSUM
FETCH curAllDBs INTO #dbName
END
CLOSE curAllDBs
DEALLOCATE curAllDBs
-- Return results
SELECT sum(DBObjects) [InvoiceSUM] FROM #DBObjectStats
END
GO
-- Execute stored procedure
EXEC TESTSUM
GO
And this work perfect and giving me right sum from all my DBs: 120 000$ ( 25 000 from SPA_PROD , 95 000 SPC_PROD and 0 (NULL) from SPB_PROD.
What I want to do:
I would like to parametrize, which allows me to choose date and databases. For example I want to choose SPA_PROD and SPB_PROD with date 2014-01-01 in another case I want all databases (SPA + SPB + SPC with another date.
Is this even possible? Any ideas?
I can use everything what gives me SQL Server 2012 and T-SQL. Maybe this technology offers me easiest way to do this.
I am also using SAP Crystal Reports to convert SQL output into a beautiful report.
Sorry for my English and I tried to describe to you my problem as far as I could. If you want any additional information which helps u to help me -> ask me :).
You can create a User-Defined Table Type:
CREATE TYPE DBTable AS TABLE
(
DBName VARCHAR(128)
);
You can use it as an input parameter of your stored procedure. As well as the date parameter.
CREATE PROCEDURE TESTSUM
#Databases DBTable READONLY
,#Date DATETIME
AS
BEGIN
...
...
...
You call it like this:
DECLARE #T AS DBTable;
DECLARE #D AS DATETIME = GETDATE();
INSERT INTO #T VALUES ('DB1', 'DB2', 'DB3')
EXEC TESTSUM #T, #D
maybe instead of
SELECT name
FROM MASTER.dbo.sysdatabases
use
SELECT name
FROM #temptable
and insert into #temptable specific db you want
Using your example I modified it to accept a string of database names (generated through you crystal reports select action). Then passing this string with the date in question to first validate the database exist and if online add the required union clause to the generated SQL code.
CREATE PROCEDURE TESTSUM
#DbNameS NVARCHAR(max)
,#Date DATETIME
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX) = ''
/* ADD EXTRA ',' RO STRING ARRAY OF DATABASES */
SET #DbNameS = #DbNameS + ',';
DECLARE #L INT = LEN(#DbNameS);
DECLARE #D INT = 0;
DECLARE #LD INT = 1;
DECLARE #DBF VARCHAR(50);
DECLARE #ACTIVE INT = 0;
/* START SQL QUERY */
SET #SQL = 'SELECT SUM([InvoiceSUM]) AS [InvoiceSUM] FROM ( SELECT '''' AS DB, 0.00 AS [InvoiceSUM]' + CHAR(13)
/* LOOP THROUGH EACH DBF NAME PASSED CHECKING IF VALID AND ONLINE */
WHILE #D < #L
BEGIN
SET #D = CHARINDEX(',', #DbNameS,#LD);
IF #LD != #D
BEGIN
SET #DBF = SUBSTRING(#DbNameS,#LD,#D-#LD)
/* VALIDATE DBF IS VALID AND ACTIVE */
SELECT #ACTIVE = COUNT(*) FROM SYS.databases WHERE name = #DBF AND [state] = 0
IF #ACTIVE = 1
BEGIN
/*
BEGIN CODE TO UNION THE SUM RESULTS FOR EACH ACTIVE AND VALID DBF
TO MAKE IT WORK WITH SOME EXISTING DBF's ON MY SYSTEM I CHANGED THE SUMMARY CODE FOR TESTING
*/
SET #SQL = #SQL + 'UNION SELECT '''+ #DBF +''' AS DB, ISNULL(SUM( CAST(DVE AS DECIMAL(18,10)) ),0) AS [InvoiceSUM] FROM '+ #DBF + '.DBO.SO_MSTR WHERE CAST(RecordCreated AS DATE) = '''+ CAST(#Date AS VARCHAR(20)) + '''' + CHAR(13)
END;
END;
SET #LD = #D + 1;
END;
/* CLOSE OUT UNION SUMMARY QUERY */
SET #SQL = #SQL + ') AS DATA'
/* OUTPUT RESULTS */
EXEC SP_EXECUTESQL #SQL
END;
Crystal reports would effective be generating this code: EXEC TESTSUM 'SPA_PROD,SPB_PROD,SPC_PROD','12/09/2014'

Report Builder paramter dropdown to choose column name

I have a parameter with the available values as column names and a I am using that parameter in the sql query
WHERE ((#ColumnName) BETWEEN (#StartDate) AND (#EndDate))
AND (schema.table.column_name LIKE (#Number))
When i try to run the report i get a cannot convert date/time from characters
If i remove the #ColumnName parameter the report runs fine but i want the ability to choose a column to search the date against.
If you want pass Column name dynamically you will need to use a stored procedure to do this using dynamic sql something like this....
CREATE PROCEDURE Get_Data
#ColumnName1 SYSNAME,
#ColumnName2 SYSNAME,
#StartDate DATETIME,
#EndDate DATETIME,
#Number VARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQL NVARCHAR(MAX);
SET #SQL = N'SELECT * FROM TableName'
+ N'WHERE ' + QUOTENAME(#ColumnName1) + N' BETWEEN #StartDate AND #EndDate '
+ N' AND ' + QUOTENAME(#ColumnName2) + N' LIKE ''#Number'' '
EXECUTE sp_executesql #SQL
,N'#StartDate DATETIME, #EndDate DATETIME, #Number VARCHAR(100)'
,#StartDate
,#EndDate
,#Number
END

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)