How to use integer variable in Dynamic Query - sql

I have created the below dynamic query to check if length of particular attribute is more than 50 or not. I am trying to make the length size also dynamic but getting below error.
Msg 207, Level 16, State 1, Line 7
Invalid column name '50'.
The query I came up with is as below. I am pretty new to SQL and trying to resolve this error. Thanks!
--Rule A.5.Summary :- Length
/* The 'DECLARE' statements below are used to
define standard test parameters and their datatypes. The values for these
parameters will be updated for each of the DQ dimensions/KDEs being tested */
DECLARE #DQ_DIMENSION_RULE VARCHAR(100)
DECLARE #RULE_NO VARCHAR(100)
DECLARE #TABLE_NAME VARCHAR(100)
DECLARE #DATA_ATTRIBUTE VARCHAR(100)
DECLARE #LENGTH_SIZE INT
/*The 'SET' statements below are used to
assign values to each of the test parameters declared above.
The values will depend on the DQ dimension/KDE being tested.*/
SET #DQ_DIMENSION_RULE = 'Accuracy - Negative Values'
SET #RULE_NO = 'A.4'
SET #TABLE_NAME = 'TRANSACTIONS'
SET #DATA_ATTRIBUTE = 'TRANSACTIONID'
SET #LENGTH_SIZE = 50
DECLARE #sql nvarchar(max) = N'
SELECT
' + QUOTENAME(#DQ_DIMENSION_RULE, '''') + N' AS [DQ_Dimension_Rule],
' + QUOTENAME(#RULE_NO, '''') + N' AS [Rule_No],
' + QUOTENAME(#TABLE_NAME, '''') + N' AS [Table Name],
' + QUOTENAME(#DATA_ATTRIBUTE, '''') + N' AS [Column Name],
case when SUM(CASE WHEN LEN(' + QUOTENAME(#DATA_ATTRIBUTE) + N') >' + QUOTENAME(#LENGTH_SIZE) + N' THEN 1 ELSE 0 END) > 0 then ''Y'' else ''N'' end as [Potential Issue(Y/N)]
FROM ' + QUOTENAME(#TABLE_NAME)
-- The data from 'SELECT' statement is being inserted into the summary table
--INSERT INTO summary
EXEC sp_executesql #sql;

