Max size of SDO_ORDINATE_ARRAY / Oracle Spatial - sql

I'm querying an Oracle Spatial database with this query (I left out the other 1496 coordinates):
SELECT *
FROM pointsofinterest
WHERE Sdo_inside (pointsofinterest.geoloc,
Sdo_geometry(2003, 4326, NULL, Sdo_elem_info_array(1, 1003, 1),
Sdo_ordinate_array(4.237378120400001, 43.7904510498, 4.2357025146,
43.7882575989
,
4.232352256800001, 43.7882575989,
4.232352256800001, 43.7871589661))) = 'TRUE'
and get this error:
ORA-00939: too many arguments for function
00939. 00000 - "too many arguments for function"
*Cause:
*Action: Error at Line: 4 Column: 27
The SDO_GEOMETRY object contains 1500 2D-coordinates. That should not be a problem according to http://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_objrelschema.htm#SPATL489
When I remove a lot of coordinates, there is no error.
Am I missing something about the max number of coordinates in the SDO_GEOMETRY constructor? Why am I getting this error?

This error comes from one of the limitations in SQL: the maximum number of arguments that can be passed to a stored function or procedure, i.e. 999 arguments (actually 1000 including the return value). This is because sdo_ordinate_array() is actually a function - the constructor of the sdo_ordinate_array type.
The proper approach (which is also more efficient) is to pass the sdo_geometry object as a bind variable and use that in the query. The way that is done depends on the language you use to submit the select statement ...

Related

SQL overlap statement

I'm trying to do overlap in SQL (using postgres) but receive an syntax error. And i do not know why I'm getting error and whats wrong with my SQL Statement
Error text
[42601] ERROR: syntax error at or near "[" Position: 296
SQL Statement
SELECT *,
ARRAY_AGG("reserve"."state_id" ) AS "states" FROM "orders_order"
JOIN "reserve" ON ("order"."id" = "reserve"."order_id")
GROUP BY "order"."id"
HAVING (NOT (ARRAY_AGG("reserve"."state_id" )&& ['test']::varchar(255)[]))
As documented in the manual there are two ways to specify an array:
First with the array keyword:
array['test']
or as a string enclosed with curly braces:
'{test}'::text[]
In the second case the casting might or might not be needed depending on the context on where it's used.
There is no need to cast it to a varchar(255)[] array. text[] will do just fine - especially when comparing it to the result of an array_agg() which returns text[] as well.

Operator does not exist: character varying = record in Postgres

