STWithin not working for Geography - sql-server-2008

Issue:
When executing #somegeog.STWithin(#othergeog) I get the execption:
Msg 6506, Level 16, State 10, Line 5
Could not find method 'STWithin' for type 'Microsoft.SqlServer.Types.SqlGeography' in assembly 'Microsoft.SqlServer.Types'
Background:
I am working with SQL Server (2008 R2) Geography data for the first time. I have a list of points in a table, and I want to retrieve those in a given area. I intend to write a stored procedure that accepts latitude and longitude bounds for the area.
I can write this procedure easily by extracting the latitude and longitude from the stored geography points, but I was hoping to let the inbuilt functionality do the work. After googling the topic for a while, I found the STWithin method, but even using Microsoft's example, I get an error claiming the method doesn't exist.
MS Example from link:
DECLARE #g geography;
DECLARE #h geography;
SET #g = geography::Parse('POLYGON ((-120.533 46.566, -118.283 46.1, -122.3 47.45, -120.533 46.566))');
SET #h = geography::Parse('CURVEPOLYGON (COMPOUNDCURVE (CIRCULARSTRING (-122.200928 47.454094, -122.810669 47.00648, -122.942505 46.687131, -121.14624 45.786679, -119.119263 46.183634), (-119.119263 46.183634, -119.273071 47.107523), CIRCULARSTRING (-119.273071 47.107523, -120.640869 47.569114, -122.200928 47.454094)))');
SELECT #g.STWithin(#h);
Can somebody please explain what I'm doing wrong?
Thanks in Advance!

I think the example you are looking at applies to SQL Server 2012. Try the example here: http://technet.microsoft.com/en-us/library/bb933991.aspx

You can use STIntersects() with a geography data type in SQL Server 2008. This is much faster than using .Lat and .Long if you have your spatial index set up.

Related

Common Table Expressions -- Using a Variable in the Predicate

I've written a common table expression to return hierarchical information and it seems to work without issue if I hard code a value into the WHERE statement. If I use a variable (even if the variable contains the same information as the hard coded value), I get the error The maximum recursion 100 has been exhausted before statement completion.
This is easier shown with a simple example (note, I haven't included the actual code for the CTE just to keep things clearer. If you think it's useful, I can certainly add it).
This Works
WITH Blder
AS
(-- CODE IS HERE )
SELECT
*
FROM Blder as b
WHERE b.PartNo = 'ABCDE';
This throws the Max Recursion Error
DECLARE #part CHAR(25);
SET #part = 'ABCDE'
WITH Blder
AS
(-- CODE IS HERE )
SELECT
*
FROM Blder as b
WHERE b.PartNo = #part;
Am I missing something silly? Or does the SQL engine handle hardcoded values and parameter values differently in this type of scenario?
Kindly put semicolon at the end of your variable assignment statement
SET #part ='ABCDE';
Your SELECT statement is written incorrectly: the SQL Server Query Optimizer is able to optimize away the potential cycle if fed the literal string, but not when it's fed a variable, which uses the plan that developed from the statistics.
SQL Server 2016 improved on the Query Optimizer, so if you could migrate your DB to SQL Server 2016 or newer, either with the DB compatibility level set to 130 or higher (for SQL Server 2016 and up), or have it kept at 100 (for SQL Server 2008) but with OPTION (USE HINT ('ENABLE_QUERY_OPTIMIZER_HOTFIXES')) added to the bottom of your SELECT statement, you should get the desired result without the max recursion error.
If you are stuck on SQL Server 2008, you could also add OPTION (RECOMPILE) to the bottom of your SELECT statement to create an ad hoc query plan that would be similar to the one that worked correctly.

PL/SQL Convert to JSON

I'm new to using PL/SQL (although I have some SQL experience before). I have been trying to convert a particular data into JSON. I did research throughout the Internet but I couldn't figure out what was wrong on my code. It did produced errors such as "ORA-12801". This is actually a large dataset that I'm working on. I would like to use only the cursor loop as it is because it is much easier to use than using other libraries. Therefore, could you offer an opinion or thought after looking through the code?
**UPDATE: I'm using Toad for Oracle for the data.
**UPDATE2: I have already looked into the other link and that didn't solve my problem because I do not wish to use other libraries such as PL/JSON. Rather, I would like to use a simple cursor statement in PL/SQL to convert the table's columns into JSON only.
DECLARE
links varchar2(750);
CURSOR statement
IS
SELECT DISTINCT NAME, GROUP
FROM ST.PEOPLE
GROUP BY ST.PEOPLE.NAME, ST.PEOPLE.GROUP
ORDER BY ST.PEOPLE.NAME ASC;
BEGIN
FOR line IN statement
LOOP
links := '{"source":"'|| line.NAME ||'", "target":"'|| line.GROUP||'""}';
END LOOP;
dbms_output.put_line(links);
END;
Fails with:
ORA-12801: error signaled in parallel query server P045
ORA-12853: insufficient memory for PX buffers: current 16352K, max needed 702720K
ORA-04031: unable to allocate 65560 bytes of shared memory (“large pool”, “unknown object”, “large pool”, “PX msg pool”)
ORA-06512: at line 17
I solved my problem by using one of the database's buttons to turn on the output on the "DBMS Output" for executing the code and it worked.

