A String Manipulation Puzzle in SQL Server 2008 R2 - sql

This information I have:
Column workflowname has this value ='12STD_Orientations_Workflow'
Column canceldate has a date value
I need to assign a value to the column campaignname like this:
let's say the value in canceldate is in November 2012, the value has to be '12STD_Orientations_2012_Nov'. If the value is in January 2013, the value has to be '12STD_Orientations_2013_Jan'. And so on.
I was thinking about doing a function and assign the value of canceldate (in the INSERT clause) by calling MyFunction(workflowname,canceldate). but I don't know how to write the code inside the function!

Here is a version that will produce the result that you want. This version reverses the current value of the #str value and then looks for the first _ in the string:
declare #str varchar(100) = '12STD_Orientations_Workflow'
declare #dt datetime = '2012-01-01'
select left(#str, len(#str) - charindex('_', REVERSE(#str)))
+ '_'
+ cast(YEAR(#dt) as char(4))
+ '_'
+ CONVERT(char(3), #dt, 109)
See SQL Fiddle with Demo
Then if you want to place this in a function, you can use:
create function dbo.New_Workflow
(
#origName varchar(200),
#dt datetime
)
RETURNS varchar(200)
AS
BEGIN
declare #newvalue varchar(100)
select #newvalue = left(#origName, len(#origName) - charindex('_', REVERSE(#origName)))
+ '_'
+ cast(YEAR(#dt) as char(4))
+ '_'
+ CONVERT(char(3), #dt, 109)
RETURN #newvalue
END;
Then to call this you can use:
declare #str varchar(100) = '12STD_Orientations_Workflow'
declare #dt datetime = '2012-11-01'
select dbo.New_Workflow(#str, #dt)
See SQL Fiddle with Demo
The result is:
| COLUMN_0 |
-------------------------------
| 12STD_Orientations_2012_Nov |
Now if you need to pull this from a table, you would use:
select dbo.New_Workflow(yourWorkFlowNameCol, yourDateColumn)
from yourtable

CREATE FUNCTION dbo.MyFunction
(
#originalString VARCHAR(200),
#dateFromField DATETIME
)
RETURNS varchar(200)
AS
BEGIN
DECLARE #newString VARCHAR(200)
SELECT #newString = LEFT(#originalString,19) + LEFT(CONVERT(VARCHAR(19),#dateFromField,109),3)
RETURN #newString
END;

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

Returning multiple values from a function in sql server

I researched and tried but cant figure it out this is what i got so far.
What i want it to do is concatenate Fstring and Lstring and return the result plus the current date in this case #date
i declared the variables #Fstring and #Lstring as input and #date as the getdate function.
I can only get it to either return the date or #fullname :(
and i cant figure out where im wrong
any help in the right direction will be appreciated
==== start function===
create function ufn_function_4
(
#Fstring varchar(20) , #Lstring varchar(20)
)
returns varchar (20)
as
begin
Declare #date datetime = getdate()
Declare #fullname varchar(100)
set #fullname = #Fstring + ' ' + #Lstring;
return (#date+#fullname)
end
go
==== start select ====
select [dbo].[ufn_function_4]('Fred','Van Vliet');
Change this line as you have just one VARCHAR(20) as RETURN
SET #fullname = #Fstring + ' ' + #Lstring + ' ' + CONVERT(VARCHAR(20), #date)
If you want to return both in separate values you need to define a Table-Valued function
Something like:
CREATE FUNCTION ufn_function_4
(
#Fstring varchar(20) , #Lstring varchar(20)
)
RETURNS #table TABLE ([date] DATETIME, fullname VARCHAR(1000))
AS
BEGIN
Declare #date datetime = getdate()
Declare #fullname varchar(100)
set #fullname = #Fstring + ' ' + #Lstring;
INSERT INTO #table
SELECT #date, #fullname
RETURN
END
To call function
SELECT * FROM ufn_function_4('james', 'connery')
the function you created is a Scalar function which you did it almost right except:
1. increase the length of return type unless your function will return a string of maximum length of 20
2: cast the date time to varchar when you want to concatinate it with varchar values unless you will get type casting error
3: remove the semicolon after setting #file name
I mean your function:
create function ufn_function_4
(
#Fstring varchar(20) , #Lstring varchar(20)
)
returns varchar (100)
as
begin
Declare #date datetime = getdate()
Declare #fullname varchar(100)
set #fullname = #Fstring + ' ' + #Lstring
return (cast(#date as varchar(20))+#fullname)
end
execution:
select [dbo].[ufn_function_4]('Fred','Van Vliet');
output:
Apr 2 2015 4:36AMFred Van Vliet
But if you want to return multiple records or fields then use table-valued function in this case you need to just change the return type to be a table:
CREATE FUNCTION ufn_function_4
(
#Fstring varchar(20) , #Lstring varchar(20)
)
RETURNS #table TABLE ([date] DATETIME, fullname VARCHAR(100))
AS
BEGIN
Declare #date datetime = getdate()
Declare #fullname varchar(100)
set #fullname = #Fstring + ' ' + #Lstring
INSERT INTO #table
SELECT #date, #fullname
RETURN
and run it like:
SELECT * FROM ufn_function_4('Fred','Van Vliet')
output:
date fullname
April, 02 2015 05:11:38 Fred Van Vliet

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)

T-SQL: query with print statement within loop returns results inconsistently

I'm getting an unexpected result while trying to use a print statement within a loop.
Here is the loop. Now, I happen to know that there is no data in this table with a createDtTm earlier than June 2012.
I am trying to return nicely formatted results with nulls weeded out in a single pane, hence all the casting and putting returned data into the #text variable for printing.
Declare #month int, #day int, #text VARCHAR(max)
Select #month=1
Select #day=1
While #month < 13 Begin
While #day < 32 Begin
select #month, #day
set #text = (SELECT cast(min([createDtTm]) as varchar(50)) + ' | ' + cast(max([createDtTm]) as varchar(50)) + ' | ' + cast(DATEDIFF (ss, min([createDtTm]), max([createDtTm])) as varchar(50))
FROM [database].[dbo].[table]
where datepart(yy, createDtTm) = 2012
and datepart(mm, createDtTm) = #month
and datepart(dd, createDtTm) = #day
and datepart(hh, createDtTm) > 17
and cast(Request as varchar(max)) like '%sometext%');
print #text
Set #day = #day + 1
End
Set #month = #month + 1
Set #day = 1
End
This query returns the results I'd expect.
When I comment out the debug statement
select #month, #day
I get no results. Doing just the SELECT in the inner loop returns a long, long pane with text like "NULL" and "(1 row affected)", which I'd rather avoid.
Thoughts? I just learned the mechanics of variable setting, PRINT, WHILE, and BEGIN/END statements this morning so I'm glad I'm getting something back at all, but I'd like to understand the apparent inconsistency.
You need to use
declare #a VARCHAR(max);
declare #b VARCHAR(max);
SELECT #a = '1',#b = '2'
print #a + #b
You can't print a select query as print

Integer to string conversion function in sql

I have a number as follows:
13901210
I want the output to give the following result
1390/12/10
Input function: a number of bigint
Output: a string
How do I create this function?
I wonder why no one suggested this Simple Query
declare #input bigint=13901210
select REPLACE(Convert(varchar,Convert(date,CONVERT(varchar,#input))),'-','/')
SQL Fiddle
DECLARE #integer int = 13901210;
DECLARE #part1 int = #integer / 10000;
DECLARE #part2 int = (#integer - #integer / 10000 * 10000) / 100;
DECLARE #part3 int = #integer - #integer / 100 * 100;
DECLARE #result char(10) =
CAST(#part1 AS char(4)) + '/'
+ CAST(#part2 AS char(2)) + '/'
+ CAST(#part3 AS char(2))
SELECT Part1 = #part1, Part2 = #part2, Part3 = #part3, Result = #result;
GO
You can try this query:
SELECT SUBSTRING(CAST(13901210 AS varchar(8)), 1,4) + '/' + SUBSTRING(CAST(13901210 AS varchar(8)), 5,2) + '/' + SUBSTRING(CAST(13901210 AS varchar(8)), 7,2)
Just replace the value with whatever field/variable you have with the number stored
The full function would look like this:
CREATE FUNCTION [dbo].[int_to_slashed_string] ( #value int )
RETURNS varchar(10)
AS
BEGIN
DECLARE #string varchar(8);
SET #string = CAST(#value AS varchar(8));
RETURN SUBSTRING(#string, 1,4)
+ '/' + SUBSTRING(#string, 5,2)
+ '/' + SUBSTRING(#string, 7,2);
END
This function assumes the value contains 8 digits. If there are other limitations or conditions, the function will have to be modified.
If you do not want to substring the value then you can do this:
DECLARE #nbr INT=13901210
SELECT
LEFT(#nbr,4)+'/'+
SUBSTRING(CAST(#nbr AS VARCHAR(10)),5,2)+'/'+
RIGHT(#nbr,2)
And then the function would look like this:
CREATE FUNCTION [dbo].[GetDateFormatForInt] (#nbr int)
RETURNS varchar(10)
AS
BEGIN
RETURN
LEFT(#nbr,4)+'/'+
SUBSTRING(CAST(#nbr AS VARCHAR(10)),5,2)+'/'+
RIGHT(#nbr,2);
END
This will only work if is a 10 digit number
This also works for me:
CREATE PROCEDURE getdatestr
#result nvarchar(12) output,
#info bigint
AS
BEGIN
SET #result=(SELECT LEFT(CAST(#info AS VARCHAR(8)),4)+'/'+
SUBSTRING(CAST(#info AS VARCHAR(8)),5,2)+'/'+
RIGHT(CAST(#info AS VARCHAR(8)),2))
RETURN #result
END
GO
Except that LEFT,RIGHT return nvarchar and SUBSTRING returns string :) Anyways try it...it gives the same output and if you are ok with it then it is simple to get.