Error when using single quote with sp_executesql - sql

I have the following SQL statement so that I can script out view creation using if not exists with sp_executesql but the statement is giving me errors due to the single quotes around 1 in my last where statement. Is there any way around this?
IF NOT EXISTS (SELECT * FROM SYS.objects WHERE NAME = 'vw_JeopardyAlertDetails' AND TYPE = 'V')
EXEC sp_executesql #statement = N'CREATE VIEW [dbo].[vw_JeopardyAlertDetails]
AS
SELECT Main.TicketNumber, TS.TicketStateDesc, Main.ApptEnd, ISNULL(C.FirstName, '') AS FirstName, ISNULL(C.LastName, '') AS LastName, ISNULL(Main.CustomerID, '')
AS CustomerID, Main.ApptID, Main.ID, Main.TicketType
FROM (SELECT s.TicketState, s.TicketID AS ID, s.ApptEnd, dbo.Ticket.TicketNumber, dbo.Ticket.TimeOpened, dbo.Ticket.CreatedBy, dbo.Ticket.ReportedBy,
dbo.Ticket.ModifiedBy, dbo.Ticket.ChangedBy, dbo.Ticket.Priority, dbo.Ticket.ServingArea, dbo.Ticket.StructureLink, dbo.Ticket.CustomerID,
dbo.Ticket.TicketCategory, dbo.Ticket.TicketCode, s.ApptStart, s.TicketType, s.CanReschedule, ISNULL(s.ID, 0) AS ApptID
FROM dbo.Schedule AS s INNER JOIN
dbo.Ticket ON s.TicketID = dbo.Ticket.ID
WHERE (s.TicketState IN
(SELECT DISTINCT TicketState
FROM dbo.AlertJeopardyTicketState
WHERE (IsJeopardyState = '1'))) AND (s.ApptEnd >= CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 111) + ' ' + dbo.GetJeopardyStartTime()))
AND (s.ApptEnd <= GETDATE())) AS Main LEFT OUTER JOIN
dbo.Customer AS C ON Main.CustomerID = C.ID LEFT OUTER JOIN
dbo.TicketStatus AS TS ON Main.TicketState = TS.ID
GO' ;
ELSE PRINT N'vw_JeopardyAlertDetails ALREADY EXISTS'
GO

