Parameterizing an SQL query which uses the NOT LIKE, " ^ " wildcard? - sql-server-2008

How can I parameterize the following query? (By the way I'm using a full text indexed table, hence the CONTAINS())
SELECT * FROM Table WHERE CONTAINS(Column, 'cat OR dog')
and ((column NOT LIKE '%[^ cat OR dog]%'));
This didn't work:
DECLARE #term1 VARCHAR(10);
DECLARE #term2 VARCHAR(10);
SET #term1 = 'cat';
SET #term2 = 'dog';
SET #term3 = #term1 + ' ' + 'OR' + ' ' + #term2;
SET #term4 = '[^ #term1 OR #term2 ]' ;
SELECT * FROM table WHERE CONTAINS(column, #term3) <--up to this point works
AND (column NOT LIKE '%[#term4]%'); <--this part doesn't include the second term (#term2)
If you'd like to fiddle with this on your end, my Full Text Indexed table looks like:
animalListID AnimalsList
1 cat dog
2 cat
3 cat dog bird
(basically i need the parameterized version of the SELECT statement which returns the rows with 'cat dog' and 'cat' and NOT 'cat dog bird')
**This is a VERY oversimplified version of my data, but the question is an exact match of the concept I'm trying to achieve. The table will have millions of rows, and many terms in each row.

You should do
SET #term4 = '[^ ' + #term1 + ' OR ' + #term2 + ' ]';
and
column NOT LIKE '%' + #term4 + '%'
Alternatively, you could initialize #term4 to also include the % signs:
SET #term4 = '%[^ ' + #term1 + ' OR ' + #term2 + ' ]%';
and then simplify the LIKE statement to:
column NOT LIKE #term4

Related

How to remove specific number in string that is in random order?

Lets say that I have data rows that look like this:
+----------------------------+
+ test_table +
+----+--------+--------------+
+ id + word + updated_word +
+----+--------+--------------+
+ 1 + g00gle + ggle +
+ 2 + bread0 + bread +
+ 3 + 0bject + bject +
+ 4 + d0d0 + dd +
+-------------+--------------+
What statement could I use to take out the zeroes in the word column, so that it looks like the updated_word column? I thought of using substring, but didn't know how to proceed after that.
try:
UPDATE test_table
SET word = REPLACE(word, '0', '');
replace the 2nd blank '' with anything you want to change with.

SQL Server separate: FirstName, MiddleName and LastName

Good day!
I get a "Varchar" which is the full name of a client, and need to split this "varchar" as:
"FirstName MidleName MiddleNameTwo LastName "
Need to enter the "FirstName" on "Col1"
Need to enter the "MiddleName, MiddleNameTwo in" col2 "
Need to enter the "LastName" in "Col3"
Thanks for your help!
You Should use subqueries for this task
INSERT INTO names(firstname, middlename, lastname)
SELECT substringfunctionofyours(name), substringfunctionofyours(name),
substringfunctionofyours(name) FROM namefield
keep in mind this is just a dummy query it won't work if you use it like this
Can you change the input method to 4 separate fields ?
If you can't, then implement a specific delimeter between the different parts of the string ?
In cases where the last name is built with 2 words, there is no deterministic way of processing the string if the delimeter is [space] or any other character like '-' or ' which are common in names.
Using a delimeter like '|' :
Declare #FullName varchar(100) = 'FirstName|MidleName|MiddleNameTwo|LastName'
Print 'FirstName = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName1 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName2 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'LastName = ' + #FullName
This will also work if you don't have one of the parts, as long as you maintain the structure.
Declare #FullName varchar(100) = 'FirstName|MidleName||LastName'
Print 'FirstName = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName1 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'MiddleName2 = ' + Substring(#FullName,1,charindex('|',#FullName)-1)
SELECT #FullName = Substring(#FullName,charindex('|',#FullName)+1,len(#fullName))
Print 'LastName = ' + #FullName
Let say you have a name like this "ABC DEF GHI"
now you want First Name, Middle Name and last Name From this string.
Here We Go
Select
Substring(Cast('ABC DEF GHI' as nvarchar),0,charindex(' ',Cast('ABC DEF GHI' as nvarchar))) as Col1,
Substring(Cast('ABC DEF GHI' as nvarchar),charindex(' ',Cast('ABC DEF GHI' as nvarchar)),4)as Col2,
Substring(Cast('ABC DEF GHI' as nvarchar),8,charindex(' ',Cast('ABC DEF GHI' as nvarchar)))as Col3
Note: This is MSSQL SERVER Query and Substring Function is Built in in MSSQL SERVER

Extracting Number From String SQL

I have a normal SQL statement:
SELECT VALUE_ID, UF_CRM_TASK FROM b_uts_tasks_task
Now this returns a a different field everytime but they take the form of the following:
a:1:{i:0;s:7:"CO_2012";} or a:1:{i:0;s:5:"CO_12";} or a:1:{i:0;s:7:"CO_2017";}
Basically they're different everytime. What I need is to just get the number after the CO_ part. I have tried TRIM but because everything changes in the leading and trailing section I don't think this would work.
I have looked on Stack Overflow for a while and cannot find it. I know how to do it in PHP:
$data = $row['UF_CRM_TASK'];
$companyID = substr($data, strpos($data, "CO_") + 1);
$newCompanyID = preg_replace('/[^0-9.]+/', '', $companyID);
But not SQL. Thanks in advance
In MYSQL is a bit ugly:
/*SUBSTRING_INDEX BASED ON CO_ AND THE LAST " - in 2 SUBSTRINGS*/
SELECT `VALUE_ID`, SUBSTRING_INDEX(SUBSTRING_INDEX(`UF_CRM_TASK`, 'CO_', -1), '"', 1) AS `COMPANY_ID` FROM `b_uts_tasks_task`
In PHP you can just unserialize():
$data = unserialize($row['UF_CRM_TASK']);
$companyID = str_replace('CO_', '', $data[0]);
eg:
$data = unserialize('a:1:{i:0;s:5:"CO_12";}');
echo str_replace('CO_', '', $data[0]);
//==> 12
You need to use CharIndex and SubString (Microsoft SQL) or
This is the sample code I made for my Microsoft SQL server:
declare #companyIdString varchar(50) = 'a:1:{i:0;s:7:"CO_2012";}'
print 'Company ID in a string: ' + #companyIdString
print 'Find first position: ' + Cast(charindex('"CO_', #companyIdString) as varchar(2))
print 'Locate the second position (the last "): ' + Cast(charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) as varchar(2))
print 'Extracted Company Id: ' + substring(#companyIdString,charindex('"CO_', #companyIdString)+4, charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) - charindex('"CO_', #companyIdString) - 4)
select
#companyIdString as CompanyIdString,
substring(#companyIdString,charindex('"CO_', #companyIdString)+4, charindex('"', #companyIdString, charindex('"CO_', #companyIdString)+4) - charindex('"CO_', #companyIdString) - 4) as CompanyId
I also made the same code on a mySQL server:
set #companyIdString := 'a:1:{i:0;s:7:"CO_2012";}';
select
#companyIdString as CompanyIdString,
substring_index(substring_index(substring_index(#companyIdString, '"', 2), '"', -1), '_', -1) as CompanyId
The substring_index starts by locating the second " (string is now a:1:{i:0;s:7:"CO_2012), then it searches backward with the -1 to locate the first " (string is now CO_2012). And then it searches backward for the underscore (string is now 2012).

How come this geometry point does not intersect with the polygon?

How come this geometry point does not intersect with the polygon? I know for a fact that the point exists in the given polygon. Any reason why it returns 0?
DECLARE #point geometry
DECLARE #poly geometry
SET #point = geometry::STGeomFromText('POINT (-79.393967 43.640056)', 4326)
DECLARE #minY varchar(20) = N'-79.37776573850101'
DECLARE #maxY varchar(20) = N'-79.41055306149906'
DECLARE #minX varchar(20) = N'43.63590433545648'
DECLARE #maxX varchar(20) = N'43.64460037532088'
DECLARE #boundingRect varchar(250)
SET #boundingRect = 'POLYGON((' + #minX + ' ' + #minY + ', ' +
#maxX + ' ' + #minY + ', ' +
#maxX + ' ' + #maxY + ', ' +
#minX + ' ' + #maxY + ', ' +
#minX + ' ' + #minY + '))'
SET #poly = geometry::STGeomFromText(#boundingRect, 4326)
SELECT #point.STIntersects(#poly)
I'm not familiar with this SQL notation, so I may be way off base, but I see that your X values seem to be associated with latitude 43N, and Y with longitude 79W. However, your POINT entries might be reversed?
Just a thought: When does a point intersect with a polygon? If it lies INSIDE the polygon? No. Only if it lies directly on one of the edges of the polygon, right?
Try this: Intersect a point with the polygon, which is lying directly on one of the edges of the polygon. If it returns else then 0 you have your answer.
The point should be declared as:
SET #point = geometry::STGeomFromText('POINT (43.640056 -79.393967)', 4326)
Then the Intersect shows the result you're expecting: 1

Computed Column with relationships

I have a table, MapLocation, which has a column and two relationships with tables that have a field that really need to be displayed as a single concatenated value. I was thinking this was a perfect case for a computed column, but not sure how to go about it.
MapLocation MaoNo Section
_____________________ _____________________ _____________________
MapNoId MapNoId SectionId
SectionId MapNumber (int) Section (int)
Identifier (nvarchar)
LocationName (nvarchar)
LocationName = "MapNUmber - SectionNumber - Identifier"
ex: 20 - 03 - SW4
How would I write that? I haven't done much with computed columns or concatenating in SQL.
Edit:
I need an actual computed column that is automatically updated, im looking for the formula. Or is this more of a function/trigger? Its possible, I certainly barely know what I'm doing. The idea is that I dont want to have to do two more server calls and concatenate these values client side.
You would use something like this to get the value:
select cast(n.MapNumber as nvarchar(10)) + ' - ' -- cast the MapNumber
+ cast(s.SectionId as nvarchar(10)) + ' - ' -- cast the SectionId
+ l.Identifier
from MapLocation l
left join MaoNo n
on l.MapNoId = n.MapNoId
left join Section s
on l.SectionId = s.SectionId
Then if you need to perform an UPDATE:
update l
set l.LocationName = (cast(n.MapNumber as nvarchar(10)) + ' - '
+ cast(s.SectionId as nvarchar(10)) + ' - '
+ l.Identifier)
from MapLocation l
left join MaoNo n
on l.MapNoId = n.MapNoId
left join Section s
on l.SectionId = s.SectionId
Edit #1 - you can use a TRIGGER:
CREATE TRIGGER trig_LocationName
ON MapLocation
AFTER INSERT
AS
Begin
update MapLocation
set LocationName = (cast(n.MapNumber as nvarchar(10)) + ' - '
+ cast(s.SectionId as nvarchar(10)) + ' - '
+ i.Identifier)
from Inserted i
left join MaoNo n
on i.MapNoId = n.MapNoId
left join Section s
on i.SectionId = s.SectionId
where MapLocation.MapNoId = i.MapNoId -- fields here to make sure you update the correct record
End