I tried to run this code on MSSQL 2014 and it returns a value.
DECLARE #g geometry;
SET #g = geometry::STPointFromText('POINT (60 60)', 4326);
Select Country From [vstl].[dbo].[EEZ_1] where geom.STIntersects(#g)=1;
Results
Singapore
However, when I tried to run on MSSQL 2012 and 2008R2, with the same sql query and data, it give and exception error as below.
Msg 6522, Level 16, State 1, Line 4
A .NET Framework error occurred during execution of user-defined routine or aggregate "geometry":
System.ArgumentException: 24144: This operation cannot be completed because the instance is not valid. Use MakeValid to convert the instance to a valid instance. Note that MakeValid may cause the points of a geometry instance to shift slightly.
System.ArgumentException:
at Microsoft.SqlServer.Types.SqlGeometry.ThrowIfInvalid()
at Microsoft.SqlServer.Types.SqlGeometry.STIntersects(SqlGeometry other)
.
Does anybody have any idea what is going on?
Found the culprit!
There is an invalid shapefile geometry in the table.
Select * from eez where geom.STIsValid()=0
Turns out give 5 invalid values. Removing the invalid values solved the problem.
Related
Calculating the avg:
SELECT
round(AVG(P.LiczbaUczniow/E.WypełnioneEtaty),2)
FROM [dbo].[UczniowieWojs] P
INNER JOIN EtatyWypełnioneWoj E ON E.WOJ=P.idTerytWojewodztwo
RESULT: 9.38
DECLARING THE VARIABLE:
DECLARE #ŚrednioUczniówNaNauczycielaPL decimal(3,2);
TRYING TO SAVE THE VARIABLE:
SELECT
#ŚrednioUczniówNaNauczycielaPL=round(AVG(P.LiczbaUczniow/E.WypełnioneEtaty),2)
FROM [dbo].[UczniowieWojs] P
INNER JOIN EtatyWypełnioneWoj E ON E.WOJ=P.idTerytWojewodztwo
Msg 137, Level 15, State 1, Line 305 Must declare the scalar variable
"#ŚrednioUczniówNaNauczycielaPL".
What I've tried to resolve it:
I've read the documentation of decimal datatype.
Google
Similar topics on stackoverflow - they all seem to refer to scale and precision which I think I got right. Yet, it's still wrong.
I've been working on it and sincerely cannot find the solution. I'd appreciate pointing me towards the answer.
Thanks
#Larnu, #stickybit, #AlwaysLearning pointed out that a variable must be in the same badge. And I was running the Declare and Select commands separately, which made them separate things. That was the reason for the error.
If I had used a GO command in between of these statements that would also have produced the erroneous result.
Semicolon turned out to be fine because it isn't a batch separator.
To sum it up - no 'go' between the statements and run them altogether.
I'm working on a spatial database SQL Server and am having a hard time querying a row where the geography contains a given lat/long.
I'm able to get this query to work:
DECLARE #polygon Geography;
select #polygon = (
select
geog4269
from census_tracts
WHERE namelsad10 = 'Census Tract 9801.02'
);
set #polygon = #polygon.ReorientObject();
select #polygon.STContains(
geography::Point(18.4102591, -66.0732014, 4269)
);
However, I want to be able to select the row that contains a given lat/long with something like the following:
select
*
from census_tracts
WHERE geog4269.ReorientObject().STContains(
geography::Point(18.4102591, -66.0732014, 4269)
) = 1
I'm getting a .NET Framework exception when I run that saying to use MakeValid to avoid it, but adding .MakeValid() doesn't fix the issue.
This is the exception message:
Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
System.ArgumentException: 24144: This operation cannot be completed because the instance is not valid. Use MakeValid to convert the instance to a valid instance. Note that MakeValid may cause the points of a geometry instance to shift slightly.
System.ArgumentException:
at Microsoft.SqlServer.Types.SqlGeography.ThrowIfInvalid()
at Microsoft.SqlServer.Types.SqlGeography.ReorientObject()
.
When I use the following query:
select
*
from census_tracts
WHERE geog4269.MakeValid().ReorientObject().STContains(
geography::Point(18.4102591, -66.0732014, 4269)
) = 1
The geographies don't get reoriented (every geography says it contains all points).
Has anyone run into something similar before or can point out where I'm going wrong? Thanks for the help!
My guess is for some geographies MakeValid also fixes the orientation of the polygons. If the polygons is invalid, MakeValid has to make a guess about what was the intended shape, and fix it using some heuristics. The results may vary depending on what exactly was wrong with the data - and sometime garbage in, garbage out applies.
I would avoid using both MakeValid() and ReorientObject() in the query. This is both error prone, and slow (as it prevents spatial index usage).
Instead, fix the actual data by updating the geographies to be the intended ones.
Quick and dirty way is to invert only those that need inverting, something like
update census_tracts
set geog4269 =
IF (geog4269.MakeValid().STArea() < 1e14, -- is it small?
geog4269.MakeValid(),
geog4269.MakeValid().ReorientObject());
I'm trying to add a column to a table that contains a lot of geography shapes. The column is going to contain the shape's area. I first altered the table as follows:
ALTER TABLE geographyShapes ADD shapeArea FLOAT NULL;
Then I ran this update statement to fill in the column:
UPDATE geographyShapes SET shapeArea = shape.STArea() WHERE shape.STIsValid() = 1
I thought this would weed out any invalid shapes, but I guess not because I keep getting this error:
Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography":
System.ArgumentException: 24144: This operation cannot be completed because the instance is not valid. Use MakeValid to convert the instance to a valid instance. Note that MakeValid may cause the points of a geometry instance to shift slightly.
System.ArgumentException:
at Microsoft.SqlServer.Types.SqlGeography.ThrowIfInvalid()
at Microsoft.SqlServer.Types.SqlGeography.STArea()
Does anyone know why I'm getting this error?
I worried all day.
My label is very big - '20317302009001'.
Zlecenie is int column - so sql generates error when compare zlecenie=#label.
I tried to catch it, but still get message:
Msg 248, Level 16, State 1, Procedure label_check, Line 9
The conversion of the varchar value '20317302009001' overflowed an int column.
Who knows the answer?
Thank you!
begin TRY
if (#komponent is null) and ISNUMERIC(#label)=1
begin
set #komponent=null
if exists(select * from Rejestr_zuzycia_tkaniny where zlecenie=#label)
begin
declare #program int;
select #program=program from Rejestr_zuzycia_tkaniny where zlecenie=#label
select #komponent=komponent from Komponenty_programu where program=#program
end;
end;
end TRY
begin CATCH
set #komponent=null
end CATCH
From your code, it looks like you don't actually use zlecenie as a number, so you might want to compare by casting it as a varchar first like so:
if exists(select * from Rejestr_zuzycia_tkaniny where cast(zlecenie as varchar(20))=#label)
However, if you do need to process zlecenie as a number later on e.g. add it to something, then you might want to make it a bigint instead of int to accommodate large values.
MSDN has this to say about TRY...CATCH in T-SQL:
The following types of errors are not handled by a CATCH block when they occur at the same level of execution as the TRY…CATCH construct:
Compile errors, such as syntax errors, that prevent a batch from running.
Errors that occur during statement-level recompilation, such as object name resolution errors that occur after compilation because of deferred name resolution.
I believe that the arithmetic overflow error might belong to the second scenario, which would explain why the CATCH block does not handle it. However, I have not been able to get any corroboration elsewhere so I suggest you do not just take my word for it.
I am strugling wiith handling a sql binary(8) data type.
No matter what I try to do with it inside the SSIS package, it always fails with an error of: "Invalid cast specification"
Let me describe what I am tying to do in details:
I have a single row that I am assigning to a variable in a SQL Task in the control flow.
select max(LastRowVersion as bigint) as MinRV from MyTable
LastRowVersion is of datatype binary(8).
2.Then I am assigning the result to variable - User::MaxRowVersion
If I configure MaxRowVersion to be of String or Object data type, then this part works fine.
3.Next I am opening a data flow task with the following select statement:
select fields
from AnotherTable
where LastRowVersion > ?
and assigning User::MaxRowVersion to the query.
Again LastRowVersion is of datatype binary(8) in the table - AnotherTable.
Here is where I am getting the error that I mentioned above.
I have tried various types of playing with the DT_BYTES cast type in the expression of the User::MaxRowVersion variable, but it is failing.
I have also read that there is a possibility to open a C# script task to handle it or that Dynamic SQL can help, but I would rather keep the solution as simple as possible with no scripting if possible.
Thanks for the help,
Dani
Have you tried this?
Keep MaxRowVersion as a Sting data type
Cast the variable reference in the SQL statement
Example:
"
SELECT my_field
FROM my_table
WHERE LastRowVersion > CAST('" + #[User::MaxRowVersion] + "' as MyDataType);
"