SQL IF and ELSE block with temp tables inside - sql-server

I got a quite big query with CTEs, temp tables and I'd like to put it into IF and ELSE blocks, for having different conditions for both of them, depend on parameter. In simplified it looks as below:
DECLARE #parameter varchar(15)
If(OBJECT_ID('tempdb..#table1') Is Not Null)
Begin
Drop Table #table1
End
create table #table1
(
column1
column2
column3
)
If(OBJECT_ID('tempdb..#table2') Is Not Null)
Begin
Drop Table #table2
End
create table #table2
(
column1
column2
column3
)
IF #parameter = 'Option1' BEGIN
select * from (
INSERT INTO #table1
select * from... where 'condition_for_Option1'
INSERT INTO #table2
select * from... where 'condition_for_Option1'
select * from #table1
union all
select * from #table2) as DATA
END ELSE
IF #parameter = 'Option2' BEGIN
SELECT *
FROM
(
INSERT INTO #table1
select * from... where 'condition_for_Option2'
INSERT INTO #table2
select * from... where 'condition_for_Option2'
select * from #table1
union all
select * from #table2)
as DATA
END
I put the #temp tables at the beginning and it fixed a part of issues, but I still got:
Msg 156, Level 15, State 1, Line 31
Incorrect syntax near the keyword 'INSERT'.
Msg 102, Level 15, State 1, Line 37
Incorrect syntax near ')'.
Msg 156, Level 15, State 1, Line 48
Incorrect syntax near the keyword 'INSERT'.
Msg 102, Level 15, State 1, Line 54
Incorrect syntax near ')'.
Is this any way how to make this work?

You can not have insert statement in select statement. Actualy you can rewrite:
IF #parameter = 'Option1'
BEGIN
INSERT INTO #table1
SELECT * FROM... WHERE 'condition_for_Option1'
INSERT INTO #table2
SELECT * FROM... WHERE 'condition_for_Option1'
SELECT * FROM #table1
UNION ALL
SELECT * FROM #table2
END
ELSE IF #parameter = 'Option2'
BEGIN
INSERT INTO #table1
SELECT * FROM... WHERE 'condition_for_Option2'
INSERT INTO #table2
SELECT * FROM... WHERE 'condition_for_Option2'
SELECT * FROM #table1
UNION ALL
SELECT * FROM #table2
END
but I can't see any usage of temp table here, so you can rewrite:
IF #parameter = 'Option1'
BEGIN
SELECT * FROM... WHERE 'condition_for_Option1'
UNION ALL
SELECT * FROM... WHERE 'condition_for_Option1'
END
ELSE IF #parameter = 'Option2'
BEGIN
SELECT * FROM... WHERE 'condition_for_Option2'
UNION ALL
SELECT * FROM... WHERE 'condition_for_Option2'
END

Why not this ?
IF #parameter = 'Option1' BEGIN
INSERT INTO #table1
select * from... where 'condition_for_Option1'
INSERT INTO #table2
select * from... where 'condition_for_Option1'
select * from (
select * from #table1
union all
select * from #table2) as DATA
END
ELSE
IF #parameter = 'Option2' BEGIN
INSERT INTO #table1
select * from... where 'condition_for_Option2'
INSERT INTO #table2
select * from... where 'condition_for_Option2'
SELECT *
FROM
(
select * from #table1
union all
select * from #table2)
as DATA
END

Related

Executing scripts as XML in Azure Synapse Analytics

I am not able to execute a script by parsing it as XML as mentioned here. I see that it is not supported in Synapse based on MSDN. Could someone please help me how could I achieve this in SQL DW? I have a table that have all the SQL Statements and I want to execute them by looping through each record in that column.
DDL:
CREATE TABLE [#Temp]
(
JOB_ID INT NOT NULL,
SQL_STMNT NVARCHAR(2000)
);
DML:
INSERT INTO #Temp
SELECT 100, 'SELECT * FROM Table_A WHERE MyDate = #ProcessDate'
UNION
SELECT 103, 'SELECT * FROM Table_B WHERE MyDate = #ProcessDate AND MyCode = ''ABC'''
UNION
SELECT 110, 'SELECT * FROM Table_C WHERE MyDate = #ProcessDate AND MyID = 345'
UNION
SELECT 200, 'SELECT * FROM Table_D WHERE MyDate = #ProcessDate'
UNION
SELECT 230, 'SELECT * FROM Table_E WHERE MyDate = #ProcessDate'
You can use the STRING_AGG function:
DECLARE #sql nvarchar(max) = (
SELECT STRING_AGG(CAST(SQL_STMNT as nvarchar(max)), '; ') WITHIN GROUP (ORDER BY JOB_ID ASC)
FROM #Temp
);
exec(#sql);

Better way to write "like operator" in SQL Server

Is there any better way to re-write the below code?
SELECT *
FROM PROFILE
WHERE GRP_NUMBER NOT LIKE '2%' AND GRP_NUMBER NOT LIKE '7%'
SELECT *
FROM PROFILE
WHERE GRP_NUMBER LIKE '[^27]%'
Try below sample
DECLARE #Table TABLE(
Col VARCHAR(50)
)
INSERT INTO #Table SELECT '2ABC'
INSERT INTO #Table SELECT '4Italy2'
INSERT INTO #Table SELECT '3Apple'
INSERT INTO #Table SELECT '234.62'
INSERT INTO #Table SELECT '2:234:43:22'
INSERT INTO #Table SELECT '7'
INSERT INTO #Table SELECT '6425.23'
INSERT INTO #Table SELECT '2'
INSERT INTO #Table SELECT 'Lions'
SELECT * FROM #Table
WHERE Col NOT LIKE '[27]%'
SELECT *
FROM PROFILE
WHERE GRP_NUMBER NOT LIKE '[27]%'

Case expression in where clause

I would like to get all records (6 rows) from testTable if a = 4. 4 is default parameter in SP.
create table testTable(a int, b int, c int)
go
insert into testTable values(2, 101, 100000)
go
insert into testTable values(2, 101, 100001)
go
insert into testTable values(3, 101, 100002)
go
insert into testTable values(3, 102, 100003)
go
insert into testTable values(4, 1, 100004)
go
insert into testTable values(4, 1, 100005)
go
create proc SPtest
#a int = 4,
#b int = 1
as
select * from testTable where a = #a and b = #b
exec SPtest 2, 101
Above works well. but I need something like this:
declare #a int
set #a = 4
select *
from testTable
where a = case #a when 4 then select distinct a from testTable end
There are few ways to cut the cookie, this would seem the most logical;
IF #a = 4 THEN
BEGIN
SELECT *
FROM testTable
END
ELSE
BEGIN
SELECT *
FROM testTable
WHERE a = #a and b = #b
END
Alternatively you can use an or statement;
SELECT *
FROM testTable
WHERE #a = 4 or (a = #a and b = #b)
Good luck (would have commented but I not there yet).
Regards,
Please try this:
create proc SPtest
#a int = 4,
#b int = 1
as
if #a = 4
select distinct a from testTable
else
select * from testTable where a = #a and b = #b
go
exec SPtest
exec SPtest 3,101

In MS SQL how to split a column into rows with no delimiter

I have data in a table which looks like this (worth noting its not CSV seperated)
It needs to be split in to single chars
Data
abcde
want to convert it to this
Data
a
b
d
c
e
I have looked on the internet but have not found the answer
CREATE FUNCTION dbo.SplitLetters
(
#s NVARCHAR(MAX)
)
RETURNS #t TABLE
(
[order] INT,
[letter] NCHAR(1)
)
AS
BEGIN
DECLARE #i INT;
SET #i = 1;
WHILE #i <= LEN(#s)
BEGIN
INSERT #t SELECT #i, SUBSTRING(#s, #i, 1);
SET #i = #i + 1;
END
RETURN;
END
GO
SELECT [letter]
FROM dbo.SplitLetters(N'abcdefgh12345 6 7')
ORDER BY [order];
Previous post that solves the problem: TSQL UDF To Split String Every 8 Characters
Pass a value of 1 to #length.
declare #T table
(
ID int identity,
Data varchar(10)
)
insert into #T
select 'ABCDE' union
select '12345'
;with cte as
(
select ID,
left(Data, 1) as Data,
stuff(Data, 1, 1, '') as Rest
from #T
where len(Data) > 0
union all
select ID,
left(Rest, 1) as Data,
stuff(Rest, 1, 1, '') as Rest
from cte
where len(Rest) > 0
)
select ID,
Data
from cte
order by ID
You could join the table to a list of numbers, and use substring to split data column into rows:
declare #YourTable table (data varchar(50))
insert #YourTable
select 'abcde'
union all select 'fghe'
; with nrs as
(
select max(len(data)) as i
from #YourTable
union all
select i - 1
from nrs
where i > 1
)
select substring(yt.data, i, 1)
from nrs
join #YourTable yt
on nrs.i < len(yt.data)
option (maxrecursion 0)
declare #input varchar(max);
set #input = 'abcde'
declare #table TABLE (char varchar(1));
while (LEN(#input)> 0)
begin
insert into #table select substring(#input,1,1)
select #input = RIGHT(#input,Len(#input)-1)
end
select * from #table

How to make row data comma separated in SQL?

I am having one query which returns me following output.
(No of results not same all time, means sometimes it gives 3 category,sometimes 8 category etc..)
CategoryName
Test1
Test2
Test3
Now i want that store procedure should return me these date in comma separated format.
e.g. output string should be like: Test1,Test2,Test3
Can you please tell me how can i achieve this?
this will work for all characters in your data:
set nocount on;
declare #YourTable table (BirthDay datetime, PersonName varchar(20))
insert into #YourTable VALUES ('1-10-2010', 'Joe' )
insert into #YourTable VALUES ('2-10-2010', 'Bob <&>' )
insert into #YourTable VALUES ('2-10-2010', 'Alice')
set nocount off
--Concatenation with FOR XML and eleminating control/encoded character expansion "& < >"
SELECT
p1.BirthDay
,STUFF(
(SELECT
', ' + p2.PersonName
FROM #YourTable p2
WHERE p2.BirthDay=p1.BirthDay
ORDER BY p2.PersonName
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,2, ''
) AS PersonNames
FROM #YourTable p1
GROUP BY p1.BirthDay
OUTPUT:
BirthDay PersonNames
----------------------- ------------------------
2010-01-10 00:00:00.000 Joe
2010-02-10 00:00:00.000 Alice, Bob <&>
(2 row(s) affected)
Try COALESCE or ISNULL:
DECLARE #returnValue varchar(MAX)
SELECT
#returnValue = COALESCE(#returnValue + ', ', '') + CategoryName
FROM
TableName
Have a look at something like (Full working example)
DECLARE #Table TABLE(
ID INT,
Val VARCHAR(50)
)
INSERT INTO #Table (ID,Val) SELECT 1, 'A'
INSERT INTO #Table (ID,Val) SELECT 1, 'B'
INSERT INTO #Table (ID,Val) SELECT 1, 'C'
INSERT INTO #Table (ID,Val) SELECT 2, 'B'
INSERT INTO #Table (ID,Val) SELECT 2, 'C'
--Concat
SELECT t.ID,
STUFF((
SELECT ',' + t1.Val
FROM #Table AS t1
WHERE t1.ID = t.ID
FOR XML PATH('')
), 1, 1, '')
FROM #Table t
GROUP BY t.ID
Also, you might find that Googling will provide a lot of answers.
One means:
SELECT STUFF((
SELECT ',' + CategoryName AS [text()]
FROM YourTable
FOR XML PATH('')
), 1, 1, '')
...but watch out for XML entities that will be escaped up - e.g. & => &
Just modify the KM answer in a store procedure
ALTER Procedure [dbo].[Payroll_rptAbsentReport]
#FromDate DateTime,
#ToDate DateTime,
#GFacatoryID UniqueIdentifier
As
Begin
-- Temporary table for Row data seperation
CREATE TABLE TestTable(GEmployeeGenInfoID uniqueidentifier, dtAttendDateTime varchar(max))
INSERT INTO
TestTable(GEmployeeGenInfoID, dtAttendDateTime)
SELECT
Payroll_tblAttendance.GEmployeeGenInfoID
,CONVERT(VARCHAR(max), dtAttendDateTime, 105)dtAttendDateTime
FROM Payroll_tblAttendance
INNER JOIN PIS.dbo.PIS_tblEmployeeGenInfo as EmployeeGenInfo ON Payroll_tblAttendance.GEmployeeGenInfoID= EmployeeGenInfo.GEmployeeGenInfoID
WHERE Payroll_tblAttendance.DayStatusID = 0 AND EmployeeGenInfo.GFactoryID=#GFacatoryID AND Payroll_tblAttendance.dtAttendDateTime Between #FromDate and #ToDate ORDER BY dtAttendDateTime
-- Final expected output
SELECT DISTINCT
EmployeeGenInfo.StrEmpName
,EmployeeGenInfo.StrEmpID
,Attendence.CardNo
,EmployeeDesignation.StrDesignationName
,EmployeeDept.StrDepartmentName
-- Count data will be in one column
,(Select COUNT(*) From TestTable Where GEmployeeGenInfoID=Attendence.GEmployeeGenInfoID) TotalAbsent
-- Row data set into one column seperate by coma
,substring( ( SELECT ', ' + dtAttendDateTime as [text()]
FROM TestTable
WHERE GEmployeeGenInfoID = Attendence.GEmployeeGenInfoID
FOR XML path(''), elements
), 3, 1000
) List
FROM
Payroll_tblAttendance as Attendence
INNER JOIN TestTable on TestTable.GEmployeeGenInfoID=Attendence.GEmployeeGenInfoID
INNER JOIN PIS.dbo.PIS_tblEmployeeGenInfo as EmployeeGenInfo ON Attendence.GEmployeeGenInfoID= EmployeeGenInfo.GEmployeeGenInfoID
INNER JOIN PIS.dbo.PIS_tblDesignationInfo as EmployeeDesignation ON EmployeeGenInfo.GDesignationInfoID= EmployeeDesignation.GDesignationInfoID
INNER JOIN PIS.dbo.PIS_tblDepartment as EmployeeDept ON EmployeeGenInfo.GDepartmentID= EmployeeDept.GDepartmentID
WHERE EmployeeGenInfo.GFactoryID=#GFacatoryID AND Attendence.DayStatusID = 0 AND Attendence.dtAttendDateTime Between #FromDate and #ToDate
DROP TABLE TestTable
END

Resources