You should not put QUOTENAME() around the integer values, the integers are not table names that you need to quote, etc.
You should just convert the integers to strings, without quotes...
DECLARE #sql nvarchar(max) = N'
SELECT
' + QUOTENAME(#DQ_DIMENSION_RULE, '''') + N' AS [DQ_Dimension_Rule],
' + QUOTENAME(#RULE_NO, '''') + N' AS [Rule_No],
' + QUOTENAME(#TABLE_NAME, '''') + N' AS [Table Name],
' + QUOTENAME(#DATA_ATTRIBUTE, '''') + N' AS [Column Name],
case when SUM(CASE WHEN LEN(' + QUOTENAME(#DATA_ATTRIBUTE) + N') >' + CAST(#LENGTHSIZE AS NVARCHAR(MAX)) + N' THEN 1 ELSE 0 END) > 0 then ''Y'' else ''N'' end as [Potential Issue(Y/N)]
FROM ' + QUOTENAME(#TABLE_NAME)
QUOTENAME(#LENGTHSIZE) => CAST(#LENGTHSIZE AS NVARCHAR(MAX))

Better than injecting it, parametrise it:
DECLARE #DQ_DIMENSION_RULE VARCHAR(100);
DECLARE #RULE_NO VARCHAR(100);
DECLARE #TABLE_NAME sysname; --Correct data type for object names
DECLARE #DATA_ATTRIBUTE VARCHAR(100);
DECLARE #LENGTH_SIZE INT;
SET #DQ_DIMENSION_RULE = 'Accuracy - Negative Values';
SET #RULE_NO = 'A.4';
SET #TABLE_NAME = 'TRANSACTIONS';
SET #DATA_ATTRIBUTE = 'TRANSACTIONID';
SET #LENGTH_SIZE = 50;
DECLARE #sql nvarchar(max) = N'
SELECT
' + QUOTENAME(#DQ_DIMENSION_RULE, '''') + N' AS [DQ_Dimension_Rule],
' + QUOTENAME(#RULE_NO, '''') + N' AS [Rule_No],
N' + QUOTENAME(#TABLE_NAME, '''') + N' AS [Table Name],
' + QUOTENAME(#DATA_ATTRIBUTE, '''') + N' AS [Column Name],
case when SUM(CASE WHEN LEN(' + QUOTENAME(#DATA_ATTRIBUTE) + N') > #LENGTH_SIZE THEN 1 ELSE 0 END) > 0 then ''Y'' else ''N'' end as [Potential Issue(Y/N)]
FROM ' + QUOTENAME(#TABLE_NAME) + N';';
EXEC sys.sp_executesql #sql, N'#LENGTH_SIZE int', #LENGTH_SIZE;
I've also changed the data type of your dynamic object and ensured that it the literal string is injected with a nvarchar notation character too.

Related

Conversion failing when applying PIVOTED SCRIPT

i am having a data conversion issues when applying this un-pivoted script on my dynamic columns SSRS report .every time SSRS Report is executed the header columns are supposedly to change .
IF OBJECT_ID('tempdb..##Temp') IS NOT NULL
DROP TABLE ##Temp;
DECLARE #ObjectName VARCHAR(100) = '[AdventureWorks2016].[Sales].[SalesOrderHeader]' ,
#KeyColumn VARCHAR(100) = '[SalesOrderID]';
DECLARE #ColumnNames NVARCHAR(MAX)= '' ,
#Values NVARCHAR(MAX)= '' ,
#SQL NVARCHAR(MAX)= '';
SELECT #ColumnNames += ',
' + QUOTENAME([ShipDate]) ,
#Values += ',
' + QUOTENAME([ShipDate]) + ' = CONVERT(VARCHAR(100), '
+ QUOTENAME([ShipDate]) + ')'
FROM [AdventureWorks2016].[Sales].[SalesOrderHeader]
WHERE '[Sales].[SalesOrderHeader]' = #ObjectName
AND [ShipDate] <> #KeyColumn;
SET #SQL = N'Select * into ##Temp
FROM
(
SELECT ' + #KeyColumn + #Values + '
FROM ' + #ObjectName + '
) AS DRV
UNPIVOT
(
Value FOR ColumnName IN (' + STUFF(#ColumnNames, 1, 1, '') + ')
) AS UnPVT;';
EXEC sp_executesql #SQL;
SELECT *
FROM ##Temp

Conversion failed when converting the varchar value ' and f.FUNCTION_ID= CAST(' to data type int

I am trying to make the procedure where I can get the data from MS SQL. Here I am getting the error
Msg 245, Level 16, State 1, Procedure GET_FUNCTIONS, Line 15 [Batch Start Line 33]
Conversion failed when converting the varchar value ' and f.FUNCTION_ID in '' to data type int.
CREATE procedure [dbo].[GET_FUNCTIONS]
#Function_Id int,
#EntityId int,
#OrderBy varchar(10)
as
begin
declare #Sql nvarchar(max)
if(#Function_Id=0 AND #EntityId=0)
set #Sql = 'select
f.Function_Code,f.FUNCTION_ID,f.EntityId,be.ENTITY_SHORT_NAME,f.FUNCTION_NAME,
f.FUNCTION_DESC,f.CREATED_DATE,f.MODIFIED_DATE from FUNCTIONS f
inner join BusinessEntity be on f.EntityId=be.ID
WHERE f.ACTIVE=1 '
if(#Function_Id!=0)
set #Sql += ' and f.FUNCTION_ID in ''' + #Function_Id + ''''
if(#EntityId!=0)
set #Sql += ' and f.EntityId = cast('+convert(varchar(12) ,#EntityId)+') '
set #Sql += ' order by FUNCTION_ID '+ #OrderBy
print #Sql
end
GO
Thanks everyone for your answers. I have got the answer by my own.
I have removed if(#Function_Id=0 AND #EntityId=0) and changed the data type of #Function_Id and #EntityId to varchar(100), so solved all errors.
I'm, making a few guesses here, which I add some comments about, however, this should be what you are after. I firstly ensure that I parametrise the values, but also validate and quote the value of #OrderBy:
CREATE PROCEDURE [dbo].[GET_FUNCTIONS] #Function_Id int =NULL, --Instead of passing 0as "select all" use NULL
#EntityId int = NULL, --Instead of passing 0as "select all" use NULL
#OrderBy nvarchar(4) --guessing this is mean to be ASC or DESC?
AS
BEGIN
IF #OrderBy NOT IN (N'ASC','DESC')
--Error is not ASC or DESC
THROW 51473, N'#OrderBy can only have a value of ''ASC'' or ''DESC''.',16; --51473 was a random error number; you can use one that is appropriate for your environment.
DECLARE #SQL nvarchar(MAX),
#CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SET #SQL = N'SELECT f.Function_Code,' + + #CRLF +
N' f.FUNCTION_ID,' + + #CRLF +
N' f.EntityId,' + + #CRLF +
N' be.ENTITY_SHORT_NAME,' + + #CRLF +
N' f.FUNCTION_NAME,' + + #CRLF +
N' f.FUNCTION_DESC,' + + #CRLF +
N' f.CREATED_DATE,' + + #CRLF +
N' f.MODIFIED_DATE' + + #CRLF +
N'FROM FUNCTIONS f' + + #CRLF +
N' INNER JOIN BusinessEntity be ON f.EntityId = be.ID' + + #CRLF +
N'WHERE f.ACTIVE = 1';
IF (#Function_Id IS NOT NULL)
SET #SQL = #SQL + #CRLF + N' AND f.FUNCTION_ID = #Function_Id'
IF (#EntityId IS NOT NULL)
SET #SQL = #SQL + #CRLF + N' AND f.EntityId = #EntityId'
SET #SQL = #SQL + #CRLF +
N'ORDER BY F.FUNCTION_ID ' + QUOTENAME(#OrderBy) + N';'
--PRINT #SQL; --Uncomment for debugging.
EXEC sp_executesql #SQL, N'#Function_Id int, #EntityId int', #Function_Id, #EntityId;
END;
GO

Update column by looping through rows

I have four columns in a table ID, Longitude, Latitude, and SpatialData. I have the first three columns filled out for every row, but I need to enter in the SpatialData for each row. I can currently manually update the SpatialData column by using the below query:
update GioMap set SpatialData = 'Point(-74.009506 40.70602)' Where ID =1
From here I have to keep manually updating the Longitude, Latitude and ID for every row. I am using this code to try to loop through all of the rows and update the table that way:
DECLARE #LoopC INT = 1, #MaxOID INT,
#Long nVarchar(32), #Lat nVarchar(32),#Col1 nVarchar(11)
SET #MaxOID = (select count(*) from GioMap)
Set #Col1 = 'SpatialData'
WHILE(#LoopC <= #MaxOID)
BEGIN
SET #Long = (Select Longitude FROM GioMap where ID = #LoopC)
SET #Lat = (Select Latitude FROM GioMap where ID = #LoopC)
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
EXEC sp_executesql #sql
SET #LoopC = #LoopC + 1
END
When I run this code I keep getting this error message:
Msg 245, Level 16, State 1, Line 13
Conversion failed when converting the nvarchar value 'update [ISSHXI1].[dbo].[GioMap] set SpatialDat = 'Point(-74.0095 40.706)' Where ID = ' to data type int.
I don't understand why it would be trying to convert it to an int?
You could do something like this:
UPDATE GioMap SET SpatialData = 'Point(' + cast(Longitude as varchar) + ' ' + cast(Latitude as varchar) + ')'
I think the way you are doing it is bad, but that's not technically what you asked.
It is trying to convert it to an int because you are adding a varchar to an int. You need to change this:
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' +
'''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' +
#LoopC)
to this
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' +
'''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' +
Cast(#LoopC as varchar))
The point statement paramaters need to be seperated by a comma.
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
Instead of:
#Long + ' ' + #Lat + ')
try
#Long + ',' + #Lat + ')
To see what is being executed you can try adding a print statement:
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
print #sql
EXEC sp_executesql #sql
Also why do you parans around strings you are assigning? Its confusing in TSQL. While it works it is jarring and unusual.
Instead of:
SET #MaxOID = (select count(*) from GioMap)
try
SET #MaxOID = 'select count(*) from GioMap'
Later in the code you do both parens and quotes. The great, great majority of TSQL developers just use single quotes.
Ben

An expression of non-boolean expression in dynamic sql concatenated string

declare #SqlString nvarchar(max);
declare #tmpTable nvarchar(50) = '#tmpTable', #tmpColumn nvarchar(50) = 'Name'
declare #ConcatString nvarchar(max);
set #SqlString = N'Create Table ' + #tmpTable + '(' + #tmpColumn + ' nvarchar(255));
'
+ '
while(select top(1) ' + #tmpColumn + ' from ' + #tmpTable + ')
begin
if(ISNULL(#ConcatString, 0) = 0)
begin
set #ConcatString += (select top(1) ' + #tmpColumn + ' from ' + #tmpTable +') ' + '
end
else
begin
set #ConcatString += '','' + (select top(1) ' + #tmpColumn + ' from ' + #tmpTable +')
end
end'
--print #SqlString
EXEC sp_executesql #SqlString, N'#ConcatString nvarchar(max)', #ConcatString = 0
select #ConcatString as ConcatString
Msg 4145, Level 15, State 1, Line 4
An expression of non-boolean type specified in a context where a condition is expected, near 'begin'.

Dynamic sql with CASE expression

SET #SQL =
'SELECT
CaseStatus =
CASE Level1Status
WHEN 1100 THEN ''Case Submitted to QC''
WHEN 1200 THEN ''Pending QC''
WHEN 1400 THEN ''Passed QC''
END,
I'm currently having problems with the dynamic sql/case expression above , as I can't seem to put strings inside dynamic sql, does anyone happen to have a solution to fixing this
EDIT
AS
BEGIN
DECLARE #SQL nvarchar(4000)
SET #SQL =
'SELECT
CaseStatus =
CASE Level1Status
WHEN 1100 THEN ''Case Submitted to QC''
WHEN 1200 THEN ''Pending QC''
WHEN 1400 THEN ''Passed QC''
END,
CaseStartDateTime,
CaseEndDateTime,
StatusName,
Cell_NameDescription,
QCAnalystName,
AnalystName,
Upload_Datetime,
Requesting_Entity,
Legal_Entity_TypeDescription,
HighPriorityDescription,
DD_Level_RequiredDescription,
CountryDscr,
Maintable.KYCCaseId AS KYCCaseId
FROM
UACTc75760ab10784b51b585f082d4b25223 AS MI,
UACT175e55161660402692a53a4cdeb89bd6 AS MainTable,
UACT5996d6e5151245cab24e4e76e3e53540 AS Statuses,
UACTde5f05df6c5f4872a1e57b3cf8368301 AS AddressDetails
WHERE
(
MI.CaseStartDateTime BETWEEN ' + quotename(convert(varchar(10), #CaseStartDateTime, 120), '''') + ' AND ' + quotename(convert(varchar(10), #CaseEndDateTime, 120), '''') +
' OR
MI.CaseEndDateTime BETWEEN ' + quotename(convert(varchar(10), #CaseStartDateTime, 120), '''') + ' AND ' + quotename(convert(varchar(10), #CaseEndDateTime, 120), '''') +
' )
AND
MI.KYCCase_Id = MainTable.KYCCaseId'
IF #StatusName IS NOT NULL AND ltrim(rtrim(#StatusName)) != N''
SET #SQL = #SQL + '
AND
Statuses.SourceStatus = MainTable.Level1Status
AND
Statuses.StatusName = ' + quotename(#StatusName, '''')
IF #CountryDscr IS NOT NULL AND ltrim(rtrim(#CountryDscr)) != N''
SET #SQL = #SQL + '
AND
AddressDetails.CountryDscr = ' + quotename(#CountryDscr, '''')
IF #CellDscr IS NOT NULL AND ltrim(rtrim(#CellDscr)) != N''
SET #SQL = #SQL + '
AND
MainTable.Cell_NameDescription = ' + quotename(#CellDscr, '''')
IF #QCAnalystName IS NOT NULL AND ltrim(rtrim(#QCAnalystName)) != N''
SET #SQL = #SQL + '
AND
MainTable.QCAnalystName = ' + quotename(#QCAnalystName, '''')
IF #AnalystName IS NOT NULL AND ltrim(rtrim(#AnalystName)) != N''
SET #SQL = #SQL + '
AND
MainTable.AnalystName = ' + quotename(#AnalystName, '''')
IF #RequestingEntity IS NOT NULL AND ltrim(rtrim(#RequestingEntity)) != N''
SET #SQL = #SQL + '
AND
MainTable.Requesting_Entity = ' + quotename(#RequestingEntity, '''')
IF #EntityType IS NOT NULL AND ltrim(rtrim(#EntityType)) != N''
SET #SQL = #SQL + '
AND
MainTable.Legal_Entity_TypeDescription = ' + quotename(#EntityType, '''')
IF #HighPriority IS NOT NULL AND ltrim(rtrim(#HighPriority)) != N''
SET #SQL = #SQL + '
AND
MainTable.HighPriorityDescription = ' + quotename(#HighPriority, '''')
IF #DDLevelRequired IS NOT NULL AND ltrim(rtrim(#DDLevelRequired)) != N''
SET #SQL = #SQL + '
AND
MainTable.DD_Level_RequiredDescription = ' + quotename(#DDLevelRequired, '''')
EXEC sp_executesql #SQL
This is the entire code, The error I'm getting is
Msg 156, Level 15, State 1, Line 32
Incorrect syntax near the keyword 'Case'.
This is working fine .
Create Table #Level1Status(Id int identity ,Level1Status int)
Insert INto #Level1Status(Level1Status) values(1100),(1200),(1400)
Declare #SQL Nvarchar(Max)
SET #SQL =
'SELECT
CaseStatus =
CASE Level1Status
WHEN 1100 THEN ''Case Submitted to QC''
WHEN 1200 THEN ''Pending QC''
WHEN 1400 THEN ''Passed QC''
END from #Level1Status';
Exec SP_ExecuteSQL #SQL
Since you are concatenate your #SQL string with local variable "#xxx", in case any of thease may null, It want give any output so use ISNULL() or COALESCE() at concatenation with all local vaiable you used.