You'll need to double up those quotes in your Sql #statement, e.g.
ISNULL(C.FirstName, '')
needs to be
ISNULL(C.FirstName, '''')
Simplified fiddle here

Related

How select all columns count of all tables by date

Today I have this query that returns all rows from all tables. But now I want to add a new column that would be the number of records in the last year. Most tables have a column called "DateInsert".
I have this:
SELECT
SCHEMA_NAME(t.[schema_id]) AS [SCHEMA],
OBJECT_NAME(p.[object_id]) AS [NOME_TABELA],
SUM(p.[rows]) AS [ROW_COUNT]
FROM [sys].[partitions] p
INNER JOIN [sys].[tables](NOLOCK) t ON p.[object_id] = t.[object_id]
WHERE p.[index_id] < 2
GROUP BY p.[object_id]
,t.[schema_id]
ORDER BY [ROW_COUNT] desc
How do i add a new column counting rows from the last year only?
Assuming, each table has DateInsert column. You can try using Dynamic SQL to prepare the count for each table from last year in one temporary table and then you can Join that temp table with your final query.
Something like this
Please note that, if any of your table dont have DateInsert Column, this query will fail. In order to look at list of tables, you can prepare the dynamic SQL for those tables only
DECLARE #SQLQuery NVARCHAR(MAX)
-- Preparing Dynamic SQL
SELECT #SQLQuery = STUFF(
(SELECT CONCAT('UNION SELECT ''', name ,''' AS [TableName], COUNT(1) AS [NoOfRowsFromLastYear] FROM ['
, name
, '] WITH (NOLOCK) WHERE YEAR(DateInsert) = (YEAR(GETDATE())-1)')
FROM [sys].[tables]
--WHERE name in ('TableName')
FOR XML PATH(''))
, 1, LEN('UNION '), ''
)
SELECT #SQLQuery = CONCAT('SELECT * INTO ##TableDetail FROM (', #SQLQuery, ') DataSet')
-- Check for table, if available, drop it
IF OBJECT_ID('tempdb..##TableDetail') IS NOT NULL DROP TABLE ##TableDetail;
-- Execute prepared query
EXECUTE sp_executesql #SQLQuery
-- Final Query with [ROW_COUNT_FROM_LAST_YEAR]
SELECT
SCHEMA_NAME(t.[schema_id]) AS [SCHEMA],
OBJECT_NAME(p.[object_id]) AS [NOME_TABELA],
SUM(p.[rows]) AS [ROW_COUNT],
td.NoOfRowsFromLastYear AS [ROW_COUNT_FROM_LAST_YEAR]
FROM [sys].[partitions] p
INNER JOIN [sys].[tables](NOLOCK) t ON p.[object_id] = t.[object_id]
INNER JOIN ##TableDetail td ON td.[TableName] = t.name
WHERE p.[index_id] < 2
GROUP BY p.[object_id]
,t.[schema_id]
,td.NoOfRowsFromLastYear
ORDER BY [ROW_COUNT] desc

How to use CTE with a T-SQL variable in SQL Server 2012?

I have a T-SQL variable containing another variable and I want to create a CTE based on this T-SQL variable.
I have tried printing the T-SQL variable in CTE but it is not working.
declare
#Hid nvarchar(5),
#mysql nvarchar(max)
set #Hid = 1
set #mysql = 'SELECT
CONVERT(DATE, GETDATE()) AS RptDate,
a.[key],
b.[Country], b.AcNumber, b.AcName,
DATEDIFF([d], a.[ItemDate], GETDATE()) AS [IAge],
[comment] AS OfficerComment,
(SELECT dbo.fnMgrCmnt(2,' + #Hid + ', a.rowid, 1)),
c.[firstname] + '' '' + c.[lastname] AS Modifiedby,
d.hubId,
'''' AS origin,
b.Authname,
CONVERT(DECIMAL(38, 2), a.amount) AS Amt,
b.AcOwner,
a.rowid AS rowid
FROM [dbo].[T_AccRecon] a
INNER JOIN [dbo].[VW_TMain] b ON a.[key] = b.[Key]
LEFT JOIN [dbo].[users] c ON a.Modifiedby = c.userId
LEFT JOIN [dbo].[Country] d ON b.Country = d.code
AND b.AcOwner = d.hubcode'
I want to create a CTE from this #mysql variable. I tried with
;WITH MY_CTE AS (#mysql)
but it is not working. What can be done for this?

Using 'in' in where clause returns Subquery returned more than 1 value

Query works fine when I run it normally with params. But it results in error as soon as I make it dynamic.
I am pretty new to SQL server.
When I print the query and run it, it works fine. But when run dynamically, it results in 'Subquery returned more than 1 value' error.
declare #query nvarchar(max) = 'Select *
into #tempFilteredData
from
(
SELECT td.UserId AS [EmployeeID],w.NAME AS [EmployeeName],at.ActivityCode AS [ActivityType],td.TargetAssigned,td.Mkt_TerritoryId,
wd.WeekName + ''('' + CONCAT((RTRIM(CONVERT(CHAR(3),DATENAME(day, wd.WeekStartDate),0))), ''-'', CONVERT(CHAR(3),DATENAME(month, wd.WeekStartDate),0),''To'',
(RTRIM(CONVERT(CHAR(3),DATENAME(day, wd.WeekEndDate),0))), ''-'', CONVERT(CHAR(3),DATENAME(month, wd.WeekEndDate),0)) + '')'' AS weekName
FROM tblTargetDetails td
INNER JOIN FMC_CMaster..Worker w ON td.UserId = w.[Personnel Number]
INNER JOIN FMC_CMaster..[vwAuthenticateUser] vw ON vw.UserId = td.UserId and vw.Blocked=''No'' and vw.Closed=''No'' AND vw.AssetCode = ''MPH''
INNER JOIN tblActivityType at ON at.ActivityTypeId = td.ActivityTypeId
INNER JOIN WeekDetails wd ON wd.WeekId = td.WeekId
LEFT JOIN FMC_CMaster..Marketing_Hierarchy_AMM_Level mrktHAL ON w.[Personnel Number] = mrktHAL.TMH_Code
WHERE td.CreatedBy = ''' + #LoggedInUserId + '''
AND mrktHAL.TMH_Code = ''' + #TMHCode + '''
) as p
pivot(
MAX([TargetAssigned]) for [WeekName] in ('+RTRIM(LTRIM(#columnName))+')
) as pvt
select * from #tempFilteredData where Mkt_TerritoryId IN ( '+(SELECT [MktTerritoryName] FROM #MktTerritoryNames)+' )'
PRINT (#query)
exec (#query)
I want to search for all the results that are being returned from #MktTerritoryNames in my temp table #tempFilteredData
There are no subqueries in the first query expression.
That leads to the second. What is this doing in the expression?
select * from #tempFilteredData where Mkt_TerritoryId IN ( '+(SELECT [MktTerritoryName] FROM #MktTerritoryNames)+' )'
I don't understand what this is even supposed to be doing. Perhaps you want to run it after you've created the temporary table. And, it doesn't need to be dynamic, just:
select *
from #tempFilteredData
where Mkt_TerritoryId IN (SELECT [MktTerritoryName] FROM #MktTerritoryNames);

Conversion failed when converting the nvarchar value '29449,29446,29450,29534' to data type int

I am create a stored procedure in SQL and I get the following error when I execute the query:
Conversion failed when converting the nvarchar value '11021,78542,12456,24521' to data type int.
Any idea why?
SELECT
A.Art_ID, A.Title
FROM
Art A
INNER JOIN
Iss I ON A.Iss_ID = I.Iss_ID
INNER JOIN
Sections S ON A.Section_ID = S.Section_ID
INNER JOIN
iPadSec IPS ON A.Sec_ID = IPS.Sec_ID
WHERE
A.Art_ID IN (SELECT CAST(Art_IDs AS int) /***error happens here***/
FROM Book_Art b
WHERE Sub_ID = 68)
AND I.Iss > dateadd(month, -13, getdate())
AND A.Active = 1
AND IPS.Active = 1
AND A.PDate <= getdate()
ORDER BY
PDate DESC, Art_ID DESC;
You cannot do what you want using in. First, it is a really bad idea to store ids in lists in strings. You should be using a junction table.
That said, sometimes this is necessary. You can rewrite this line of code as:
EXISTS (SELECT 1 /***error happens here***/
FROM Book_Art b
WHERE Sub_ID = 68 AND
',' + Art_IDs + ',' LIKE '%,' + cast(A.Art_ID as varchar(255)) + ',%'
)
However, the performance would generally be on the lousy side and there is little prospect of speeding this up without fixing the data structure. Use a junction table instead of a string to store lists.
Adding this line works for me.
declare #ids varchar(1000)
select #ids = art_ids from book_art where sub_id = #Sub_ID
EXECUTE ( 'SELECT A.Art_ID, A.Title'
+ ' FROM Art A'
+ ' INNER JOIN Iss I ON A.Iss_ID = I.Iss_ID'
+ ' INNER JOIN Sections S ON A.Section_ID = S.Section_ID'
+ ' INNER JOIN iPadSec IPS ON A.Sec_ID = IPS.Sec_ID'
+ ' WHERE A.Art_ID IN (' + #ids + ')'
+ ' AND I.Iss > dateadd(month, -13, getdate())'
+ ' AND A.Active = 1'
+ ' AND IPS.Active = 1'
+ ' AND A.PDate <= getdate()'
+ ' ORDER BY PDate DESC,'
+ ' Art_ID DESC;'
)
END
Thank you all for your help :)

How do I pivot query using UNION ALL

I have following table structure & below is the Query i am executing :-
Following are the tables :-
First Table :-
Second Table :-
SELECT Code, Fname, OTHINC1, OTHINC2
FROM (SELECT a.FieldName
,a.YearlyValue
,b.Code
,b.Fname
FROM [TaxOtherIncome] AS a
INNER JOIN [EmployeeDetail] AS b
ON a.EmployeeId = b.Id
WHERE a.EntryDate = '2014-12-01') x
PIVOT (MAX(YearlyValue) FOR FieldName IN (OTHINC1,OTHINC2)) p
Result i am getting :-
I also want Records from the Second table i mentioned above. So In my final Result Columns SUBFLD36
SUBFLD37 & House_Rent will be added.
As i am new to Pivot, Help me to modify above query to get expected results.
Consider you are inserting the result after your join to a temporary table which is the below
Declare a variable for getting the columns to pivot
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + [FIELD NAME] + ']',
'[' + [FIELD NAME] + ']')
FROM (SELECT DISTINCT [FIELD NAME] FROM #TEMP) PV
ORDER BY [FIELD NAME]
Now pivot it
DECLARE #query NVARCHAR(MAX)
SET #query = '
SELECT * FROM
(
SELECT * FROM #TEMP
) x
PIVOT
(
MAX([YEARLY VALUE])
FOR [FIELD NAME] IN (' + #cols + ')
) p
'
EXEC SP_EXECUTESQL #query
Click here to view the result
RESULT
You can try this:
SELECT Code, Fname, OTHINC1, OTHINC2, SUBFLD36, SUBFLD37, House_Rent
FROM (SELECT a.FieldName
,a.YearlyValue
,b.Code
,b.Fname
FROM [TaxOtherIncome] AS a
INNER JOIN [EmployeeDetail] AS b
ON a.EmployeeId = b.Id
WHERE a.EntryDate = '2014-12-01'
UNION
SELECT a.FieldName
,a.FieldValue AS YearlyValue
,a.EmployeeCode AS Code
,b.Fname
FROM SecondTable AS a
INNER JOIN [EmployeeDetail] AS b
ON a.EmployeeId = b.Id
WHERE EntryDate = '2014-12-01') x
PIVOT (MAX(YearlyValue) FOR FieldName IN (OTHINC1, OTHINC2, SUBFLD36, SUBFLD37, House_Rent)) p