Related
I wrote two stored procedures
ALTER PROCEDURE [dbo].[GetPhysicalChildNodesAsString]
-- Add the parameters for the stored procedure here
#Book varchar(50),
#Vertical varchar(50)
AS
BEGIN
DECLARE #results nvarchar(max)
;WITH cte AS
(
SELECT a.BookID, a.ParentBookID, a.BookName
FROM DimBook a
WHERE BookName = #Book
UNION ALL
SELECT a.BookID, a.ParentBookID, a.BookName
FROM DimBook a JOIN cte c ON a.ParentBookID = c.BookID
and HighPortfolioID = ( select PortfolioID from portfolioMaster where PortfolioName = #Vertical and PortfolioType='HighPortfolio')
)
select #results = coalesce(#results + ',', '')+'''' + convert(varchar(max),BookName)+''''
from cte Where Len(BookName) < 20
select #results as Book
END
Above stored Proc returns below string
'Physical','Anish Vohra','Sandeep Bajoria','Nirav Desai','Sushil Mohta','Sahil Pasad','G R Poddar','Direct','Sales Broker','Internal Transfer','Sprint','Murji Meghan','Intra Oils & Fats','GGN','GGN1','GGN2','Book1','Book2','Book 3','Book4','Book5','Comglobal','Sunvin','PVOC','Afro Asian'
DECLARE #BooksList varchar(max)
DECLARE #t table(BookNames varchar(max) )
INSERT #t(BookNames)
EXEC #BooksList = GetPhysicalChildNodesAsString 'Physical','Enterprise'
SELECT #BooksList = BookNames FROM #t
select #BooksList as 'books'
select * from DimBook where BookName IN(select #BooksList as 'books') ----> reults only header of table Only. But if pass result string directly like below it is working. can you help me for why above query is not working
select * from DimBook where BookName IN('Physical','Anish Vohra','Sandeep Bajoria','Nirav Desai','Sushil Mohta','Sahil Pasad','G R Poddar','Direct','Sales Broker','Internal Transfer','Sprint','Murji Meghan','Intra Oils & Fats','GGN','GGN1','GGN2','Book1','Book2','Book 3','Book4','Book5','Comglobal','Sunvin','PVOC','Afro Asian') ----> getting correctly.
I wrote a SP which will call internally another parameterized SP and output will be store into a physical table.While I am executing Outer SP I am getting following error.
Msg 207, Level 16, State 1, Procedure CBs_LargeExposer, Line 88 [Batch
Start Line 12] Invalid column name 'SlNo'.
I observed, if I execute inner SP in separate window and very next to it if I execute the same outer SP is working fine, after certain time if I execute the same statement(Outer SP) I am getting same error.
ALTER PROCEDURE [dbo].[CBS_GlMapping]
#finYear nvarchar(30)='2019-2020',
#quarter char(5)='Q2',
#Oflag Varchar(6)='O4'
AS
BEGIN
SET NOCOUNT ON;
Declare #QtrStart date,#QtrSEnd date,#FyFrom int,#FyTo int,#BranchId int
select #FyFrom=year(YearBeginDate),#FyTo=Year(YEarEndDate) from BranchTable where BranchCode in(select OrgBankCode from OrgDetails)
IF(#FyFrom < left(#finYear,4) and #FyTo < Right(#finYear,4))
Begin
print 'Sorry, Recods are not available for the financial year ' + #finYear
return
End
If(#quarter='Q1')
Begin
select #QtrStart=YearBeginDate,#QtrSEnd=EOMONTH(DATEADD(MM,2,YearBeginDate)) from BranchTable where BranchCode in(select OrgBankCode from OrgDetails)
End
If(#quarter='Q2')
Begin
select #QtrStart=Dateadd(mm,3,YearBeginDate),#QtrSEnd=EOMONTH(DATEADD(MM,5,YearBeginDate)) from BranchTable where BranchCode in(select OrgBankCode from OrgDetails)
End
If(#quarter='Q3')
Begin
select #QtrStart=Dateadd(mm,6,YearBeginDate),#QtrSEnd=EOMONTH(DATEADD(MM,8,YearBeginDate)) from BranchTable where BranchCode in(select OrgBankCode from OrgDetails)
End
If(#quarter='Q4')
Begin
select #QtrStart=DATEADD(month, DATEDIFF(month, 0,Dateadd(mm,-2,YEarEndDate)), 0),#QtrSEnd=YEarEndDate from BranchTable where BranchCode in(select OrgBankCode from OrgDetails)
End
/* To handel the Financial year */
if(left(#finYear,4)<year(#QtrStart) and #quarter<>'Q4')
begin
set #QtrStart = cast(left(#finYear,4) as varchar(4))+'-'+cast(month(#QtrStart) as Varchar(2))+'-'+Cast(day(#QtrStart) as Varchar(2))
set #QtrSEnd = cast(left(#finYear,4) as varchar(4))+'-'+cast(month(#QtrSEnd) as Varchar(2))+'-'+Cast(day(#QtrSEnd) as Varchar(2))
end
if(right(#finYear,4)<year(#QtrStart) and #quarter='Q4')
begin
set #QtrStart = cast(right(#finYear,4) as varchar(4))+'-'+cast(month(#QtrStart) as Varchar(2))+'-'+Cast(day(#QtrStart) as Varchar(2))
set #QtrSEnd = cast(right(#finYear,4) as varchar(4))+'-'+cast(month(#QtrSEnd) as Varchar(2))+'-'+Cast(day(#QtrSEnd) as Varchar(2))
end
Create table #tempData
(
Bal numeric(15,2)
)
declare #sql varchar(500),#sql2 varchar(500),#day Varchar(10),#Month varchar(2),#Year varchar(4)
select #day= Day(#QtrSEnd)
select #Month= month(#QtrSEnd)
select #Year= Year(#QtrSEnd)
Create table #temp
( slno int,
glcode Varchar(500),
GlLen int,
ColNO varchar(50),
CellNo varchar(50),
Amount Numeric(15,2)
)
declare #tsql varchar(500)
set #tsql=N'
insert into #temp
select ROW_NUMBER() over(order by glcode) slno,glcode,LEN(Glcode) GlLen,ColNo,CellNo,amount
from BsGl'+#Oflag+'
where glcode <>'''' '
exec(#tsql)
declare #LoopStart int,#loopEnd Int,#glcode varchar(500),#amt numeric(15,0)
select #LoopStart=Min(Slno) from #temp
select #loopEnd=MAX(Slno) from #temp
while (#LoopStart <= #loopEnd)
begin
select #glcode= Glcode from #temp where slno = #LoopStart
set #sql='insert into #tempData select Sum(day'+#day+') from DayBal where AcYear='+#Year+' and acmonth='+#Month+'and GlCode in(SELECT glcode FROM dbo.splitstring(convert(varchar(500),'''+#glcode+''')))'
EXEC(#sql)
update #temp set Amount=(select Bal from #tempData) where slno =#LoopStart
set #LoopStart=#LoopStart+1
Truncate table #tempData
end
set #tsql=''
set #tsql='update BsGl'+#Oflag+' set Amount=0.00 where Glcode ='''' '
EXEC(#tsql)
set #tsql=''
set #tsql='update B set B.amount=isnull(round((Case when A.Amount<0 then A.Amount*(-1) else A.Amount end/1000),0),0) from #temp a inner join BsGl'+#Oflag+' B on a.CellNo=B.CellNo and B.ColNo=A.ColNo'
EXEC(#tsql)
IF(#Oflag='O4')
BEGIN
EXEC [DBO].[CBs_LargeExposer] #QtrSEnd
END
Drop table #temp
End
Not sure if you have tried this already. Try specifying the exact same column name "slno" as in CREATE TABLE statement, in the below two SELECT statements, instead of "Slno".
select #LoopStart=Min(Slno) from #temp
select #loopEnd=MAX(Slno) from #temp
I found the Solution for the error. I created same #temporary table in outer sp as well as in inner sp with different columns. Basically a #temporary table's scope is limited to the session but when you are calling a inner Sp inside a outer sp it will consider a single session.
Outer SP TempTable Declaration
Create table #tempData
(
Bal numeric(15,2)
)
Inner SP TempTable Declaration
CREATE TABLE #tempData(
[ID] int identity(1,1) ,
[Funded] [numeric](15, 2) NOT NULL,
[NonFunded] [numeric](2, 2) NOT NULL,
[Limitsanctioned] [numeric](15, 2) NOT NULL
)
So I changed the #tmpData to #tempData1 in outer Sp it's working fine.
How would I return a table from a SQL Server function?
In Postgres, I would simply do something like the following:
CREATE FUNCTION table_get(_active_bool BOOLEAN)
RETURNS TABLE(column integer)
language plpgsql
as $$
BEGIN
RETURN QUERY
SELECT column
FROM table
WHERE active = _active_bool
END;
$$;
And it will just work.
For what ever reason I can't get this one to work in SQL Server.
CREATE FUNCTION hr.naughty_emp_id_get
(#pquarter NVARCHAR(1),
#pyear NVARCHAR(4))
RETURNS TABLE (employeeid INT)
AS
BEGIN
WITH vars AS
(
SELECT #pquarter AS pquarter, #pyear AS pyear
)
SELECT tblhr_employees.employeeid
FROM hr.tblhr_employees
INNER JOIN hr.tblHR_AttendancePunchTime ON tblhr_employees.employeeid = tblHR_AttendancePunchTime.EmployeeID
INNER JOIN hr.tblHR_AttendanceTimeCode ON tblHR_AttendancePunchTime.CodeID = tblHR_AttendanceTimeCode.CodeID
WHERE 1 = 1
AND (tblHR_AttendanceTimeCode.CategoryID = 3
OR tblHR_AttendanceTimeCode.CategoryID = 11)
AND dbo.to_year_quarter(tblHR_AttendancePunchTime.AdjTimeIn) = (SELECT vars.pyear FROM vars) + '-' + (SELECT vars.pquarter FROM vars)
AND tblhr_employees.separationdate IS NULL
GROUP BY
tblhr_employees.employeeid;
RETURN
END
GO
It is throwing this error:
Msg 156, Level 15, State 1, Procedure naughty_emp_id_get, Line 18 [Batch Start Line 6]
Incorrect syntax near the keyword 'BEGIN'
I tried adding ;s in various spots and it didn't seem to work
You are missing the table name for the table to be returned. This should work
CREATE FUNCTION hr.naughty_emp_id_get
(
-- Add the parameters for the function here
#pquarter NVARCHAR(1)
, #pyear NVARCHAR(4)
)
RETURNS #employees TABLE (employeeid INT)
AS
BEGIN
WITH vars AS (SELECT #pquarter AS pquarter, #pyear AS pyear)
INSERT #employees
SELECT tblhr_employees.employeeid
FROM hr.tblhr_employees
INNER JOIN hr.tblHR_AttendancePunchTime ON tblhr_employees.employeeid = tblHR_AttendancePunchTime.EmployeeID
INNER JOIN hr.tblHR_AttendanceTimeCode ON tblHR_AttendancePunchTime.CodeID = tblHR_AttendanceTimeCode.CodeID
WHERE 1=1
AND (tblHR_AttendanceTimeCode.CategoryID = 3
OR tblHR_AttendanceTimeCode.CategoryID = 11)
AND dbo.to_year_quarter(tblHR_AttendancePunchTime.AdjTimeIn) = (SELECT vars.pyear FROM vars) + '-' + (SELECT vars.pquarter FROM vars)
AND tblhr_employees.separationdate IS NULL
GROUP BY tblhr_employees.employeeid;
RETURN
END
You have mixed 2 ways of declaring the resulting temporal table.
Either declare as table variable and explicitly insert into it:
CREATE FUNCTION hr.naughty_emp_id_get
(
#pquarter NVARCHAR(1)
, #pyear NVARCHAR(4)
)
RETURNS #result TABLE (employeeid INT) -- Here
AS
BEGIN
;WITH vars AS (SELECT #pquarter AS pquarter, #pyear AS pyear)
INSERT INTO #result (employeeid) -- And here
SELECT tblhr_employees.employeeid
FROM --...
END
Or avoid it's declaration altogether:
CREATE FUNCTION hr.naughty_emp_id_get
(
-- Add the parameters for the function here
#pquarter NVARCHAR(1)
, #pyear NVARCHAR(4)
)
RETURNS TABLE AS RETURN
WITH vars AS (SELECT #pquarter AS pquarter, #pyear AS pyear)
SELECT tblhr_employees.employeeid
FROM --...
You have to insert into the resulting table variable.
RETURNS #MyTable TABLE (MyID INT)
AS BEGIN
INSERT INTO #MyTable SELECT 1
RETURN
END
I am working on a SQL query where I have to store result of a stored procedure into a string type variable. There is a stored procedure named SP_CheckAgentProperty which is returning a string type of value either 'y' or 'N' or 'NP'.
I am passing an integer value to the stored procedure. I want to store this output in any string variable. For this I am using this SQL query:
My stored procedure is:
CREATE Procedure [dbo].[SP_CheckAgentProperty] --12
(
#ID bigint =null
)
As
BEGIN
------Calculating total Ads Post allowed of any specific package of any user-----
DECLARE #Ad int=(SELECT tblPackage.Ads FROM tblPayment_Details INNER JOIN tblPayments ON tblPayments.ID =
tblPayment_Details.Payment_ID INNER JOIN tblPackage ON tblPayments.Package_ID = tblPackage.ID
WHERE (tblPayment_Details.Payment_ID =(SELECT MAX(ID) AS d FROM tblPayments AS tblPayments_1 WHERE (User_ID = #ID))))
print #Ad
------Calculating the date when the user makes the last payment------
DECLARE #St DATE=(SELECT tblPayment_Details.Date FROM tblPayment_Details INNER JOIN tblPayments ON
tblPayments.ID = tblPayment_Details.Payment_ID INNER JOIN tblPackage ON tblPayments.Package_ID = tblPackage.ID
WHERE (tblPayment_Details.Payment_ID =(SELECT MAX(ID) AS d FROM tblPayments AS tblPayments_1 WHERE (User_ID = #ID))))
print #St
------Calculating the validity of specific package taken by any user-----
DECLARE #LT int=(SELECT tblPackage.Validity FROM tblPayment_Details INNER JOIN tblPayments ON tblPayments.ID =
tblPayment_Details.Payment_ID INNER JOIN tblPackage ON tblPayments.Package_ID = tblPackage.ID
WHERE (tblPayment_Details.Payment_ID =(SELECT MAX(ID) AS d FROM tblPayments AS tblPayments_1 WHERE (User_ID = #ID))))
print #LT
print dateadd(DAY,#LT,#St)
-------Calculating the Remaining days of package taken by the user
DECLARE #NoOfDays int=(select DATEDIFF(DAY,GETDATE(),dateadd(DAY,#LT,#St)))
print #NoOfDays
-------Calculating if the user makes does not any payment in history------
DECLARE #SS int=(ISNULL(DATEDIFF(DAY, GETDATE(), #St), 0))
IF(#SS='0')
BEGIN
select 'NP' as Message
END
ELSE
BEGIN
if(#NoOfDays<=0)
BEGIN
--select 'This User Does Not Make a Payment.' as Message
select 'MP' as Message
END
ELSE
BEGIN
DECLARE #TOT int=(select count(*) from tblProperty where tblProperty.Date between #St and dateadd(DAY,#LT,#St))
--group by tblProperty.ID
--select count(*) from tblProperty where tblProperty.Date between '2015-07-04' and dateadd(DAY,20,'2015-07-04')
IF(#TOT<#Ad)
BEGIN
select 'y' as Message
END
ELSE
BEGIN
select 'N' as Message
END
END
END
END
And I am using the above stored procedure like this:
declare #ss varchar(10)
exec #ss = SP_CheckAgentProperty 10
if(#ss='NP')
BEGIN
print 'Not Payment'
END
else
BEGIN
print 'Payment'
END
The above query is returning the appropriate result but when I am using its output in if condition then it is not working.
If the procedure is "returning" the value by selecting it, you'll have to use insert into with something like this:
declare #ss table (ss varchar(10))
insert into #ss exec SP_CheckAgentProperty 10
if(exists (select 1 from #ss where ss='NP') ...
or if it has an output parameter, then the call should be:
declare #ss varchar(10)
exec SP_CheckAgentProperty 10, #ss output
if(#ss='NP')
I'm trying to create a procedure in SQL Server 2008 that inserts data from a temp table into an already existing table. I think I've pretty much figured it out, I'm just having an issue with a loop. I need the row count from the temp table to determine when the loop should finish.
I've tried using ##ROWCOUNT in two different ways; using it by itself in the WHILE statement, and creating a variable to try and hold the value when the first loop has finished (see code below).
Neither of these methods have worked, and I'm now at a loss as to what to do. Is it possible to use ##ROWCOUNT in this situation, or is there another method that would work better?
CREATE PROCEDURE InsertData(#KeywordList varchar(max))
AS
BEGIN
--create temp table to hold words and weights
CREATE TABLE #tempKeywords(ID int NOT NULL, keyword varchar(10) NOT NULL);
DECLARE #K varchar(10), #Num int, #ID int
SET #KeywordList= LTRIM(RTRIM(#KeywordList))+ ','
SET #Num = CHARINDEX(',', #KeywordList, 1)
SET #ID = 0
--Parse varchar and split IDs by comma into temp table
IF REPLACE(#KeywordList, ',', '') <> ''
BEGIN
WHILE #Num > 0
BEGIN
SET #K= LTRIM(RTRIM(LEFT(#KeywordList, #Num - 1)))
SET #ID = #ID + 1
IF #K <> ''
BEGIN
INSERT INTO #tempKeywords VALUES (#ID, #K)
END
SET #KeywordList = RIGHT(#KeywordList, LEN(#KeywordList) - #Num)
SET #Num = CHARINDEX(',', #KeywordList, 1)
--rowcount of temp table
SET #rowcount = ##ROWCOUNT
END
END
--declaring variables for loop
DECLARE #count INT
DECLARE #t_name varchar(30)
DECLARE #key varchar(30)
DECLARE #key_weight DECIMAL(18,2)
--setting count to start from first keyword
SET #count = 2
--setting the topic name as the first row in temp table
SET #t_name = (Select keyword from #tempKeywords where ID = 1)
--loop to insert data from temp table into Keyword table
WHILE(#count < #rowcount)
BEGIN
SET #key = (SELECT keyword FROM #tempKeywords where ID = #count)
SET #key_weight = (SELECT keyword FROM #tempKeywords where ID = #count+2)
INSERT INTO Keyword(Topic_Name,Keyword,K_Weight)
VALUES(#t_name,#key,#key_weight)
SET #count= #count +2
END
--End stored procedure
END
To solve the second part of your problem:
INSERT INTO Keyword(Topic_Name,Keyword,K_Weight)
SELECT tk1.keyword, tk2.keyword, tk3.keyword
FROM
#tempKeywords tk1
cross join
#tempKeywords tk2
inner join
#tempKeywords tk3
on
tk2.ID = tk3.ID - 1
WHERE
tk1.ID = 1 AND
tk2.ID % 2 = 0
(This code should replace everything in your current script from the --declaring variables for loop comment onwards)
You could change:
WHILE(#count < #rowcount)
to
WHILE(#count < (select count(*) from #tempKeywords))
But like marc_s commented, you should be able to do this without a while loop.
I'd look at reworking your query to see if you can do this in a set based way rather than row by row.
I'm not sure I follow exactly what you are trying to achieve, but I'd be tempted to look at the ROW_NUMBER() function to set the ID of your temp table. Used with a recursive CTE such as shown in this answer you could get an id for each of your non empty trimmed words. An example is something like;
DECLARE #KeywordList varchar(max) = 'TEST,WORD, ,,,LIST, SOME , WITH, SPACES'
CREATE TABLE #tempKeywords(ID int NOT NULL, keyword varchar(10) NOT NULL)
;WITH kws (ord, DataItem, Data) AS(
SELECT CAST(1 AS INT), LEFT(#KeywordList, CHARINDEX(',',#KeywordList+',')-1) ,
STUFF(#KeywordList, 1, CHARINDEX(',',#KeywordList+','), '')
union all
select ord + 1, LEFT(Data, CHARINDEX(',',Data+',')-1),
STUFF(Data, 1, CHARINDEX(',',Data+','), '')
from kws
where Data > ''
), trimKws(ord1, trimkw) AS (
SELECT ord, RTRIM(LTRIM(DataItem))
FROM kws
)
INSERT INTO #tempKeywords (ID, keyword)
SELECT ROW_NUMBER() OVER (ORDER BY ord1) as OrderedWithoutSpaces, trimkw
FROM trimKws WHERE trimkw <> ''
SELECT * FROM #tempKeywords
I don't fully understand what you are trying to acheive with the second part of your query , but but you could just build on this to get the remainder of it working. It certainly looks as though you could do what you are after without while statements at least.