How come this geometry point does not intersect with the polygon? - sql-server-2008

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

Related

HTML title attribute line break

I am trying to generate a tool tip text using SQL. The text generated is passed as Title Attribute in HTML. There needs to be some newline characters generated in the tool tip.
I have used the following -
CHAR(13); CHAR(10); <br>; \n.
However in all cases, I see the character itself in HTML and not a new line.
Any idea how to achieve this?
the SQL is something like this
(SELECT
STUFF(';' + WOR.OrderNo + ' - ' + P.ProductNo + ' - ' + CAST(CAST(ROUND(WOR.OrderQuantity , 0) as int) as varchar(20)) + '; <br/> ', 1, 1, '')
FROM
[ORDER] WOR
JOIN
PRODUCT P
ON P.ID = WOR.ProductID
JOIN
PRODUCT_GROUP PGR
ON P.ID = PGR.ProductID FOR XML PATH(''),TYPE).value('.','nvarchar(MAX)')```
And the Tootip that I see is the following
```SMU_100000021 - A-WHEL-001 - 100;<br/>SMU_100000023 - A-WHEL-001 - 90;<br/>```
The CHAR(10) did the trick.
(SELECT
STUFF(';' + WOR.OrderNo + ' - ' + P.ProductNo + ' - ' + CAST(CAST(ROUND(WOR.OrderQuantity , 0) as int) as varchar(20)) +' '+ CHAR(10) + ' ', 1, 1, '')
FROM
[ORDER] WOR
JOIN
PRODUCT P
ON P.ID = WOR.ProductID
JOIN
PRODUCT_GROUP PGR
ON P.ID = PGR.ProductID FOR XML PATH(''),TYPE).value('.','nvarchar(MAX)')

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

Using Dynamic SQL in a WHILE Loop

I work for an Insurance Company and creating a custom application. When we apply a coverage to a policy it is stored in a table with a Limit, Deductible, and Premium field. However, there are many coverages that do not follow the norm. They use different fields for Limit, Deductible, and Premium and are even stored in different tables. (Don’t ask why and don’t even try to understand the fact that they are STILL doing this so I need to leave logic to allow for additional coverages like this.) There is also no rhyme or reason to what fields they choose so varies greatly.
So, we have decided to create “LookUp” tables that will store all the information we need for a coverage. This avoids numerous joins – we were having issues with speed and performance of the application.
I need to find a way to prepopulate all these fields into a table. I would like the best option performance-wise. This will end up being a Nightly job – so when we receive a new snapshot of data we will run this query and prepopulate/update the values of the table.
I have the following code, I loop through this for each policy, essentially 614,000 time each night...It takes a LONG time to run.
Is there a better way for me to do this?
SELECT #SQL = N'SELECT #Limit=' + ISNULL(Limit, '''''') + N',#Deductible=' + ISNULL(Deductible, '''''') + N',#Premium=' + ISNULL(Premium, '''''') + N' FROM PHI_PIJ.dbo.ASBYCPP' + N' WHERE ' + PolicyNum + N' = ''' + #PolicyKey +'''' + N' AND BYAOTX' + N'='''+Coverage +''''
FROM PolicySummary.dbo.Coverage
WHERE Coverage = #Coverage
AND LOB = 'BOP'
EXEC sp_executesql #SQL, N'#Limit nVarChar(255) output,#Deductible nVarChar(255) output,#Premium nVarChar(255) output', #Limit output, #Deductible output, #Premium output
UPDATE PolicySummary.dbo.CoverageLkup
SET Limit = #Limit, Deductible = #Deductible, Premium = #Premium
WHERE CovAbbrev = #Coverage
AND PolicyKey = #PolicyKey
Here is what is inside my While Loop:
SELECT #SQL = N'SELECT #Limit=' + ISNULL(Limit, '''''') + N',#Deductible=' + ISNULL(Deductible, '''''') + N',#Premium=' + ISNULL(Premium, '''''') + N' FROM PHI_PIJ.dbo.' + [File] + N' WHERE ' + PolicyNum + N' = ''' + #PolNum +'''' + N' AND ' + #CovField + N'='''+Coverage +''''
FROM PolicySummary.dbo.Coverage
WHERE Coverage = #Coverage
AND LOB = #LOB
EXEC sp_executesql #SQL, N'#Limit nVarChar(255) output,#Deductible nVarChar(255) output,#Premium nVarChar(255) output', #Limit output, #Deductible output, #Premium output
INSERT INTO #OptCov2 VALUES(#Coverage, #Description, #LOB, #Limit, #Deductible, #Premium)

Parameterizing an SQL query which uses the NOT LIKE, " ^ " wildcard?

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

Why is my CAST returning null/nothing?

When I attempt to cast my FLOATS into CHARS in this procedure, I get null values in the database. Location is a Geospatial field. What am I doing wrong?
CREATE DEFINER=`me`#`%` PROCEDURE `UpdateLocationByObjectId`(IN objectId INT,
IN latitude FLOAT,
IN longitude FLOAT)
BEGIN
UPDATE Positions P
JOIN Objects O ON P.Id = O.PositionId
SET P.Location = GeomFromText('Point(' + CAST(latitude AS CHAR(10)) + ' ' + CAST(longitude AS CHAR(10)) +')')
WHERE O.ObjectId = objectId;
END
If I use this as a test, it works fine.
CREATE DEFINER=`me`#`%` PROCEDURE `UpdateLocationByObjectId`(IN objectId INT,
IN latitude FLOAT,
IN longitude FLOAT)
BEGIN
UPDATE Positions P
JOIN Objects O ON P.Id = O.PositionId
SET P.Location = GeomFromText('Point(10 10')')
WHERE O.ObjectId = objectId;
END
Change this line
SET P.Location = GeomFromText('Point(' + CAST(latitude AS CHAR(10)) + ' '
+ CAST(longitude AS CHAR(10)) +')')
To
SET P.Location = GeomFromText(concat('Point(' , CAST(latitude AS CHAR(10)) , ' '
, CAST(longitude AS CHAR(10)) ,')'))
The + operator is adding your text values ('10' + '10') = 20
So the center part evaluates to 'Point(' + 20 + ')', adding text that cannot be read as number + numbers evaluates to NULL.
Only the concat function can concatenate strings.
In fact this code will work just as well:
SET P.Location = GeomFromText(concat('Point(', latitude, ' ', longitude,')'))