Delphi - what am I missing in this query - sql

I am trying to run this query but fail :
procedure TForm4.FormShow(Sender: TObject);
begin
with ClientDataSet1 do
begin
ClientDataSet1.Close;
ClientDataSet1.CommandText :='';
ClientDataSet1.CommandText :='select lokacije.[LOKACIJA_ID],lokacije.[RESORT_ID],'
+ 'lokacije.[HOTEL_ID],lokacije.[NAZIV],'
+ 'uporabniki.[RESORT_ID],uporabniki.[HOTEL_ID],uporabniki.[LOKACIJA_ID],'
+ 'uporabniki.[UPORABNIK],uporabniki.[GESLO],uporabniki.[PRAVICE] from LOKACIJE'
+ 'inner join UPORABNIKI on lokacije.[LOKACIJA_ID]=uporabniki.[LOKACIJA_ID]'
+ 'where lokacije.[NAZIV] = ''' + Form2.AdvOfficeStatusBar1.Panels[3].Text + ''' '
+ 'ORDER BY Uporabniki.[UPORABNIK]';
ClientDataSet1.Open;
end;
end;
I get the error : "Remote error: No such table :LOKACIJEinner"
What am I missing here ???
Database is SQLite. The form that I am opening here is a modal one.The whole app is a datasnap one.This is Client side. Problem is actually this : I have many locations and I only need the data from the name of the location displayed by AdvOfficeStatusBar1.Panels[3].Text.

I think that this is more readable
procedure OpenLokacije(ANaziv: String);
begin
ClientDataSet1.Close;
ClientDataSet1.CommandText := ' select lokacije.[LOKACIJA_ID],'+ // AS Lok_LOKACIJA_ID
' lokacije.[RESORT_ID],'+
' lokacije.[HOTEL_ID],'+
' lokacije.[NAZIV],'+
' uporabniki.[RESORT_ID],'+
' uporabniki.[HOTEL_ID],'+
' uporabniki.[LOKACIJA_ID],'+ // AS Upor_LOKACIJA_ID
' uporabniki.[UPORABNIK],'+
' uporabniki.[GESLO],'+
' uporabniki.[PRAVICE]'+
' from LOKACIJE'+
' inner join UPORABNIKI on lokacije.lokacija_id=uporabniki.lokacija_id '+
' where lokacije.[NAZIV] = :#NAZIV'+
' order by Uporabniki.[UPORABNIK]';
ClientDataSet1.Parameters.ParamByName('#NAZIV').Value:= ANaziv;
ClientDataSet1.Open;
end;
lokacije.lokacija_id and uporabniki.lokacija_id are the same value and field respectively.
use AS:
lokacije.lokacija_id as lok_lokacija_id
uporabniki.lokacija_id as upo_lokacija_id
Also use the schema of the database like
dbo.uporabniki.lokacija_id

Related

Relation "" already exist dynamic query

I'm trying to execute a query within a loop which is within another loop, which is within an anonymous code block.
I'm trying to run this query
query := 'CREATE VIEW hopsPartialDistance AS '
||'SELECT AvgDistance '
||'FROM Distance '
||'WHERE PlanetOrigin = ' || rHops.PlanetOrigin
||' AND PlanetDestination = ' || rHops.PlanetDestination;
EXECUTE query;
But I keep getting the error
relation "hopspartialdistance" already exists
I then run
\d hopspartialdistance;
And the output is
Did not find any relation named "hopspartialdistance".
So I don't know where the error is coming from.
Here's the full function
DO
$$
DECLARE
routeDistance real := 0.0;
hopDistance real := 0.0;
rRoute record;
rHops record;
query text := '';
BEGIN
FOR rRoute IN
SELECT MonitoringKey FROM TradingRoute
LOOP
query := 'CREATE VIEW PortsOfCall AS '
||'SELECT PlanetID, VisitOrder '
||'FROM EnrichedCallsAt '
||'WHERE MonitoringKey = ' || rRoute.MonitoringKey
||' ORDER BY VisitOrder';
EXECUTE query;
CREATE VIEW Hops AS
SELECT A.PlanetID AS PlanetOrigin,
B.PLanetID AS PlanetDestination
FROM PortsOfCall A INNER JOIN PortsOfCall B ON A.VisitOrder + 1 = B.VisitOrder;
routeDistance = 0.0;
FOR rHops IN
SELECT PlanetOrigin, PlanetDestination FROM Hops
LOOP
query := 'CREATE VIEW hopsPartialDistance AS '
||'SELECT AvgDistance '
||'FROM Distance '
||'WHERE PlanetOrigin = ' || rHops.PlanetOrigin
||' AND PlanetDestination = ' || rHops.PlanetDestination;
EXECUTE query;
hopDistance = (SELECT SUM(AvgDistance) FROM hopsPartialDistance) ;
routeDistance = routeDistance + hopDistance;
END LOOP;
INSERT INTO RouteLength (RouteMonitoringKey, RouteTotalDistance)
SELECT rRoute.MonitoringKey, routeDistance;
DROP VIEW Hops
CASCADE;
DROP VIEW PortsOfCall
CASCADE;
END LOOP;
END;
$$;

How can i turn this pl/sql into a procedure

I had to write this query for an assignement. So we have a database and we are pulling information from it, this is going to work with some back end c# eventually. Is there anything i can do , knowing im going to reuse this, in order to make it better and more adaptable when the day comes when i have to connect it all.
set serveroutput on
DECLARE
LV_DATE HVK_RESERVATION.RESERVATION_START_DATE%TYPE;
LV_SERV VARCHAR(100);
CURSOR LCUR_RES IS
SELECT *
FROM HVK_RESERVATION R
INNER JOIN HVK_PET_RESERVATION PR
ON R.RESERVATION_NUMBER = PR.RES_RESERVATION_NUMBER
INNER JOIN HVK_PET P
ON P.PET_NUMBER = PR.PET_PET_NUMBER
INNER JOIN HVK_OWNER OW
ON OW.OWNER_NUMBER = P.OWN_OWNER_NUMBER
WHERE R.RESERVATION_START_DATE < LV_DATE
AND R.RESERVATION_END_DATE > LV_DATE;
CURSOR LCUR_SERVICE(PET_RES_NUM NUMBER) IS
SELECT *
FROM HVK_SERVICE S
INNER JOIN HVK_PET_RESERVATION_SERVICE PRS
ON PRS.SERV_SERVICE_NUMBER = S.SERVICE_NUMBER
AND PRS.PR_PET_RES_NUMBER = PET_RES_NUM;
BEGIN
LV_DATE := TO_DATE('&logdate', 'yy-mm-dd');
DBMS_OUTPUT.PUT_LINE('Kennel log for ' || '' || LV_DATE);
DBMS_OUTPUT.PUT_LINE('-------------------------------');
FOR I IN LCUR_RES LOOP
DBMS_OUTPUT.PUT_LINE('Run:' || '' || I.RUN_RUN_NUMBER || ' ' ||
'Pet: ' || '' || I.PET_NAME || ' ' ||
I.OWNER_LAST_NAME || ' Pet Reservation: ' || '' ||
I.PET_RES_NUMBER);
DBMS_OUTPUT.PUT_LINE('Reservation start/end ' || ' ' ||
I.RESERVATION_START_DATE || ' ' ||
I.RESERVATION_END_DATE);
DBMS_OUTPUT.PUT('Services : ');
FOR X IN LCUR_SERVICE(I.PET_RES_NUMBER) LOOP
DBMS_OUTPUT.PUT(X.SERVICE_DESCRIPTION || ' ');
END LOOP;
DBMS_OUTPUT.PUT_LINE('');
FOR LREC_LOG IN (SELECT *
FROM HVK_KENNEL_LOG KL
WHERE KL.PR_PET_RES_NUMBER = I.PET_RES_NUMBER
) LOOP
DBMS_OUTPUT.PUT_LINE('Notes: ' || '' ||
LREC_LOG.KENNEL_LOG_SEQUENCE_NUMBER || ' ' ||
'Log Note: ' || '' || LREC_LOG.KENNEL_LOG_NOTES);
END LOOP;
DBMS_OUTPUT.PUT_LINE(' ');
END LOOP;
END;
It it supposed to output the run number , reservation number , pet name , and any relate notes.
you can replace DECLARE with CREATE OR REPLACE PROCEDURE my_proc(in_logdate in date) IS.
in that case my_proc will be the name of your procedure.
you should also use a parameter instead of &logdate
so e.g. parameter name in_logdate of type date
...
LV_DATE := in_logdate;
...

Postgres Type of Parameter does not match

I am having an odd problem with Postgres (10.5). I have a function, generate_unique_name which takes in three text values. It works fine; however, calling this function seems to be an issue. When I call the function using:
SELECT generate_unique_name('basic', 'seeds', 'project=' || 2)
It works without issue. I can make the same call several times. Now, when I try the same call, but change the second parameter as below:
SELECT generate_unique_name('basic', 'queue', 'project=' || 2)
Then it seems to fail with the error:
ERROR: type of parameter 9 (text) does not match that when preparing
the plan (character varying) CONTEXT: PL/pgSQL function
generate_unique_name(text,text,text) line 12 at assignment SQL state:
42804
I have tried changing the query to:
SELECT generate_unique_name('basic'::text, 'queue'::text, ('project=' || 2)::text)
But this also fails. If I then kill the connection to postgres DB, and create a new one, and instead start with the second query, it now works, but the first stops functioning.
It seems like postgres decides to stop treating the parameters as text part way through, for no apparent reason. Am I missing something?
EDIT: Code for generate_unique_name
CREATE OR REPLACE FUNCTION public.generate_unique_name(
proposed_name text,
table_name text,
condition text)
RETURNS text
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE
unique_name text;
name_counter integer;
r record;
names_to_check text[];
BEGIN
unique_name = proposed_name;
name_counter = 0;
FOR r IN EXECUTE 'SELECT name FROM ' || table_name || ' WHERE ' || condition LOOP
names_to_check = array_append(names_to_check, r.name::text);
END LOOP;
WHILE unique_name = ANY(names_to_check) LOOP
name_counter = name_counter + 1;
unique_name = proposed_name || ' (' || name_counter || ')';
END LOOP;
RETURN unique_name;
END;
$BODY$;
My guess is there's a value in the name column of the queue table that causes an issue with
names_to_check = array_append(names_to_check, r.name::text)
As Joe mentioned, the issue was with the array_append, which I could not figure out a way to fix. Instead, the generate_unique_names functions was changed to just query the DB continuously.
CREATE OR REPLACE FUNCTION generate_unique_name (proposed_name text, table_name text, condition text) RETURNS text AS
$BODY$
DECLARE
unique_name text;
name_counter integer;
not_unique boolean;
BEGIN
unique_name = proposed_name;
name_counter = 0;
EXECUTE 'SELECT COUNT(*)!=0 FROM ' || table_name || ' WHERE ' || condition || ' AND name = ''' || unique_name || '''' INTO not_unique;
WHILE not_unique LOOP
name_counter = name_counter + 1;
unique_name = proposed_name || ' (' || name_counter || ')';
EXECUTE 'SELECT COUNT(*)!=0 FROM ' || table_name || ' WHERE ' || condition || ' AND name = ''' || unique_name || '''' INTO not_unique;
END LOOP;
RETURN unique_name;
END;
$BODY$ LANGUAGE plpgsql;

An SQL Query works fine when executed, But the same Query if I'm using in a PL/SQL it shows error

Hi I've the following query which works fine in SQL, I mean it gets executed successfully.
SELECT id_ligne, n_res_id, n_rty_id, NVL (res_va_text, va_res_txt),
NVL (res_va_short_name, va_res_short_name), bl_has_bo, bl_asset,
bl_needs_profile, bl_update_name, bl_popup_mandatory, va_popup_name,
va_itrack_create, va_itrack_delete, va_generic_mail,
n_application_type, bl_mono_profile
FROM t_t_actres_ea4, t_resource_ea4
WHERE res_n_id(+) = n_res_id
AND t_t_actres_ea4.id_ligne NOT IN (
SELECT DISTINCT (t_erralim_ea4.err_n_lineid)
FROM t_erralim_ea4
WHERE 0235303 = t_erralim_ea4.err_n_code_trt
AND err_n_rejecttype = 0)
It gets executed and the desired output is fetched. But when I use the same query for the PL/SQL like below.
L_REQ Varchar2(1000) := 'select ID_LIGNE, N_RES_ID, N_RTY_ID, NVL(RES_VA_TEXT,VA_RES_TXT),NVL(RES_VA_SHORT_NAME,VA_RES_SHORT_NAME), '||
' BL_HAS_BO, BL_ASSET, BL_NEEDS_PROFILE, BL_UPDATE_NAME, BL_POPUP_MANDATORY, VA_POPUP_NAME, ' ||
' VA_ITRACK_CREATE, VA_ITRACK_DELETE, VA_GENERIC_MAIL, N_APPLICATION_TYPE, BL_MONO_PROFILE ' ||
' from T_T_ACTRES_EA4, T_RESOURCE_EA4 ' ||
' where RES_N_ID (+) = N_RES_ID AND T_T_ACTRES_EA4.ID_LIGNE not in ( select distinct(T_ERRALIM_EA4.ERR_N_LINEID) ' ||
' from T_ERRALIM_EA4 ' ||
' where 0235307 = T_ERRALIM_EA4.ERR_N_CODE_TRT AND ERR_N_REJECTTYPE = 0 and T_ERRALIM_EA4.ERR_VA_MSG not like ''Mono-profile%'')';
It gives me the error saying ORA-00936: missing expression
Note: This error is caused when I append this conditon to the sub-query.
and T_ERRALIM_EA4.ERR_VA_MSG not like ''Mono-profile%''
TIA.
Assuming what you provided is what you want, no execute immediate: it cannot compile.
You have
variable declaration := sql statement
You should have
DECLARE
variable declaration
BEGIN
sql statement
END;
The sql statement should have SELECT INTO syntax
SELECT id_ligne, n_res_id, n_rty_id, NVL (res_va_text, va_res_txt),
NVL (res_va_short_name, va_res_short_name), bl_has_bo, bl_asset,
bl_needs_profile, bl_update_name, bl_popup_mandatory, va_popup_name,
va_itrack_create, va_itrack_delete, va_generic_mail,
n_application_type, bl_mono_profile
INTO LREQ
FROM t_t_actres_ea4, t_resource_ea4
WHERE res_n_id(+) = n_res_id
AND t_t_actres_ea4.id_ligne NOT IN (
SELECT DISTINCT (t_erralim_ea4.err_n_lineid)
FROM t_erralim_ea4
WHERE 0235303 = t_erralim_ea4.err_n_code_trt
AND err_n_rejecttype = 0);
#Bob Jarvis is spot on also - you could do
DECLARE
L_REQ Varchar2(1000) := 'select ID_LIGNE, N_RES_ID, N_RTY_ID, NVL(RES_VA_TEXT,VA_RES_TXT),NVL(RES_VA_SHORT_NAME,VA_RES_SHORT_NAME), '||
' BL_HAS_BO, BL_ASSET, BL_NEEDS_PROFILE, BL_UPDATE_NAME, BL_POPUP_MANDATORY, VA_POPUP_NAME, ' ||
' VA_ITRACK_CREATE, VA_ITRACK_DELETE, VA_GENERIC_MAIL, N_APPLICATION_TYPE, BL_MONO_PROFILE ' ||
' from T_T_ACTRES_EA4, T_RESOURCE_EA4 ' ||
' where RES_N_ID (+) = N_RES_ID AND T_T_ACTRES_EA4.ID_LIGNE not in ( select distinct(T_ERRALIM_EA4.ERR_N_LINEID) ' ||
' from T_ERRALIM_EA4 ' ||
' where 0235307 = T_ERRALIM_EA4.ERR_N_CODE_TRT AND ERR_N_REJECTTYPE = 0 and T_ERRALIM_EA4.ERR_VA_MSG not like ''Mono-profile%'')';
BEGIN
EXECUTE IMMEDIATE L_REQ;
END;
This is probably not the best choice, static SQL offers better performance a lot of the time.

SQL insert using stored procedure

I am fighting an error which is stopping my stored procedure from working:
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN SET lob' at line 1:"
Here is a portion of my IF/ELSEIF statement:
IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN
SET lobInsertStmt = ' AND p.PROJECTION_PROJECT_NME = ' || SELECTED_PROJECT_NAME
|| ' AND p.PROJECTION_PROJ_CATG_NME = ' || SELECTED_PROJECT_CATG
|| ' AND p.FINANCIAL_PROJECTION_YEAR_NUM = ' || CAST(SELECTED_PROJECT_YEAR AS int)
|| ' AND g.MODEL_GROUP_SNAPSHOT_TSP = ' || SELECTED_SNAPSHOT_TIMESTAMP;
What am I doing incorrectly and why won't my compare work? Thanks!
UPDATE:
My issue wasn't an IF/THEN compare. It was how the IN params were being read. Here is the solution to that:
IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN
SET lobInsertStmt = ' AND p.PROJECTION_PROJECT_NME = ''' || SELECTED_PROJECT_NAME || ''''
|| ' AND p.PROJECTION_PROJ_CATG_NME = ''' || SELECTED_PROJECT_CATG || ''''
|| ' AND p.FINANCIAL_PROJECTION_YEAR_NUM = ' || TRIM(CAST(SELECTED_PROJECT_YEAR AS int))
|| ' AND g.MODEL_GROUP_SNAPSHOT_TSP = ''' || SELECTED_SNAPSHOT_TIMESTAMP || '''';
Now, I am receiving an SQLSTATE of 07005 which is: "The cursor 'cursor-name' could not be used as specified because the prepared statement named in the declaration for the cursor was not a SELECT statement."
How can I do the insert with a stored procedure without the cursor?
Here is additional code:
REPLACE PROCEDURE "SCHEMA"."PROCEDURE_NAME" (
IN "SELECTED_PROJECT_NAME" VARCHAR(256) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_CATG" VARCHAR(256) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_YEAR" VARCHAR(4) CHARACTER SET LATIN,
IN "SELECTED_SNAPSHOT_TIMESTAMP" VARCHAR(28) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_TYPE" VARCHAR(6) CHARACTER SET LATIN,
IN "SELECTED_PROJECT_LOBSELECTION" VARCHAR(256) CHARACTER SET LATIN,
IN "SELECTED_LOB_NUMBERS" VARCHAR(256) CHARACTER SET LATIN,
IN "COPY_TO_PROJECT_NAME" VARCHAR(256) CHARACTER SET LATIN,
IN "REQUESTER_ID" VARCHAR(8) CHARACTER SET LATIN,
OUT "TEST_OUT" VARCHAR(5000) CHARACTER SET LATIN,
OUT "SQLSTATE_OUT" VARCHAR(5) CHARACTER SET LATIN,
OUT "SQLCODE_OUT" INTEGER)
DYNAMIC RESULT SETS 1
P1: BEGIN
DECLARE lobInsertStmt varchar(500);
DECLARE mystmt varchar(5000);
DECLARE CURSOR_C CURSOR WITH RETURN FOR PREPSTMT;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET SQLCODE_OUT = SQLCODE;
SET SQLSTATE_OUT = SQLSTATE;
SET TEST_OUT = mystmt;
END;
IF (SELECTED_PROJECT_LOBSELECTION = 'Copy the Whole Project') THEN
SET lobInsertStmt = ' AND p.PROJECTION_PROJECT_NME = ''' || SELECTED_PROJECT_NAME || ''''
|| ' AND p.PROJECTION_PROJ_CATG_NME = ''' || SELECTED_PROJECT_CATG || ''''
|| ' AND p.FINANCIAL_PROJECTION_YEAR_NUM = ' || TRIM(CAST(SELECTED_PROJECT_YEAR AS int))
|| ' AND g.MODEL_GROUP_SNAPSHOT_TSP = ''' || SELECTED_SNAPSHOT_TIMESTAMP || '''';
-- Other ElseIFs
END IF;
SET mystmt = 'INSERT INTO D_FAR_WORK_VW.V_COPY_MODEL_PROCESS_WORK'
|| ' SELECT reqt.RUN_ID,'''
|| SELECTED_PROJECT_NAME || ''' AS TO_PROJECTION_PROJECT_NME,'
|| ' m.PROJECTION_MODEL_SEQ_ID,'
|| ' m.PROJECTION_MODEL_ROW_SEQ_ID,'
|| ' p.PROJECTION_PROJECT_NME as FROM_PROJECTION_PROJECT_NME, '''
-- More insert code
PREPARE PREPSTMT FROM mystmt;
OPEN CURSOR_C;
SET TEST_OUT = mystmt;
SET SQLSTATE_OUT = SQLSTATE;
SET SQLCODE_OUT = SQLCODE;
END P1;
I answered my question. I removed the cursor and added an execute statement
EXECUTE PREPSTMT;
after the Prepare