space in a select statement in dynamic query - sql

I have a dynamic query like this :
SET #str_Query = 'SELECT SIM.Item_ID,
SIM.Item_Description,
SU.Short_Description AS Unit,
SIM.Std_Lead_Time,'+
'' ''+' AS Last_Purchase_Rate
FROM FKMS_Item_Master AS SIM
INNER JOIN FKMS_STP_Units SU
ON SIM.Item_Purchase_Unit=SU.Unit_Id' +
' WHERE ' + #str_Condition +
' AND SIM.Location_Id =' + CAST(#aint_Location_Id AS VARCHAR(10)) +
' AND SIM.Item_Deleted =0
AND SIM.Approved_On IS NOT NULL'
+' ORDER BY SIM.Item_Description'
I want to retrieve space as Last_Purchase_Rate
It is showing syntax error in the portion of '' ''+' AS Last_Purchase_Rate
when I execute this query.
If I print this dynamic query, query seems correct. It shows as AS Last_Purchase_Rate with space before AS. Please help.

I would write
...SIM.Std_Lead_Time, '' '' AS Last_Purchase_Rate...
instead of
...SIM.Std_Lead_Time,'+'' ''+' AS Last_Purchase_Rate...

Why not use NULL instead of space and then handle the result in your app?
I.e.,
SET #str_Query = 'SELECT SIM.Item_ID,
SIM.Item_Description,
SU.Short_Description AS Unit,
SIM.Std_Lead_Time,
NULL AS Last_Purchase_Rate, -- and so on.
You could also use CHAR(32):
SET #str_Query = 'SELECT SIM.Item_ID,
SIM.Item_Description,
SU.Short_Description AS Unit,
SIM.Std_Lead_Time,
CHAR(32) AS Last_Purchase_Rate, -- and so on.

You did not escape all quotes.
A working version of your statement would be
SET #str_Query = 'SELECT SIM.Item_ID,
SIM.Item_Description,
SU.Short_Description AS Unit,
SIM.Std_Lead_Time,'
+ ''' '''
+ ' AS Last_Purchase_Rate
FROM FKMS_Item_Master AS SIM
INNER JOIN FKMS_STP_Units SU
ON SIM.Item_Purchase_Unit=SU.Unit_Id' +
' WHERE ' + #str_Condition +
' AND SIM.Location_Id =' + CAST(#aint_Location_Id AS VARCHAR(10)) +
' AND SIM.Item_Deleted =0
AND SIM.Approved_On IS NOT NULL'
+' ORDER BY SIM.Item_Description'
but I find that with a little reformatting, the error is easier to spot
SET #str_Query =
'SELECT SIM.Item_ID '
+ ', SIM.Item_Description '
+ ', SU.Short_Description AS Unit '
+ ', SIM.Std_Lead_Time '
+ ', '' ''' + ' AS Last_Purchase_Rate '
+ 'FROM FKMS_Item_Master AS SIM '
+ ' INNER JOIN FKMS_STP_Units SU '
+ ' ON SIM.Item_Purchase_Unit=SU.Unit_Id '
+ ' WHERE ' + #str_Condition
+ ' AND SIM.Location_Id = ' + CAST(#aint_Location_Id AS VARCHAR(10))
+ ' AND SIM.Item_Deleted =0 '
+ ' AND SIM.Approved_On IS NOT NULL '
+ ' ORDER BY SIM.Item_Description '

Try using tsql function SPACE(1)

Related

Cannot resolve collation conflict for column 2 in SELECT statement

The following SQL statement is giving me a "Cannot resolve collation conflict for column 2 in SELECT statement." error.
I can tell the culprit is RTRIM(TABLE_ONE.AUT_NAME) because the statement works if I remove it. However, if I use COLLATE before it I get a syntax error. How can I resolve this issue? thanks
SELECT NRS, RTRIM(STR_DES) + ', ' + RTRIM(TABLE_TWO.TO_NA)
AS FT_NAME, KEYWORDS = CAST(NRS AS VARCHAR(15)) + ' ' + RTRIM(STR_DES) + '' +
RTrim(TABLE_THREE.LC_NAME) + ' ' + RTRIM(TABLE_TWO.TO_NA) + '' +
RTRIM(TABLE_ONE.AUT_NAME)
From NSG_STR INNER Join TABLE_TWO On TABLE_TWO.TN_UID = NSG_STR.TN_UID INNER Join
TABLE_THREE ON TABLE_THREE.LCT_UID = NSG_STR.LCT_UID INNER JOIN TABLE_ONE ON TABLE_ONE.AUT_UID = NSG_STR.AUT_UID
WHERE CAST(NRS As VARCHAR(15)) + ' ' + RTRIM(STR_DES) + ' ' + RTRIM(TABLE_THREE.LC_NAME) + ' ' + RTRIM(TABLE_TWO.TO_NA) + '' +
RTrim(TABLE_ONE.AUT_NAME) COLLATE DATABASE_DEFAULT LIKE '%3%'
Run this before your code:
declare #db_collation nvarchar(100) = (select cast( databasepropertyex(db_name(),'collation') as nvarchar) )
declare #altertablequery nvarchar(500)
set #altertablequery = '
alter table NSG_AUTHORITY alter column AUTHORITY_NAME nvarchar (max) collate '+#db_collation+';'
exec (#altertablequery)
A better answer is to simply add "COLLATE DATABASE_DEFAULT" to your query, which requires no schema modifications at all.
SELECT USRN, RTRIM(STREET_DESCRIPTOR) + ', ' + RTRIM(NSG_TOWN.TOWN_NAME)
AS FEATURE_NAME, KEYWORDS = CAST(USRN AS VARCHAR(15)) + ' ' + RTRIM(STREET_DESCRIPTOR) + '' +
RTrim(NSG_LOCALITY.LOCALITY_NAME) + ' ' + RTRIM(NSG_TOWN.TOWN_NAME) + '' +
RTRIM(NSG_AUTHORITY.AUTHORITY_NAME) COLLATE DATABASE_DEFAULT
From NSG_STREET INNER Join NSG_TOWN On NSG_TOWN.TOWN_UID = NSG_STREET.TOWN_UID INNER Join
NSG_LOCALITY ON NSG_LOCALITY.LOCALITY_UID = NSG_STREET.LOCALITY_UID INNER JOIN NSG_AUTHORITY ON NSG_AUTHORITY.AUTHORITY_UID = NSG_STREET.AUTHORITY_UID
WHERE CAST(USRN As VARCHAR(15)) + ' ' + RTRIM(STREET_DESCRIPTOR) + ' ' + RTRIM(NSG_LOCALITY.LOCALITY_NAME) + ' ' + RTRIM(NSG_TOWN.TOWN_NAME) + '' +
RTrim(NSG_AUTHORITY.AUTHORITY_NAME) COLLATE DATABASE_DEFAULT LIKE '%3%' COLLATE DATABASE_DEFAULT
You simply use it everywhere it's referenced, and with everything you compare against (to be safe).

when using "SELECT varname = something + something etc. I cannot then do "WHERE varname = ..."

I have:
SELECT KEYWORDS = CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(SD) + ' ' + RTRIM(NL.LOCALITY_NAME) + ' ' +
RTRIM(NT.TOWN_NAME) + ' ' + RTRIM(NA.AUTHORITY_NAME)
That gives me what looks like a column, but is not:
I want to have it so my code only selects the rows from KEYWORDS that match whatever the user is typing. Normally, if KEYWORDS was a column, I would write:
SELECT .... WHERE KEYWORDS = '%whateverTheUserIsTyping%'
but I cannot because keywords is not a real column and it is telling me that it does not exist.
How do I get around this? thanks
The column alias KEYWORDS isn't visible to the SQL Engine at the time that the WHERE clause is evaluated. You can just repeat your CAST statment, though.
SELECT
KEYWORDS = CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(STREET_DESCRIPTOR) + ' ' + RTRIM(NSG_LOCALITY.LOCALITY_NAME) + ' ' +
RTRIM(NSG_TOWN.TOWN_NAME) + ' ' + RTRIM(NSG_AUTHORITY.AUTHORITY_NAME)
FROM yourTable
WHERE
CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(STREET_DESCRIPTOR) + ' ' + RTRIM(NSG_LOCALITY.LOCALITY_NAME) + ' ' +
RTRIM(NSG_TOWN.TOWN_NAME) + ' ' + RTRIM(NSG_AUTHORITY.AUTHORITY_NAME)
LIKE '%whateverTheUserIsTyping%'
You can use derived table with an alias (here Q) and get the result from that by filtering in WHERE clause:
SELECT Q.KEYWORDS FROM (
SELECT KEYWORDS = CAST(USRN AS VARCHAR(15)) + ' ' +
RTRIM(STREET_DESCRIPTOR) + ' ' + RTRIM(NSG_LOCALITY.LOCALITY_NAME) + ' ' +
RTRIM(NSG_TOWN.TOWN_NAME) + ' ' + RTRIM(NSG_AUTHORITY.AUTHORITY_NAME)
) AS Q
WHERE Q.KEYWORDS LIKE '%whateverTheUserIsTyping%'
Because you can't use the column alias in the WHERE clause as you mentioned. Also instead of the KEYWORDS = '%whateverTheUserIsTyping%', you can use LIKE operator.

Correct escaping for Where clause in dynamic procedure

I am pretty new to dynamic procedure and am trying to use something like the below in a Where clause there.
I have covered the rest of the procedure but have an issue with the below.
What would the correct escaping (quotes) look like in this case to cover the variable inputs? Also, I am not sure how to handle the part "R.#searchCategory" as here I need to add the "R.".
SQL Query :
WHERE ' + #selection + ' = ''closed'' AND (R.logStatus LIKE ''%Completed%'' OR R.logStatus LIKE ''%Closed%'')
AND
(
(
' + #searchCategory + ' <> ''dateRec'' AND R.' + #searchCategory + ' LIKE ''%' + #searchTerm + '%''
)
OR
(
' + #searchCategory + ' = ''dateRec'' AND CAST(R.dateRec AS DATE) LIKE ''%' + #searchTerm + '%''
)
)
Make your life easier and use REPLACE and QUOTENAME
SET #sql = ...
'WHERE #selection = ''closed'' ' +
' AND (R.logStatus LIKE ''%Completed%'' ' +
' OR R.logStatus LIKE ''%Closed%'') ' +
' AND ( ' +
' (#searchCategoryText <> ''dateRec'' ' +
' AND R.#searchCategoryColumn LIKE ''%'' + #searchTerm + ''%'' ' +
' ) ' +
' OR ' +
' (#searchCategoryText = ''dateRec'' ' +
' AND CAST(R.dateRec AS DATE) LIKE ''%'' + #searchTerm + ''%'' ' +
' ) ' +
' ) ';
SET #sql = REPLACE(#sql, '#selection', QUOTENAME(#selection, ''''));
SET #sql = REPLACE(#sql, '#searchCategoryText', QUOTENAME(#searchcategory, ''''));
SET #sql = REPLACE(#sql, '#searchCategoryColumn', QUOTENAME(#searchcategory));
SET #sql = REPLACE(#sql, '#searchTerm', QUOTENAME(#searchTerm, ''''));
you have to separate out each whenever you add your variable like
WHERE ' + #selection +'= ''closed'' AND (R.logStatus LIKE ''%Completed%'' OR R.logStatus LIKE ''%Closed%'')
AND
(
(
' + #searchCategory +' <> ''dateRec'' AND R.' + #selection +'#searchCategory LIKE ''%' + ' + #searchTerm+'%''
)
OR
(
' + #searchCategory +'= ''dateRec'' AND CAST(R.dateRec AS DATE) = ' + #searchTerm +'
)
)
Still you got error then make direct query on which you make dynamic latter. i.e.
declare #searchCategory nvarchar(100) = 'abc'
select * from table where colname = #searchCategory
Run this and check the result properly come, now you just add into string here and your query ready to execute , simple.

Dynamic WHERE clause in SQL Server 2008 R2

I have a table which I'm querying using a dynamic conditional WHERE clause. I'm looking a best approach to get simple WHERE condition when all columns are null or when some columns has some value.
I tried something like this:
SET #CONDITIONS = CASE
WHEN #VEHICLE_TYPE_NAME IS NULL
THEN ' ISNULL(A.VEHICLE_TYPE_NAME,'''') = ISNULL(A.VEHICLE_TYPE_NAME,'''') '
ELSE ' A.VEHICLE_TYPE_NAME = ''' + #VEHICLE_TYPE_NAME + ''''
END + ' ' + CASE
WHEN CAST(#PRODUCT_ID AS VARCHAR(MAX)) IS NULL
THEN ' AND ISNULL(A.PRODUCT_ID, ''-1'') = ISNULL(A.PRODUCT_ID, ''-1'') '
ELSE ' AND A.PRODUCT_ID = ''' + CAST(#PRODUCT_ID AS VARCHAR(MAX)) + ''''
END + ' ' + CASE
WHEN CAST(#CAPABILITY_ID AS VARCHAR(MAX)) IS NULL
THEN ' AND ISNULL(A.CAPABILITY_ID,''-1'') = ISNULL(A.CAPABILITY_ID,''-1'') '
ELSE ' AND A.CAPABILITY_ID = ''' + CAST(#CAPABILITY_ID AS VARCHAR(MAX)) + ''''
END + ' ' + CASE
WHEN #SPONSOR_FIRM_ID IS NULL
THEN ' AND ISNULL(A.SPONSOR_FIRM_ID,'''') = ISNULL(A.SPONSOR_FIRM_ID,'''') '
ELSE ' AND A.SPONSOR_FIRM_ID = ''' + #SPONSOR_FIRM_ID + ''''
END + ' ' + CASE
WHEN #CLIENT_FIRM_ID IS NULL
THEN ' AND ISNULL(A.CLIENT_FIRM_ID,'''') = ISNULL(A.CLIENT_FIRM_ID,'''') '
ELSE ' AND A.CLIENT_FIRM_ID = ''' + #CLIENT_FIRM_ID + ''''
END + ' ' + CASE
WHEN CAST(#DIST_PLATFORM_ID AS VARCHAR(MAX)) IS NULL
THEN ' AND ISNULL(A.DIST_PLATFORM_ID,''-1'') = ISNULL(A.DIST_PLATFORM_ID,''-1'') '
ELSE ' AND A.DIST_PLATFORM_ID = ''' + CAST(#DIST_PLATFORM_ID AS VARCHAR(MAX)) + ''''
END + ' ' + CASE
WHEN #RR_INTERNAL_NUMBER IS NULL
THEN 'AND ISNULL(A.RR_INTERNAL_NUMBER,'''') = ISNULL(A.RR_INTERNAL_NUMBER,'''') '
ELSE ' AND A.RR_INTERNAL_NUMBER = ''' + #RR_INTERNAL_NUMBER + ''''
END
You don't need the part where your parameter is null. You can simply build up a dynamic SQL for each part
IF #PRODUCT_ID IS NOT NULL
#CONDITIONS = #CONDITIONS + ' AND A.PRODUCT_ID = ''' + CAST(#PRODUCT_ID AS VARCHAR(MAX)) + ''''
Why do you need dynamic SQL?
WHERE (#VEHICLE_TYPE_NAME IS NULL OR A.VEHICLE_TYPE_NAME = #VEHICLE_TYPE_NAME)
AND (#PRODUCT_ID IS NULL OR A.PRODUCT_ID = #PRODUCT_ID)
...

Building dynamic self join statements in SQL

Declare #alias as varchar(10)
set #alias = 'fk2'
insert into #Queries(Query, ExecuteOrder)
select top 1 'delete ' + fk1.TableFrom + ' from ' + fk1.TableFrom
+ ' join ' + #alias.TableFrom + ' on ' + fk1.TableFrom+'.'+fk1.FK_Column + ' = ' + fk2.TableFrom + '.ID'
+ ' join ' + fk3.TableFrom + ' on ' + fk2.TableFrom+'.'+fk2.FK_Column + ' = ' + fk3.TableFrom + '.ID'
+ ' join ' + fk4.TableFrom + ' on ' + fk3.TableFrom+'.'+fk3.FK_Column + ' = ' + fk4.TableFrom + '.ID'
+ ' Where ' + fk4.TableFrom + '.' + fk4.FK_Column + ' = ' + #value
,#i
from #FK fk1
join #fk As #alias on #alias.TableFrom = fk1.TableTo
join #fk fk3 on fk3.TableFrom = fk2.TableTo
join #fk fk4 on fk4.TableFrom = fk3.TableTo
I am joining a table to itself to build a resulting query to then be executed from the temp table being inserted into. I am currently specifying the amount of joins but would like to build them dynamically based on another integer value being passed in. The amount of joins will correlate with this integer value. The only problem is I need a unique Alias for each join to then be used above to build the resulting query. Is it possible to use a dynamic Alias as to eliminate the need to hardcode the Alias for each join?