I have some filters in the following form:
Object A
+/- Start End
----------------------------------------------
+ 000000080000 000000090000
- 000000800500
+ 054*
Object B
+/- Start End
----------------------------------------------
+ 000000090000 000000100000
+ 00??00900500
- 000000900500
+ 055*
It means:
Numbers between 000000080000 and 000000090000 except 000000800500, and numbers starting with 054 are associated with object A.
Numbers between 000000090000 and 000000100000 except 000000900500, numbers matching 00??00900500 (except 000000900500 of course), and numbers starting with 055 are associated with object B.
Example of the table structure:
CREATE TABLE dbo.Filter
(
IDFilter int IDENTITY PRIMARY KEY
)
CREATE TABLE dbo.FilterRow
(
IDFilterRow int IDENTITY PRIMARY KEY
,IDFilter int FOREIGN KEY REFERENCES dbo.Filter(IDFilter) NOT NULL
,Operator bit --0 = -, 1 = + NOT NULL
,StartNumber varchar(50) NOT NULL
,EndNumber varchar(50)
)
CREATE TABLE dbo.[Object]
(
IDObject int IDENTITY PRIMARY KEY
,Name varchar(10) NOT NULL
,IDFilter int FOREIGN KEY REFERENCES dbo.Filter(IDFilter) NOT NULL
)
I need a way to make sure no numbers can get associated with more than 1 object, in SQL (or CLR), and I really have no clue how to do such a thing (besides bruteforce).
I do have a CLR function Utils.fIsInFilter('?8*', '181235467895') that supports wildcards and would return 1, if it helps...
Can you use a CLR function in SQL 2005?
It's possible in raw SQL using LIKE JOINS (where ? becomes [0-9] and * becomes %), perhaps followed by CAST, but this is what CLR functions are for...
Related
I need to perform location based search based on latitude and longitude pairs, to find out the near by locations of stores within a radius/distance of given KMs.
I am to use (for certain) Oracle's SDO_GEOMETRY for searching the locations.
Also, the table structure are parent-child based such that store address (zip, lat/long) is in parent table but store details (name, contact, etc) are in the child table.
This is to make sure that we do not have redundant data (as multiple store can have same lat/long and by some dark magic same address)
I have the following scenario (tables provided):
Version - Oracle Database 12c Enterprise Edition Release 12.2.0.1.0
Table: STORE_LOCATION
CREATE TABLE STORE_LOCATE
(
ID NUMBER DEFAULT STORE_LOCATE.nextval,
POSTAL_CODE VARCHAR2(18) NOT NULL,
ADDRESS VARCHAR2(382) NOT NULL,
GEO_LOCATION SDO_GEOMETRY NOT NULL
);
Table: STORE_DETAIL
CREATE TABLE STORE_DETAIL
(
ID NUMBER DEFAULT STORE_DETAIL_SEQ.nextval,
STORE_CODE VARCHAR2(20) NOT NULL,
STORE_NAME VARCHAR2(150) NOT NULL,
IS_ACTIVE NUMBER(3) DEFAULT 0 NOT NULL,
fk_store_locate_id INT NOT NULL. -- FK to ID of parent
);
I have inserted data in parent as:
INSERT INTO STORE_LOCATE (ZIP, ADDRESS, GEO_LOCATION) VALUES
('567875', '84 Paddar Road',
SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE (80.34234431,26.12354422, NULL), NULL, NULL));
Likewise, child table has entries:
INSERT INTO STORE_DETAIL (STORE_CODE, STORE_NAME, FK_STORE_LOCATION_ID) VALUES
('ST01', 'STORE 1', 1);
So, now when a user shares his location to me (lat/long), I need to search all nearby locations of stores within a specified radius.
I tried the following query, but I am getting error with this:
SELECT
s.store_code,
s.store_name,
loc.zip,
loc.address,
loc.geo_location
FROM store_detail s,
store_locate loc
where MDSYS.SDO_WITHIN_DISTANCE(loc.geo_location,
(MDSYS.SDO_GEOMETRY(2001, 8307,
MDSYS.SDO_POINT_TYPE(80.21456732,26.23117864, NULL) ,NULL, NULL)),
'distance=1000 unit=KM') = 'TRUE';
Getting the below error:
ORA-29900: operator binding does not exist
ORA-06553: PLS-306: wrong number or types of arguments in call to 'SDO_WITHIN_DISTANCE'
29900. 00000 - "operator binding does not exist"
*Cause: There is no binding for the current usage of the operator.
*Action: Change the operator arguments to match any of the existing
bindings or add a new binding to the operator.
I am breaking my head around this for a while now but in vain.
Ref:
https://issues.redhat.com/browse/TEIID-751?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel
https://docs.oracle.com/cd/E17781_01/appdev.112/e18750/xe_locator.htm#XELOC562
Q's:
Is this the correct way to perform location search on Oracle SQL?
Is there any other way if the above is incorrect?
There are a number of syntax errors in your code (POSTAL_CODE called ZIP, etc)
Here is the corrected example (I also removed the sequences for simplicity)
CREATE TABLE STORE_LOCATE (
ID NUMBER primary key,
POSTAL_CODE VARCHAR2(18) NOT NULL,
ADDRESS VARCHAR2(382) NOT NULL,
GEO_LOCATION SDO_GEOMETRY NOT NULL
);
CREATE TABLE STORE_DETAIL (
ID NUMBER primary key,
STORE_CODE VARCHAR2(20) NOT NULL,
STORE_NAME VARCHAR2(150) NOT NULL,
IS_ACTIVE NUMBER(3) DEFAULT 0 NOT NULL,
fk_store_locate_id INT NOT NULL references STORE_LOCATE
);
INSERT INTO STORE_LOCATE (ID, POSTAL_CODE, ADDRESS, GEO_LOCATION) VALUES (1, '567875', '84 Paddar Road', SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE (80.34234431,26.12354422, NULL), NULL, NULL));
INSERT INTO STORE_DETAIL (ID, STORE_CODE, STORE_NAME, FK_STORE_LOCATE_ID) VALUES (1001,'ST01', 'STORE 1', 1);
commit;
Here is running your query:
SELECT
s.store_code,
s.store_name,
loc.postal_code,
loc.address,
loc.geo_location
FROM store_detail s, store_locate loc
where SDO_WITHIN_DISTANCE(
loc.geo_location,
SDO_GEOMETRY(2001, 8307,
SDO_POINT_TYPE(80.21456732,26.23117864, NULL),NULL, NULL
),
'distance=1000 unit=KM'
) = 'TRUE';
STORE_ STORE_NAME POSTAL ADDRESS GEO_LOCATION(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES
------ ---------- ------ -------------------- ----------------------------------------------------------------------------------
ST01 STORE 1 567875 84 Paddar Road SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(80.3423443, 26.1235442, NULL), NULL, NULL)
1 row selected.
The error you get probably means Oracle Spatial is not or incorrectly installed in your database. What exact database version do you use ?
IMPORTANT NOTE:
Those queries really need a spatial index on the GEO_LOCATION column. Without one, the query is rejected in versions up to 12.1. From 12.2 and later, the query will run, but will be very slow as soon as the number of locations goes above a few 100s. Once you go into the 100000 or more, it will be very slow.
See https://docs.oracle.com/en/database/oracle/oracle-database/19/spatl/indexing-querying-spatial-data.html#GUID-07129836-0DAE-4BCC-B290-942C456AE2EA for details
I am trying to add CHECK constraints for my table in database, but I am getting error CHECK Constraint failed everytime I tried adding values in table. It may syntax error for SQLite. Thanks in advance.
CREATE TABLE `staff` (
`sid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`sname` TEXT NOT NULL,
`semail` TEXT NOT NULL UNIQUE,
`sphone` TEXT NOT NULL CHECK(length ( 'sphone' ) = 10) UNIQUE,
`sdept` TEXT NOT NULL CHECK(length ( 'sdept ' ) = 2),
`spassword` TEXT NOT NULL CHECK(length ( 'spassword' ) <= 8));
You shouldn't have single quotes around your column names in the constraint clauses; that turns the names into strings. You should replace the single-quotes with double quotes or omit them altogether. (You should also replace the back-quotes in your table and column names with either double-quotes or nothing at all to conform to the SQL standard.)
I have the following table (maximum number of records 999) I use for a lookup:
CREATE TABLE lga
(
lgacode character varying(3) NOT NULL DEFAULT '000'::character varying,
lganame character varying(32) NOT NULL,
CONSTRAINT pk_lga PRIMARY KEY (lganame),
CONSTRAINT uk_lga UNIQUE (lgacode)
);
Using Anorm, I easily get a result list lgas of the type List[models.LgaTable]
How do I get this result list into the form List[Tuple2[String,String]]?
I searched Stack Overflow and found something close ([a link]http://stackoverflow.com/questions/4927260/filling-a-scala-immutable-map-from-a-database-table) but this contained Set, which I have an aversion for, meanwhile: I just needed something simple. Thanks
Just call a map on your result:
val lgas: List[models.LgaTable] = ...
val lgas_tupled = lags.map(row => (row.lgacode, lganame))
Does a unique constraint include a not null constraint?
I have a case that one attribute cellPhone can be NULL but cannot be repeated, so I give it 2 constraints: "not null" and "unique", in a case of updating the record, if user didn't enter a value I put 0 in the field, so it makes this exception:
SEVERE: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (TEST1.OSQS_PARENTS_CELLPHONE_UK) violated
What should I do in the UPDATE case?
EDIT
here's the definition of table ddl
CREATE TABLE "TEST1"."OSQS_PARENTS"
( "PARENT_NO" NUMBER(38,0),
"PARENT_NAME" VARCHAR2(4000 BYTE),
"PARENT_ID" NUMBER(38,0),
"PARENT_EMAIL" VARCHAR2(30 BYTE),
"PARENT_CELLPHONE" NUMBER(38,0)
)
and here's an image of the constraints
and here is the update statement
Parent aParent; //is an object I pass through a function
String SQlUpdate = "UPDATE OSQS_PARENTS P SET P.PARENT_ID=?,P.PARENT_EMAIL=?,P.PARENT_CELLPHONE=?"
+ " where P.PARENT_NO=?";
PreparedStatement pstmt = null;
try {
pstmt = con.prepareStatement(SQlUpdate);
pstmt.setLong(1, aParent.getId());
pstmt.setString(2, aParent.getEmail());
pstmt.setLong(3, aParent.getCellPhoneNo());
pstmt.setLong(4, parentNo);
pstmt.executeUpdate();
}
it sounds like this:
cellPhone must be unique. When user does not input value, you mark it as a 0. Thus it fails when you try to insert multiple 0 values into a 'UNIQUE' column.
I believe you need to drop the NOT NULL constraint on the column (allow it to be UNIQUE yes, but allow NULLS).
Then when user inputs no value, use it as a NO value (unknown = null <> 0 -- 0 is a known value )
throw an IF into your statement, if value then what you have, otherwise SET IT TO NULL!\
pstmt.setNull(3, java.sql.Types.INTEGER);
When I execute a certain stored procedure (which selects from a non-indexed view) with a non-null parameter, it's lightning fast at about 10ms. When I execute it with a NULL parameter (resulting in a FKColumn = NULL query) it's much slower at about 1200ms.
I've executed it with the actual execution plan and it appears the most costly portion of the query is a clustered index scan with the predicate IS NULL on the fk column in question - 59%! The index covering this column is (AFAIK) good.
So what can I do to improve the performance here? Change the fk column to NOT NULL and fill the nulls with a default value?
SELECT top 20 dbo.vwStreamItems.ItemId
,dbo.vwStreamItems.ItemType
,dbo.vwStreamItems.AuthorId
,dbo.vwStreamItems.AuthorPreviewImageURL
,dbo.vwStreamItems.AuthorThumbImageURL
,dbo.vwStreamItems.AuthorName
,dbo.vwStreamItems.AuthorLocation
,dbo.vwStreamItems.ItemText
,dbo.vwStreamItems.ItemLat
,dbo.vwStreamItems.ItemLng
,dbo.vwStreamItems.CommentCount
,dbo.vwStreamItems.PhotoCount
,dbo.vwStreamItems.VideoCount
,dbo.vwStreamItems.CreateDate
,dbo.vwStreamItems.Language
,dbo.vwStreamItems.ProfileIsFriendsOnly
,dbo.vwStreamItems.IsActive
,dbo.vwStreamItems.LocationIsFriendsOnly
,dbo.vwStreamItems.IsFriendsOnly
,dbo.vwStreamItems.IsDeleted
,dbo.vwStreamItems.StreamId
,dbo.vwStreamItems.StreamName
,dbo.vwStreamItems.StreamOwnerId
,dbo.vwStreamItems.StreamIsDeleted
,dbo.vwStreamItems.RecipientId
,dbo.vwStreamItems.RecipientName
,dbo.vwStreamItems.StreamIsPrivate
,dbo.GetUserIsFriend(#RequestingUserId, vwStreamItems.AuthorId) as IsFriend
,dbo.GetObjectIsBookmarked(#RequestingUserId, vwStreamItems.ItemId) as IsBookmarked
from dbo.vwStreamItems WITH (NOLOCK)
where 1 = 1
and vwStreamItems.IsActive = 1
and vwStreamItems.IsDeleted = 0
and vwStreamItems.StreamIsDeleted = 0
and (
StreamId is NULL
or
ItemType = 'Stream'
)
order by CreateDate desc
When it's not null, do you have
and vwStreamItems.StreamIsDeleted = 0
and (
StreamId = 'xxx'
or
ItemType = 'Stream'
)
or
and vwStreamItems.StreamIsDeleted = 0
and (
StreamId = 'xxx'
)
You have an OR clause there which is most likely the problem, not the IS NULL as such.
The plans will show why: the OR forces a SCAN but it's manageable with StreamId = 'xxx'. When you use IS NULL, you lose selectivity.
I'd suggest changing your index make StreamId the right-most column.
However, a view is simply a macro that expands so the underlying query on the base tables could be complex and not easy to optimise...
The biggest performance gain would be for you to try to loose GetUserIsFriend and GetObjectIsBookmarked functions and use JOIN to make the same functionality. Using functions or stored procedures inside a query is basically the same as using FOR loop - the items are called 1 by 1 to determine the value of a function. If you'd use joining tables instead, all of the items values would be determined together as a group in 1 pass.