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

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.

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

using CASE in SQL with update statement

I am trying to write a case statement something like this. Can someone help with the syntax
UPDATE A
CASE WHEN ATTDESC = 'ABC' THEN SET A.DESC = PG.VAL + ' - ' + LD.DESC + ' - ' + GH.PL3NAME
WHEN ATTDESC = 'DEF' THEN SET A.DESC = PG.VAL + ' - ' + LD.DESC + ' - ' + GH.PL3NAME
END
FROM ATTR A, PRODUCT PG, Global GH, Look LD
A CASE expression doesn't control flow; it returns a single value. So something like this:
...
SET [DESC]=CASE [ATTDESC]
WHEN 'ABC' THEN PG.VAL + ' - ' + LD.DESC + ' - ' + GH.PL3NAME
WHEN 'DEF' THEN PG.VAL + ' - ' + LD.DESC + ' - ' + GH.PL3NAME
ELSE [DESC]
END
FROM
...

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?

OLEDB Jet 4.0 SQL Character Limit

I am attempting to generate lines for an SDF (Space Delimited File). I am creating these lines from a DBASE IV DBF file using an OLEDB adapter with extended properties DBASEIV to get at the data. My data column output is 425 characters long after padding, I am placing this into a datagridview in VB.NET to display it.
However when I run my query, while it seems to execute correctly the resultant field is restricted to 256 characters. The longest individual field I am reading is 35 characters and I am returning a dataset with 2 fields, the barcode and the SDF line. As I understand it OLEDB Jet 4.0 tries to guess the type based on the first 8 rows, however as all rows are equal length for the data column (425 chars) I don't get why it is choosing the smaller field type. I assume it is because my field is a generated one using string concatenation. I have included the horrible SQL at the bottom of this question. So my question is how can I get the full 425 character output? Or is there a way I can specify the datatype for my own field as memo?
SELECT scan,
RIGHT('0000000000000' + trim(cstr(scan)), 13) +
LEFT(trim(cstr(name)) + ' ', 35) +
LEFT(trim(cstr(name)) + ' ', 16) +
' ' +
' ' +
' ' +
'1 ' +
'0.00 ' +
'0.00 ' +
'1' +
'0.00 ' +
'0.01 ' +
'0.00 ' +
'F' +
'2' +
'0.00 ' +
'0.00 ' +
' ' +
' ' +
' ' +
'SALS' +
' ' +
' ' +
LEFT(trim(cstr(plof)) + ' ', 13) +
' ' +
' ' +
'0.00 ' +
'0.00 ' +
'0.00 ' +
'F' +
'T' +
'001' +
' ' +
'T' +
'01' +
' ' +
' ' +
' ' +
' ' +
'F' +
'F' +
' ' +
' ' +
'0 ' +
'0.00 ' +
' ' +
'0 ' +
'0.00 ' +
'0.00 ' +
'0.00 ' +
'0.00 ' +
'1 ' +
'1 ' +
'1 ' +
'0.00 ' +
'0.00 ' +
'0.00 ' +
'0.00 ' +
'0.00 ' +
'0.00 ' +
' ' +
' ' +
' '
as STTEMPLINE
from salus where cstr(scan) in (select distinct cstr(scan) from nonscan)
Thanks in advance for any help.
This is a known issue where data types are guessed based on data in the first few rows.
See this post...
Load Excel sheet into DataTable but only the first 256 chars per cell are imported,
Also, see this post for an explanation of how OLEDB deals with mixed data types...
http://social.msdn.microsoft.com/Forums/pl-PL/csharplanguage/thread/0404d003-5bfb-44f9-8e6b-aebdfce24875

space in a select statement in dynamic query

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)