How to validated geography polygon in SQL server 2008?

In the SQL Server 2012 there is methods to validate geography '.IsValidDetailed()' and to change orientation '.ReorientObject (geography)'.
I am working with SQL server 2008 and facing problems of polygon orientation.
Question is -
is there any solution to validate geography polygon or change the orientation to valid geography?
is it possible to copy that IsValidDetailed method from sqlserver 2012 to 2008?
if I have to do it manually, then what is the correct orientation of polygon for valid geography datatype?
We can validate geometry datatype in SQL server 2008, is it ok to convert geography polygon in to geometry polygon and validated it?
Please assist. Thanks in advance
This is working for me on SQL Server 2008. After loading the shape as a geometry, use MakeValid() to correct it, then reload into a geography.
declare #gt nvarchar(max)
declare #gm geometry
declare #gmvalid geometry
set #gmvalid = #gm.MakeValid()
set #gt = #gmvalid.STAsText()
--select #gt
if LEFT(#gt,7 ) = 'POLYGON'
begin
set #gg = geography::STPolyFromText(#gt, 4326)
end
else
begin
set #gg = geography::STMPolyFromText(#gt, 4326)
end
I found solution, SQL Server Saptial Tools
http://sqlspatialtools.codeplex.com/
Followings are the methods solved my problem.
IsValidGeographyFromText(string inputWKT, int srid)
Check if an input WKT can represent a valid geography. This function requires that
the WTK coordinate values are longitude/latitude values, in that order and that a valid
geography SRID value is supplied. This function will not throw an exception even in
edge conditions (i.e. longitude/latitude coordinates are reversed to latitude/longitude).
SqlGeography MakeValidGeographyFromText(string inputWKT, int srid)
Convert an input WKT to a valid geography instance.
This function requires that the WKT coordinate values are longitude/latitude values,
in that order and that a valid geography SRID value is supplied.

SQLServer Spatial query is returning error An expression of non-boolean type specified in a context where a condition is expected, near ')'

I am trying to learn how to do radius search on records using the new SqlServer 2008 managed spacial type and methods (geography) for doing geospatial calculations. I am following the samples on this web page:
http://msdn.microsoft.com/en-us/magazine/dd434647.aspx
I am specifically trying to do this sample:
-- or declare POINT for "downtown Seattle"
-- 1609.344 meters per mile
DECLARE #Seattle geography = 'POLYGON(....)'; SELECT c.customerid FROM
customer c WHERE c.geog.STIntersects(#Seattle.STBuffer(10 * 1609.344));
However, even before running the query (or when I run the quer--both compile and runtime error)I am getting the following error message:
An expression of non-boolean type specified in a context where a condition is expected, near ')'
I am really baffled by this. I am not doing exactly the same query (I am using my own data with a geography column) but it is almost identical to the sample. I am running Sql SErver 2008 SP2 Standard Edition 64-bit. When I type the query it uses intellisense for the STIntersection method and shows a (other_geography geography) sample so it knows that the method exists. I am properly closing the parentheses and delimiting the expression with a semi-colon but I cannot figure out why I am getting the error. Googling has not worked.
Any thoughts?
Seth
STIntersects returns 0 or 1. Try this:
WHERE c.geog.STIntersects(#Seattle.STBuffer(10 * 1609.344)) = 1

Create stored procedure with CONTAINS in SQL Server 2008

I want to create a stored procedure to do some combined keyword search using CONTAINS,something like below:
SELECT theContent
FROM FtsTest
WHERE CONTAINS
(theContent,
' FORMSOF (INFLECTIONAL, keyword1) AND FORMSOF (INFLECTIONAL, keyword2)');
and he number of keywords may vary, so I tried to pass the whole 'FORMSOF... AND FORMSOF.....'clause as a parameter,declaring the parameter as nvarchar(max),but it won't let me do it,saying The argument type "nvarchar(max)" is invalid for argument 2 of "CONTAINS".
So, is there any way to make it work with the sp?
Thanks!
Just declare argument 2 of contains as nvarchar(4000) instead of nvarchar(max) and it will work.
See the difference here: https://msdn.microsoft.com/en-us/library/ms186939.aspx
2 GB is a bit too much for the search expression.
this seems stupid,but using nvarchar(500) instead of nvarchar(max), Sql Server cheerfully accepts it and works just fine.
Still trying to gain some insight on sp_executesql,thanks.
You could build it dynamically and pass in the keywords as parameters. Executing with sp_executesql allows you to take advantage of the query plan cache, as described in the answers to this question:
Alternative to executing dynamic sql
You may need to watch out for this issue, though, that relates to parameter sniffing and full text queries:
http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=510118