Psql - How to skip row when error in address during Geocoding - psql

Am Geocoding hundreds of thousands of records, while this query is running if the address does not produce a Lat and Long value for a particular row it shows an error "invalid input syntax for integer: "J199" ". So if this line
(geocode_intersection(crashroad,crashreferenceroad,state,city,'',1)
Produces a value like "J199",it has to skip that row. So how to do this?
update nj.condition_3
set (rating,new_address,points) = ( COALESCE((g.geo).rating,-1),pprint_addy((g.geo).addy),st_astext(ST_SnapToGrid((g.geo).geomout, 0.000001)))
-- Replace in limit value if error occurs
FROM (SELECT addid FROM nj.condition_3 WHERE rating IS NULL ORDER BY addid LIMIT 3) As a
LEFT JOIN (SELECT addid, (geocode_intersection(crashroad,crashreferenceroad,state,city,'',1)) As geo
-- Replace in limit value if error occurs
FROM nj.condition_3 As ag WHERE ag.rating IS NULL ORDER BY addid LIMIT 3) As g ON a.addid = g.addid
WHERE a.addid = nj.condition_3.addid;

I have written a function to overcome this Error. So now it is working fine.
CREATE OR REPLACE FUNCTION geocode_all_values() RETURNS VOID AS
$$
DECLARE
r record;
g record;
BEGIN
FOR r IN select * from TableName where rating is null order by Sno
LOOP
BEGIN
FOR g IN select * from geocode_intersection(r.Street1,r.Street2,r.state,r.city,'',1)
LOOP
update TableName
set new_address = pprint_addy(g.addy),
rating = g.rating,
points = ST_AsTEXT(g.geomout)
where sno = r.sno;
END LOOP;
EXCEPTION WHEN OTHERS THEN
END;
END LOOP;
END;
$$
LANGUAGE plpgsql;

Related

How to use cursor results in a query in stored procedure

I am trying to get the variable (ACTIVE_INVENTORY) value from sql query dynamically and use it in further below queries. But it seems to be giving error.
Please suggest how could a variable be used in following query.
Thanks
create or replace procedure sp()
returns table (vin varchar, listing_date date, sale_date date, active_inventory boolean)
language sql
as
$$
declare
select_query varchar;
SOLD_THRESHOLD_DATE date;
c1 cursor for select max(sale_date) from TBL;
res resultset;
begin
open c1;
fetch c1 into SOLD_THRESHOLD_DATE;
select_query := 'select vin,listing_date,sale_date,
case when 60 >= DATEDIFF(Day,sale_date,SOLD_THRESHOLD_DATE) then 1 else 0 end as active_inventory from
TBL limit 10';
res:= (execute immediate : select_query);
close c1;
return table(res);
end;
$$;
call sp();
Uncaught exception of type 'STATEMENT_ERROR' on line 13 at position 9 : SQL compilation error: error line 2 at position 41 invalid identifier 'SOLD_THRESHOLD_DATE'
Parametrizing the query:
select_query := 'select vin,listing_date,sale_date,
case when 60>=DATEDIFF(Day,sale_date,?) then 1 else 0 end as active_inventory
from TBL limit 10';
res:= (execute immediate :select_query using (SOLD_THRESHOLD_DATE) );

Insert Rows in the Database which should be conditional if exist then update value else insert

I have function where I insert rows in mapping table without any validation but I am facing an issue that if the value already exist in the database, it should update a flag of isactive to true instead of inserting a new rows in database.
Postgres version is 9.4 and below is my function to insert records:
CREATE OR REPLACE FUNCTION cloudschema.org_retailer_map(
j integer[],
l integer[])
RETURNS integer AS
$BODY$
BEGIN
insert into retailer_org_map(org_id,supplier_id,isactive)(
SELECT org_id[i],supplier_id[i],isactive[1]
FROM (
SELECT generate_series(1, array_upper(org_id, 1)) AS i,supplier_id,org_id,isactive
FROM (SELECT $1 supplier_id ,$2 org_id,ARRAY[true] isactive) t) t);
return 1;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

Stored Procedure not returning data based on IF condition

I have a stored procedure in which I am checking if a table returns any rows. If no rows are returned then just return an empty/dummy result set. If rows are returned then return the same result set.
Here's the procedure
BEGIN
Declare #HAS_ROWS int
SELECT #HAS_ROWS(SELECT COUNT(*) AS HAS_ROWS FROM Table1)
If(#HAS_ROWS <= 0)
BEGIN
SELECT TOP 1 NULL FROM Table1
Return
END
Else
BEGIN
SELECT * FROM Table1
Return
END
END
Upon running this procedure I get the following result
(No column name)
0
HAS_ROWS
NULL
Title
This is title of row1
This is title of row2
As you can see it is returning 3 result sets and I expect it to return on only based on IF condition. What am I doing wrong?
#Aaron is right with the #Has_Rows - it needs to be assigned with SELECT #HAS_ROWS = ... or SET #HAS_ROWS = ... (the latter has more restrictions on use).
Here is a fixed / simplified version that should work for you:
BEGIN
IF((SELECT COUNT(*) FROM Table1) = 0)
SELECT NULL
ELSE
SELECT * FROM Table1
RETURN
END

function or stored procedure for bulk insert in table by sets

how can i convert the following to teradata stored procedure or some function :
WHILE EXISTS (SELECT * FROM #temp_set1)
BEGIN
/*group of statemnts :delete insert etc
like */
INSERT INTO #temp_set
SELECT TOP 200 * FROM #temp_set1;
INSERT INTO Activepull
as select * from #temp_set1
and this should occur for each set of 200 untill all inserts
end;
There are more than 60000 rows in #temp_set1 so want to insert by sets.
Thanks.
Written on my phone, but I would use the over expression. It creates a kind of pseudo Identity column that you can then use to paginate. And you can even choose the order based on an order by clause.
Declare #IntervalSize int = 100
Declare #BeginSet int = 0,
#EndSet int = #IntervalSize
While #Counter < (Select Max(ROW_NUMBER() OVER (ORDER BY someColumn desc) From #temp_set1)
Begin
Insert Into #temp_set
Select *, Row_Number() Over (Order By someColumn desc) As MyIdentity
Where MyIdentity Between #BeginSet And #EndSet
Select #BeginSet = #BeginSet + #IntervalSize,
#EndSet = #EndSet + #IntervalSize
End

Firebird and stored procedures: if exists then else

I'm trying to create a stored procedure for firebird 2.1 (this is the version which is to be used)
But am getting a bit stuck, so any help is appreciated.
The final version should compare 4 values agains the table, and retreive either the primaryid if the value exists, or create the new entry in the table, and return the new primaryid.
But I get stuck with only one value lookup, and it's not even using the variable yet.
SET TERM ^ ;
CREATE PROCEDURE TESTSP
( A Varchar(64) )
RETURNS
( RESULT Integer )
AS
BEGIN
IF (EXISTS (SELECT PRIMARYID FROM TABLENAME WHERE FIELD = 'Some string')) then
SELECT PRIMARYID FROM TABLENAME WHERE FIELD = 'Some string' into :primaryid;
result = PRIMARYID;
ELSE
INSERT INTO TABLENAME (FIELD) VALUES ('Some string');
result = gen_id(GEN_TABLEID, 0);
END^
SET TERM ; ^
I get a "Token unknown" for the Else command.
Update after responses:
Now I want to use the 4 variables and return the 4 results.
I think I need a for loop to do so, but with firebird, the for function means something else.
So what would be the way to go?
SET TERM ^ ;
CREATE PROCEDURE TESTSP
( value1 Varchar(64) )
RETURNS
( RESULT1 Integer )
AS
BEGIN
IF (EXISTS (SELECT PRIMARYID FROM TABLENAME WHERE FIELD = :value1)) then
SELECT PRIMARYID FROM TABLENAME WHERE FIELD = value1 into :result1;
ELSE BEGIN
result1 = gen_id(GEN_TABLEID, 1);
INSERT INTO TABLENAME (PRIMARYID, FIELD) VALUES (:result1, :value1);
END
suspend;
END^
SET TERM ; ^
As Tico already answered you have to use begin / end to group multiple statements in then / else part. The error abut column PRIMARYID being unknown is because you reference to it without having declared a local variable for it. Try this:
CREATE PROCEDURE TESTSP ( A Varchar(64) )
RETURNS ( RESULT Integer )
AS
BEGIN
-- initialize the result
Result = NULL;
-- check is the string already in table
SELECT PRIMARYID FROM TABLENAME WHERE FIELD = 'Some string' into :Result;
IF (Result is NULL) then
INSERT INTO TABLENAME(PRIMARYID, FIELD) VALUES(gen_id(GEN_TABLEID, 1), 'Some string') RETURNING PRIMARYID INTO :Result;
END^
I think your stored procedure should look like this:
SET TERM ^ ;
CREATE PROCEDURE TESTSP
( A Varchar(64) )
RETURNS ( result Integer )
AS
BEGIN
IF (EXISTS (SELECT PRIMARYID
FROM TABLENAME
WHERE FIELD = 'Some string')) then
SELECT PRIMARYID
FROM TABLENAME
WHERE FIELD = 'Some string'
into :result;
ELSE BEGIN
result = gen_id(GEN_TABLEID, 1);
INSERT INTO TABLENAME
(PRIMARYID, FIELD)
VALUES (:result, 'Some string');
END
END^
SET TERM ; ^
If you have multiple instruction for then and/ or else clause you must use BEGIN ... END-block!
SET TERM ^ ;
CREATE PROCEDURE TESTSP
( A Varchar(64) )
RETURNS
( RESULT Integer )
AS
BEGIN
IF (EXISTS (SELECT PRIMARYID FROM TABLENAME WHERE FIELD = 'Some string')) then
BEGIN
SELECT PRIMARYID FROM TABLENAME WHERE FIELD = 'Some string' into :primaryid;
result = PRIMARYID;
END
ELSE
BEGIN
INSERT INTO TABLENAME (FIELD) VALUES ('Some string');
result = gen_id(GEN_TABLEID, 0);
END
END^
SET TERM ; ^

Resources