I have this condition in my stored procedure to determine which WHERE clause to use:
IF (#communityDesc = 'All Areas')
BEGIN
WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (SELECT name
FROM dbo.splitstring(#communityDesc))
AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
END
ELSE
BEGIN
WHERE V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
END
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
but I get a long list of errors:
Msg 156, Level 15, State 1, Procedure GetProductionSchedule, Line 256
Incorrect syntax near the keyword 'WHERE'.
Msg 156, Level 15, State 1, Procedure GetProductionSchedule, Line 256
Incorrect syntax near the keyword 'AND'.
What am I doing wrong?
You can't separate out a query by a conditional. You'd have to do something like.
if(#communityDesc = 'All Areas')
BEGIN
SELECT * FROM Table
WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC IN
(select name from dbo.splitstring(#communityDesc))
AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
END
else
BEGIN
SELECT * FROM Table
WHERE V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
END
Your other option would be to conditionally build the query:
DECLARE #Query VARCHAR(1000)
SET #Query = 'SELECT * FROM TABLE '
if(#communityDesc = 'All Areas')
BEGIN
SET #Query = #Query +
'WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (select name from dbo.splitstring(#communityDesc)) AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE() '
END
ELSE
SET #Query = #Query +
'WHERE V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE() '
BEGIN
SET #Query = #Query + 'ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END'
END
exec sp_executesql #Query
Or just put all of the logic into a single WHERE
SELECT *
FROM [Table]
WHERE V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
AND (#communityDesc = 'All Areas'
OR V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (SELECT name
FROM dbo.splitstring(#communityDesc)))
Im not sure you have your logic right.. You probably want to split #communityDesc if it's not equal to All Areas I've updated my answer to reflect what I mean.
You should probably write it like this
-- your preceding select statements followed by this line
SELECT * FROM V_CONSTAT_ACTUAL_DATES
WHERE
(
#communityDesc = 'All Areas' AND
V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (select name from dbo.splitstring(#communityDesc)) AND
V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
)
OR
( #communityDesc <> 'All Areas' AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
)
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
This can also be simplified as
-- your preceding select statements followed by this line
SELECT * FROM V_CONSTAT_ACTUAL_DATES
WHERE
V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
AND NOT
(
#communityDesc <> 'All Areas' OR
V_CONSTAT_ACTUAL_DATES.AREA_DESC not IN (select name from dbo.splitstring(#communityDesc))
)
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
which can be further optimized like below
-- your preceding select statements followed by this line
SELECT * FROM V_CONSTAT_ACTUAL_DATES
LEFT JOIN (select name from dbo.splitstring(#communityDesc) Temp
ON Temp.name=V_CONSTAT_ACTUAL_DATES.AREA_DESC
WHERE
V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
AND NOT
(
#communityDesc <> 'All Areas' OR Temp.Name is null
)
)
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
Related
I'm getting the following error
Conversion failed when converting date and/or time from character string
I can't get it to run properly please help me, here is my code (don't shame my loop i just need it to work).
The thing is i have a closed list with contracts IDs and a table with different dates and dates called #PERIODO it contains datetime type.
WHILE (SELECT TOP 1 FECHA1 FROM #PERIODO) > 0
BEGIN
SET #MES_ANTERIOR = (SELECT TOP 1 FECHA1 FROM #PERIODO ORDER BY FECHA1 ASC)
SET #MES_EN_CURSO = (SELECT TOP 1 B.FECHA1 FROM (SELECT TOP 2 A.FECHA1 FROM #PERIODO A ORDER BY FECHA1 ASC ) B ORDER BY B.FECHA1 DESC)
SET #MES_3 = (SELECT TOP 1 FECHA3 FROM #PERIODO ORDER BY FECHA1 ASC)
SET #MES_4 = (SELECT TOP 1 B.FECHA3 FROM (SELECT TOP 2 A.FECHA3 FROM #PERIODO A ORDER BY FECHA3 ASC ) B ORDER BY B.FECHA3 DESC)
SET #MES_ANT = LEFT(CONVERT(VARCHAR(8),#MES_ANTERIOR,112),8) -- SELECT #MES_ANT
SET #MES_CURR = LEFT(CONVERT(VARCHAR(8),#MES_EN_CURSO,112),8) -- SELECT #MES_CURR
EXEC('IF OBJECT_ID(''WORK.DBO.OPERACIONES_ABIF_'+#MES_CURR+''', ''U'') IS NOT NULL
DROP TABLE WORK.DBO.OPERACIONES_ABIF_'+#MES_CURR+' ')
SET #SQL1 = 'SELECT DISTINCT
A.*
INTO WORK.DBO.OPERACIONES_ABIF_'+#MES_CURR+'
FROM BDGESTION.DBO.BASE_RIESGOS_PROD_ALTAIR_'+#MES_CURR+' A WHERE '
SET #SQL2 = ' A.NUM_OPERACION IN (
SELECT
B.NUM_CONTRATO
FROM (
SELECT NUM_CONTRATO
FROM
( SELECT * FROM #OPER WHERE FECHA_INICIO IS NOT NULL) H
WHERE H.FECHA_INICIO < CAST(CONVERT(VARCHAR(12),'+#MES_EN_CURSO+',23) AS VARCHAR )
AND H.FECHA_INICIO >= CAST(CONVERT(VARCHAR(12),'+#MES_ANTERIOR+',23) AS VARCHAR )
) B
WHERE
B.NUM_CONTRATO IS NOT NULL ) '
EXEC (#SQL1 + #SQL2)
DELETE FROM #PERIODO
WHERE FECHA1 = #MES_ANTERIOR
END
The problem would appear to be these lines:
WHERE H.FECHA_INICIO < CAST(CONVERT(VARCHAR(12), ' + #MES_EN_CURSO + ', 23) AS VARCHAR)
Presumably, you want the cast() outside the aggregation:
WHERE H.FECHA_INICIO < ' + CONVERT(VARCHAR(12), #MES_EN_CURSO + ', 23) + '
However, I don't recommend this as a solution. The correct solution is to pass the value in as a parameter. Your query is too complex (and messy) for me to attempt that. You should look at the documentation for sp_executesql on how to properly construct dynamic SQL with parameters.
I think you should print #SQL2 as you go through the loop so you can see the incorrect value.
It would be helpful to show how you declare #MES_EN_CURSO and declare #MES_ANTERIOR.
I have a parameter that dynamically generates UNION ALL
depends on the input.
SELECT #CMD +=N'
SET NOCOUNT ON;
SELECT
COUNT(CASE WHEN RFRD.QueuTypeID=4
THEN RFRD.QueuTypeID
END) RequiredaQueue
,COUNT(DISTINCT RFRD.LeadDocumentID) AS Repeat,CONCAT('''+RF+''' ,'' '') AS RiskFactorID
FROM FCT.RiskMng_fact_RiskFactorResultDetails AS RFRD
UNION ALL
SELECT
COUNT(CASE WHEN RFRD.QueuTypeID=4
THEN RFRD.QueuTypeID
END) RequiredaQueue
,COUNT(DISTINCT RFRD.LeadDocumentID)AS Repeat,CONCAT('''+RF+''' ,''*'') AS RiskFactorID
FROM FCT.RiskMng_fact_RiskFactorResultDetails AS RFRD'
--------------
FROM #cte RF
EXEC sys.sp_executesql #CMD
at the end i want to connect them all into one long UNION, so i added a UNION ALL in the end:
SELECT #CMD +=N'
SET NOCOUNT ON;
SELECT
COUNT(CASE WHEN RFRD.QueuTypeID=4
THEN RFRD.QueuTypeID
END) RequiredaQueue
,COUNT(DISTINCT RFRD.LeadDocumentID) AS Repeat,CONCAT('''+RF+''' ,'' '') AS RiskFactorID
FROM FCT.RiskMng_fact_RiskFactorResultDetails AS RFRD
UNION ALL
SELECT
COUNT(CASE WHEN RFRD.QueuTypeID=4
THEN RFRD.QueuTypeID
END) RequiredaQueue
,COUNT(DISTINCT RFRD.LeadDocumentID)AS Repeat,CONCAT('''+RF+''' ,''*'') AS RiskFactorID
FROM FCT.RiskMng_fact_RiskFactorResultDetails AS RFRD'
--------------
+' UNION ALL ' <-----------------------
FROM #cte RF
EXEC sys.sp_executesql #CMD
after it runs, the last UNION ALL is Needless,
and i get errors:
ON OU.ID = RFRD.Entity_OrganizationUnitID
INNER JOIN #Entity_OrganizationUnitTypeIDs OUT
ON OUT.ID = RFRD.Entity_OrganizationUnitTypeID
WHERE RFRD.EntityTypeID = 1055
and RFRD.riskfactorid IN(6249,6102)
AND RFRD1.ID IS NULL
UNION ALL
Msg 156, Level 15, State 1, Line 118
can anyone suggest how can i remove only the last UNION ALL?
maybe i should not add a UNION AL at the end?
Thanks
At the end you need to remove it by
set #CMD = substring(#CMD,1,len(#CMD)-9)
EXEC sys.sp_executesql #CMD
The UNION ALL command takes two parameters, the table before and the table after the UNION ALL command.
So it should allways have the form
SELECT col1,col2 FROM A
UNION ALL
SELECT col3 as col1,col4 as col2 FROM B
When you are concatenating your SELECT statements, why not check to see if the existing string is empty, and add the UNION ALL then only if it is required, for example:
SELECT #CMD = #CMD +
CASE WHEN #CMD = '' THEN '' ELSE ' UNION ALL ' END +
'SELECT ... '
Then you won't be in the situation where you'll have to strip anything back out again.
Below is a piece of my stored proc.
I am getting error as invalid object MyCount, Please let me know where am going wrong
;With MyCount AS
(
Select DispatchToRegionId ,FolderNo, row_number() OVER(ORDER BY FolderNo DESC) as Row
from tblTransite where FolderNo = #VAL group by DispatchToRegionId,FolderNo
)
select #cnt = COUNT(*) from MyCount
if #cnt = 0
begin
set #InvalidFolderNo = #VAL
print 'cnt -' + cast(#cnt as varchar(max) ) + 'invalid folder - ' + cast(#InvalidFolderNo as varchar(max) )
return
end
select #Region =( Select top 1 DispatchToRegionId from MyCount
order by Row desc )
MSDN clearly states the following about the scope of a Common Table Expression (CTE):
A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement
Once you have run the first select query, you can no longer use the CTE for your next one. You may want to consider storing the data in a temporary table or table variable if you want to access it in multiple queries.
MyCount is available only for the first query after it. Try to select all you need in this one query:
;With MyCount AS
(
Select DispatchToRegionId ,FolderNo, row_number() OVER(ORDER BY FolderNo DESC) as Row
from tblTransite where FolderNo = #VAL group by DispatchToRegionId,FolderNo
)
SELECT
#cnt = (select COUNT(*) from MyCount),
#Region =( Select top 1 DispatchToRegionId from MyCount
order by Row desc )
if #cnt = 0
begin
set #InvalidFolderNo = #VAL
print 'cnt -' + cast(#cnt as varchar(max) ) + 'invalid folder - ' + cast(#InvalidFolderNo as varchar(max) )
return
end
I have written this query to get data for special keyword:
ALTER procedure [dbo].[GetAllSpecialPaperTags]
#PKeyword nvarchar(200)
as
begin
select
Papers.PID, Papers.PTitle, Papers.PaperSummary
from
PaperKeywords
left join
PaperTags on PaperKeywords.PKeyID = PaperTags.PKeyID
left join
Papers on PaperTags.PID = Papers.PID
where
PaperKeywords.PKeyword = #PKeyword
end
I want use this article for custom paging : Custom Paging using SQL Server Stored Procedure
I wrote this query but I'm getting an error:
create procedure [dbo].[GetAllSpecialPaperTags]
#PageIndex INT = 1
,#PageSize INT = 10
,#RecordCount INT OUTPUT
,#PKeyword nvarchar(200)
as
BEGIN
SET NOCOUNT ON;
SELECT ROW_NUMBER() OVER
(
ORDER BY [Papers.PID] ASC
)AS RowNumber
,Papers.PID , Papers.PTitle , Papers.PaperSummary
INTO #Results
from PaperKeywords
left join PaperTags on PaperKeywords.PKeyID = PaperTags.PKeyID
left join Papers on PaperTags.PID = Papers.PID where PaperKeywords.PKeyword = #PKeyword
SELECT #RecordCount = COUNT(*)
FROM #Results
SELECT * FROM #Results
WHERE RowNumber BETWEEN(#PageIndex -1) * #PageSize + 1 AND(((#PageIndex -1) * #PageSize + 1) + #PageSize) - 1
DROP TABLE #Results
end
Error:
Msg 207, Level 16, State 1, Procedure GetAllSpecialPaperTags, Line 11
Invalid column name 'Papers.PID'.
Why?
This is your order by expression:
ORDER BY [Papers.PID] ASC
It is looking for a column named in its entirety "Papers.PID". It is not looking for the PID column in Papers. Just drop the braces:
ORDER BY Papers.PID ASC
I have a SQL Server table-valued function which is created by me I have pasted the create script below
CREATE FUNCTION [dbo].[getTableFromString]
(
#String AS nvarchar(max)
)
RETURNS #ReturnTable TABLE ( StringValues nvarchar(10) )
AS begin
if (SELECT CHARINDEX(',', #String)) = 0
begin
insert into #ReturnTable (StringValues) values (subString(#String,1,len(#String)));
end
else
begin
while (SELECT CHARINDEX(',', #String)) > 0
begin
insert into #ReturnTable (StringValues) values (subString(#String,1,CHARINDEX(',', #String)-1));
set #String = subString(#String,CHARINDEX(',', #String)+1,len(#String));
if (SELECT CHARINDEX(',', #String)) = 0
begin
insert into #ReturnTable (StringValues) values (subString(#String,1,len(#String)));
end
end
end
return ;
end
and I am using this function like below
Select sum(NetSales)
from vwxsalesall
where Company = 'rs'
and storecode = (select cPrimaryStockRoomCode from CompanyMaster.CompanyProfileDetail where cCompanyNo = 'rs' and cSecondaryStockRoomCode = 'R01B')
and trandate >= '2012-01-01'
and trandate <= '2012-01-31'
and (
brand in (
select StringValues from dbo.getTableFromString(
select vIncludedBrandCodes
from StockRoomTargetData.MonthlyTarget
where cCompanyNo = 'rs'
and cSecondaryStockRoomCode = 'R01B'
and nYear = 2012
and nMonth = 8
)
)
)
Unfortunately I am getting this error
Msg 156, Level 15, State 1, Line 10
Incorrect syntax near the keyword 'select'.
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near ')'.
please help me
You need to add another set of parenthesis around subquery, for instance
select StringValues from dbo.getTableFromString(( { your-subquery }))
^ ^
(parenthesis added)
First set of parenthessis syntactically belong to TVF invocation, and second denote a subquery.
And now your query:
Select sum(NetSales)
from vwxsalesall
where Company = 'rs'
and storecode = (select cPrimaryStockRoomCode from CompanyMaster.CompanyProfileDetail where cCompanyNo = 'rs' and cSecondaryStockRoomCode = 'R01B')
and trandate >= '2012-01-01'
and trandate <= '2012-01-31'
and (
brand in (
select StringValues from dbo.getTableFromString((
select vIncludedBrandCodes
from StockRoomTargetData.MonthlyTarget
where cCompanyNo = 'rs'
and cSecondaryStockRoomCode = 'R01B'
and nYear = 2012
and nMonth = 8
))
)
)