I am trying to execute query in community edition version of postgres:
select COUNT(*)
from cdar_cpms_owner.hshldgrp_wkly_actvty
where wkly_actvty_cd IN (('B','H') ,'N')
From that query, I get this error:
ERROR: operator does not exist: character varying = record
LINE 1: ..._owner.hshldgrp_wkly_actvty where wkly_actvty_cd IN(('B','H...
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
While the same query is working fine with the EDB version of postgres.
Can anyone please suggest what changes are required in this query to make it work?
Here:
where wkly_actvty_cd IN ( ('B','H'),'N')
Your list has a nested list element: ('B','H'). So Postgres ends up trying to compare a scalar value (wkly_actvty_cd) to a tuple, which raises the error that you are getting.
Did you actually mean?
where wkly_actvty_cd IN ('B', 'H', 'N')

Missing Keyword when trying to Select into

So I have a function to return an Average of a column such as
CREATE OR REPLACE FUNCTION avgCol
RETURN DEC IS avgNum DEC;
BEGIN
SELECT AVG(myCol)
INTO avgNum
FROM MyTable;
RETURN avgNum;
END;
/
While trying to test the results, i have the following
SELECT avgCol
INTO RESULT
FROM DUAL;
but it gives me the error
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
*Cause:
*Action:
Error at Line: 175 Column: 6
Where line 175 is INTO RESULT. As far as I know, this is a scalar function and I'm trying to return a signal variable so it should work right? What keyword am I missing here?
Also I know I can just use AVG(), but I am learning how to create a scalar function. this is strictly for learning purposes.
While testing your code (which should be ok), you need
SELECT avgCol AS result FROM DUAL;
'INTO' assigns the result value to a PL/SQL variable; 'AS' creates an alias/name for a SQL SELECT (not PL/SQL) result column/field.

How to use ANY instead of IN in a WHERE clause?

I used to have a query like in Rails:
MyModel.where(id: ids)
Which generates sql query like:
SELECT "my_models".* FROM "my_models"
WHERE "my_models"."id" IN (1, 28, 7, 8, 12)
Now I want to change this to use ANY instead of IN. I created this:
MyModel.where("id = ANY(VALUES(#{ids.join '),('}))"
Now when I use empty array ids = [] I get the folowing error:
MyModel Load (53.0ms) SELECT "my_models".* FROM "my_models" WHERE (id = ANY(VALUES()))
ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: org.postgresql.util.PSQLException: ERROR: syntax error at or near ")"
Position: 75: SELECT "social_messages".* FROM "social_messages" WHERE (id = ANY(VALUES()))
from arjdbc/jdbc/RubyJdbcConnection.java:838:in `execute_query'
There are two variants of IN expressions:
expression IN (subquery)
expression IN (value [, ...])
Similarly, two variants with the ANY construct:
expression operator ANY (subquery)
expression operator ANY (array expression)
A subquery works for either technique, but for the second form of each, IN expects a list of values (as defined in standard SQL) while = ANY expects an array.
Which to use?
ANY is a later, more versatile addition, it can be combined with any binary operator returning a boolean value. IN burns down to a special case of ANY. In fact, its second form is rewritten internally:
IN is rewritten with = ANY
NOT IN is rewritten with <> ALL
Check the EXPLAIN output for any query to see for yourself. This proves two things:
IN can never be faster than = ANY.
= ANY is not going to be substantially faster.
The choice should be decided by what's easier to provide: a list of values or an array (possibly as array literal - a single value).
If the IDs you are going to pass come from within the DB anyway, it is much more efficient to select them directly (subquery) or integrate the source table into the query with a JOIN (like #mu commented).
To pass a long list of values from your client and get the best performance, use an array, unnest() and join, or provide it as table expression using VALUES (like #PinnyM commented). But note that a JOIN preserves possible duplicates in the provided array / set while IN or = ANY do not. More:
Optimizing a Postgres query with a large IN
In the presence of NULL values, NOT IN is often the wrong choice and NOT EXISTS would be right (and faster, too):
Select rows which are not present in other table
Syntax for = ANY
For the array expression Postgres accepts:
an array constructor (array is constructed from a list of values on the Postgres side) of the form: ARRAY[1,2,3]
or an array literal of the form '{1,2,3}'.
To avoid invalid type casts, you can cast explicitly:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Related:
PostgreSQL: Issue with passing array to procedure
How to pass custom type array to Postgres function
Or you could create a Postgres function taking a VARIADIC parameter, which takes individual arguments and forms an array from them:
Passing multiple values in single parameter
How to pass the array from Ruby?
Assuming id to be integer:
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
But I am just dabbling in Ruby. #mu provides detailed instructions in this related answer:
Sending array of values to a sql query in ruby?

Syntax Errors in User Defined Function in SQL

I'm unable to understand why this code to calculate the Volume of a cube results in the Error Procedure or function 'CubicVolume' expects parameter '#CubeLength', which was not supplied..
CREATE FUNCTION CubicVolume
-- Input dimensions in centimeters
(
#CubeLength decimal(4,1),
#CubeWidth decimal(4,1),
#CubeHeight decimal(4,1)
)
RETURNS decimal(12,3)
AS
BEGIN
RETURN(#CubeLength * #CubeWidth * #CubeHeight)
END
I then try to Execute it using EXEC CubicVolume, which is how one would Execute a Stored Procedure.
I know some Syntax is wrong, but I'm unable to tell where.
Thank You
I'm assuming SQL Server.
You defined a scalar function, but are trying to invoke it like a stored procedure. The two are not the same. Stored procedures are basically batches of SQL statement that execute sequentially, and optionally send resultsets back to the client. Scalar functions behave like built-in functions (e.g., LEN(), CHARINDEX(), ABS(), etc.). That is, they belong in an expression inside a SELECT statement, or moral equivalent. So you need to use your function in a SELECT statement where you'd use a column or an expression. Examples:
SELECT dbo.CubicVolume(12, 5, 3) AS vol
-- result is: 180
SELECT CubeName, l, w, h FROM dbo.SomeTable WHERE dbo.CubicVolume(l, w, h) > 200
-- result could be something like: MyCube, 10, 10, 10 etc.
Basically, it's equivalent to using a mathematical expression based on columns or constants. You cannot use EXEC on it.