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

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'.

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

How to use integer variable in Dynamic Query

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.

String literal in SQL query field

I'd like to do a stuff command in string literal query and it give some error
The query without string literal working:
SELECT apGr.*, 'Name: ' + apGr.GroupDesc + ' | Group: ' + apGr.GroupName GroupFull ,
abc = STUFF
(
(
SELECT ',' + appGrMn.Email
FROM APP_GroupManager As appGrMn
-- You only want to combine rows for a single ID here:
WHERE appGrMn.GroupId = apGr.GroupId
FOR XML PATH (''), TYPE
).value('.', 'varchar(max)')
, 1, 1, '')
FROM App_Group apGr
WHERE apGr.GroupId = 239
The query as string literal failed:
DECLARE #WhereQuery NVARCHAR(200) = ''
DECLARE #Query NVARCHAR(500)
SET #GroupId = 5
-- Insert statements for procedure here
IF(#GroupId IS NOT NULL)
BEGIN
PRINT(#GroupId)
SET #WhereQuery = 'WHERE apGr.GroupId = ' + #GroupId
END
ELSE IF (#SystemId IS NOT NULL)
BEGIN
SET #WhereQuery = 'WHERE apGr.SystemId = ' + #SystemId
END
ELSE IF (#GroupName IS NOT NULL)
BEGIN
SET #WhereQuery = 'WHERE apGr.GroupName = ''' + #GroupName + ''''
END
SET #Query = 'SELECT ''Name: '' + apGr.GroupDesc + '' | Group: '' + apGr.GroupName GroupFull ,
abc = STUFF
(
(
SELECT '','' + appGrMn.AdministratorMail
FROM APP_GroupManager As appGrMn
-- You only want to combine rows for a single ID here:
WHERE appGrMn.GroupId = apGr.GroupId
FOR XML PATH (''), TYPE
).value(''.'', varchar(max))
, 1, 1, '') ' +
'FROM App_Group apGr ' +
'JOIN T_SensitiveLevel AS tSen ON tSen.SensitiveLevelId = apGr.SensitiveLevelId ' + #WhereQuery
PRINT #Query
EXEC(#Query)
END
The printed query looks:
5
SELECT 'Name: ' + apGr.GroupDesc + ' | Group: ' + apGr.GroupName GroupFull ,
abc = STUFF
(
(
SELECT ',' + appGrMn.AdministratorMail
FROM APP_GroupManager As appGrMn
-- You only want to combine rows for a single ID here:
WHERE appGrMn.GroupId = apGr.GroupId
FOR XML PATH ('), TYPE
).value('.', varchar(max))
, 1, 1, ') FROM App_Group apGr JOIN T_SensitiveLevel AS tSen ON tSen.SensitiveLevelId = apGr.SensitiveLevelId WHERE apGr.GroupId = 2
It not append the #WhereQuery as it should and the error is:
Msg 102, Level 15, State 1, Line 20
Incorrect syntax near '.'.
Any help on this would be appreciated.
There were some '' related syntax error. instead of '' you need to use '''' when expecting ('') in output. Where clause is truncated since #query became larger then it's length(500). I have made some changes in the query please check:
DECLARE #WhereQuery NVARCHAR(200) = ''
DECLARE #Query NVARCHAR(2000)
declare #GroupId NVARCHAR(500)
declare #SystemId NVARCHAR(500)
declare #GroupName NVARCHAR(500)
set #GroupName='a'
SET #GroupId = 5
-- Insert statements for procedure here
IF(#GroupId IS NOT NULL)
BEGIN
PRINT(#GroupId)
SET #WhereQuery = 'WHERE apGr.GroupId = ' + #GroupId
END
ELSE IF (#SystemId IS NOT NULL)
BEGIN
SET #WhereQuery = 'WHERE apGr.SystemId = ' + #SystemId
END
ELSE IF (#GroupName IS NOT NULL)
BEGIN
SET #WhereQuery = 'WHERE apGr.GroupName = ''' + #GroupName + ''''
END
SET #Query = 'SELECT ''Name: '' + apGr.GroupDesc + '' | Group: '' + apGr.GroupName GroupFull ,
abc = STUFF
(
(
SELECT '','' + appGrMn.AdministratorMail
FROM APP_GroupManager As appGrMn
-- You only want to combine rows for a single ID here:
WHERE appGrMn.GroupId = apGr.GroupId
FOR XML PATH (''''), TYPE
).value(''.'', ''varchar(max)'')
, 1, 1, '''') ' +
'FROM App_Group apGr ' +
'JOIN T_SensitiveLevel AS tSen ON tSen.SensitiveLevelId = apGr.SensitiveLevelId ' + #WhereQuery +''
PRINT #Query
EXEC(#Query)

Dynamic SQL - Insert a variables via INSERT INTO x SELECT statement

I would like to ask how can I insert a variables into a table using INSERT INTO x SELECT statement via dynamic SQL.
I have following table:
|-------------------|-----------------|--------------|-----------------|
| TableName | ColName | Value | SQL_Statement |
|-------------------|-----------------|--------------|-----------------|
I get a content for Value column by this query:
INSERT INTO #ReturnTable(Value) SELECT TreeHolder FROM prm.Schm_Root WHERE ParentTreeHolderId = 'DD040D31-4591-4658-A02E-A6ED00AB64F2';
But I need to fill whole table. Please consider that other values are variables, not SQL queries.
SELECT #TableSchema = TableSchema FROM #TableNames WHERE Id = #Counter;
SELECT #TableName = TableName FROM #TableNames WHERE Id = #Counter;
SELECT #ColName = ColName FROM #TableNames WHERE Id = #Counter;
SET #SQL_Statement = 'SELECT ' + #ColName + ' FROM ' + #TableSchema + '.' + #TableName + ' WHERE ' + #ColName + ' = ' + '''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''' + ';';
Now I have this query that fills a table:
SET #SQL_String = N'INSERT INTO #ReturnTable SELECT
''' + #TableName + ''',
''' + #ColName + ''',
''' + #SQL_Statement + ''',
'' + Value + '',
(SELECT ' +
#ColName + '
FROM ' +
#TableSchema + '.' + #TableName + '
WHERE ' +
#ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) + '
'')';
EXECUTE sp_executesql #SQL_String
PRINT #SQL_String;
The thing I need is to rewrite this query from INSERT INTO ? VALUE to INSERT INTO ? SELECT format.
If I understand correctly, you want to insert SQL execute syntax string and it results in ReturnTable table.
I would let subquery SQL execute syntax save in a variable. because the will be more clear what you need to do.
Declare a new variable #SQL_excuteStatement variable to save your execute syntax.
the #SQL_Statement to carry the original SQL string.
set #SQL_Statement = 'SELECT ' + #ColName +
' FROM ' + #TableSchema + '.' + #TableName +
' WHERE ' + #ColName + ' = '+'''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''';
and use select ... from table instead of subquery in select
There is a sample for you.
DECLARE #SQL_String NVARCHAR(MAX)
DECLARE #TableSchema NVARCHAR(MAX)
DECLARE #TableName NVARCHAR(MAX)
DECLARE #ColName NVARCHAR(MAX)
DECLARE #Counter int = 1
DECLARE #SQL_Statement NVARCHAR(MAX)
DECLARE #GuidArgument INT = 1
CREATE TABLE TableNames(
ID INT,
TableSchema NVARCHAR(100),
TableName NVARCHAR(100),
ColName NVARCHAR(100)
);
CREATE TABLE ReturnTable(
TableName NVARCHAR(100),
ColName NVARCHAR(100),
SQL_Statement NVARCHAR(max),
value nvarchar(max)
);
INSERT INTO TableNames VALUES (1,'dbo','T','val');
CREATE TABLE T(val INT);
INSERT INTO T VALUES (1)
SELECT #TableSchema = TableSchema FROM TableNames WHERE Id = #Counter;
SELECT #TableName = TableName FROM TableNames WHERE Id = #Counter;
SELECT #ColName = ColName FROM TableNames WHERE Id = #Counter;
set #SQL_Statement = 'SELECT ' + #ColName +
' FROM ' + #TableSchema + '.' + #TableName +
' WHERE ' + #ColName + ' = '+ '''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''';
SET #SQL_String = N'INSERT INTO ReturnTable (TableName,ColName,SQL_Statement,value)
SELECT '''+ #TableName + ''','''+ #ColName + ''','''+ #SQL_Statement + '''' + ',' + QUOTENAME(#ColName) +
' FROM ' + QUOTENAME(#TableSchema) + '.' + QUOTENAME(#TableName) + '' +
' WHERE ' + #ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''';
EXECUTE sp_executesql #SQL_String
sqlfiddle
Note
I would suggest you use clear column after insert into
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;

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