DB2-LUW: UNION in Stored Procedure - stored-procedures

I'm trying to run the following simple select in a stored procedure:
P1: BEGIN
DECLARE v_uid INTEGER;
SELECT UID
INTO v_id
FROM TableA
UNION
SELECT UID
FROM TableB
;
END P1
It works fine on a z/OS database but with a LUW database I receive the following error:
Create‬‎ ‪stored‬‎ ‪procedure‬‎ ‪returns‬‎ ‪SQLCODE‬‎:‪‬‎ ‪‬‎-‪104‬‎,‪‬‎ ‪SQLSTATE‬‎:‪‬‎ ‪42601‬‎.‪
TEST‬‎:‪‬‎ ‪25‬‎:‪‬‎ ‪An‬‎ ‪unexpected‬‎ ‪token‬‎ ‪‬‎"‪SELECT UID
FROM TABLEB"‬‎ ‪was‬‎ ‪found‬‎ ‪following‬‎ ‪‬‎"FROM TABLEA UNION"‬‎.‪‬‎
Expected‬‎ ‪tokens‬‎ ‪may‬‎ ‪include‬‎:‪‬‎ ‪ ‬‎"‪‪<space>"‬‎.‪‬‎.‪‬‎
‪SQLCODE‬‎=‪‬‎-‪104‬‎,‪‬‎ ‪SQLSTATE‬‎=‪42601‬‎,‪‬‎ ‪DRIVER‬‎=‪4‬‎.‪24‬‎.‪92
Is the use of the UNION keyword not allowed on LUW?

You have to put union inside a subselect like
select uid into v_id from
(select uid from tablea
union select uid from tableb);

Related

Is there any way to append the variable in big query select in stored procedure

I am trying to call the variable in a select query like below:
BEGIN
DECLARE TGT_LOAD_STATUS_TBL STRING;
SET TGT_LOAD_STATUS_TBL=''||PROJ_ID||'.'||TGT_SCHEMA||'.'||LOAD_STATUS_TBL||'';
FOR FETCH_TEST IN (select col1 from TGT_LOAD_STATUS_TBL WHERE LOAD_STATUS='N')
DO
INSERT INTO project.datasetid.table VALUES(FETCH_TEST.col1);
END FOR;
END
Is there any way to append the variable in a select query?
You can use build your SQL statement by concatenating some strings together and then execute it using EXECUTE IMMEDIATE. This is exactly the use case that EXECUTE IMMEDIATE exists for
I don't think it's a good practice to update a table one by one within a loop.
Instead consider a bulk update using a dynamic sql like below
EXECUTE IMMEDIATE FORMAT("""
INSERT INTO table1
SELECT col1 FROM `%s` WHERE LOAD_STATUS='N'
""", TGT_LOAD_STATUS_TBL);
Test Query:
DECLARE TGT_LOAD_STATUS_TBL DEFAULT 'table2';
CREATE TEMP TABLE table1 (col1 STRING);
CREATE TEMP TABLE table2 AS
SELECT 'a' col1, 'N' LOAD_STATUS UNION ALL
SELECT 'b', 'Y' UNION ALL
SELECT 'c', 'N' UNION ALL
SELECT 'd', 'N' UNION ALL
SELECT 'e', 'N' ;
EXECUTE IMMEDIATE FORMAT("""
INSERT INTO table1
SELECT col1 FROM `%s` WHERE LOAD_STATUS='N'
""", TGT_LOAD_STATUS_TBL);
SELECT * FROM table1;

Solve the syntax error with Redshift operator does not exist and add explicit casts

I am a newbie in the area of redshift data modeling and got myself into trouble with an error.ERROR:
--Final version
syntax error ERROR: operator does not exist: text | record Hint: No
operator matches the given name and argument type(s). You may need to
add explicit type casts. Where: SQL statement "SELECT 'create temp
table ' || $1 || ' as select * from' | $2 |" PL/pgSQL function "egen"
line 36 at execute statement [ErrorId:
1-61dc32bf-0a451f5e2c2639235abb8876]
I am trying to do a simple transformation that gets returned in output when the procedure is called. (As of now I got to find from the documentation we have to use either temp table or cursors to achieve this)
Pseudocode:
I am trying to restrict data to its latest one in (2019) Get the
list of managers create columns if a person is a manager or not from the list.
Return it as a result
Data looks as follows Employee Data
My Select query works fine out of the procedure, please find my complete code below.
CREATE OR REPLACE PROCEDURE EGEN(tmp_name INOUT varchar(256) )
AS $$
DECLARE
--As i have less data managed to create it as an array or please use temp or table and join it with the actual query to perform transformation
MGR_RECORD RECORD;
DATAS RECORD;
item_cnt int := 0;
V_DATE_YEAR int := 0;
BEGIN
--EXECUTE (select cast(extract(year from current_date) as integer)-3) INTO V_DATE_YEAR;
--Manager Records are stored here below
SELECT DISTINCT managerid from "dev"."public"."emp_salary" INTO MGR_RECORD;
SELECT employeeid,
managerid,
promotion,
q_bonus,
d_salary,
case when contractor = 'x'
then 'TemporaryEmployee'
else 'PermanentEmployee'
END as EmployeeType,
-- IFstatement not supported under select query
case when employeeid in (select distinct managerid FROM "dev"."public"."emp_salary" )
then 'Manager'
else 'Ordinary FTE'
END as FTETYPE
FROM "dev"."public"."emp_salary" where cast(extract(year from promotion) as int ) >= 2019 into DATAS;
--COMMIT;
tmp_name := 'ManagerUpdatedTable';
EXECUTE 'drop table if exists ' || tmp_name;
EXECUTE 'create temp table ' || 'ManagerUpdatedTable' || ' as select * from' |DATAS| ;
END;
$$ LANGUAGE plpgsql;
-- Call tests CALL EGEN('myresult'); SELECT * from myresult;
Also, additional query (Can we replace )
case when employeeid in (select distinct managerid FROM "dev"."public"."emp_salary" )
then 'Manager'
else 'Ordinary FTE'
END as FTETYPE
this transform in query to IF , if possible please provide details.
Thanks and Regards,
Gabby

How to get the table name from a column in a join query with SQL Server and FIREDAC?

I looking for get metadata on a TFDQuery (FireDAC).
I have this query:
SELECT *
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.Code = t2.code
I would like to know the column information (table name, the real column name in the table, ....)
I find this post : How to get the table name from a field in a join query with MSSQL? (mysql_field_table equivalent) but I have not the same structure on FireDac.
As RBA already mentioned you have to enable ExtendedMetaData in the connection first. When done you can get the field column description via query.GetFieldColumn(field) and access the table and column name with its ActualOriginTabName and ActualOriginColName properties.
column := query.GetFieldColumn(field);
orgTableName := column.ActualOriginTabName;
orgColumnName := column.ActualOriginColName;

How to get foreign key value from Stored Procedure while showing the list.?

Following is the procedure that i have written in my application. But i want the LogSource Column in my list, but i am not able to get it from this stored procedure.
CREATE PROCEDURE [dbo].[GetApplicationLogs]
-- Add the parameters for the stored procedure here
#Skip int,
#Pagesize int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
WITH TableDatawithRowNumber AS
( SELECT dbo.ApplicationLog.* ,ROW_NUMBER() OVER (ORDER BY LoggedDate DESC) AS RowNumber,
(SELECT COUNT(*) AS Expr1
FROM ApplicationLog ) AS TotalRecords
from ApplicationLog
)
SELECT * FROM TableDatawithRowNumber
WHERE RowNumber > #Skip AND RowNumber <= (#Pagesize+#Skip)
END
This table doensn't contain a LogSource column but it is having LogSourceID in it which is a foreign key in this table and the primary key in LogSource Table. I want to show that in my list but i am not able to get it in the view. I can only use LogSourceId but not LogSource. So please help me.
I think you just need to do a left join on the LogSource table
WITH TableDatawithRowNumber AS
( SELECT dbo.ApplicationLog.* ,ROW_NUMBER() OVER (ORDER BY LoggedDate DESC) AS RowNumber, logSource.LogSource
(SELECT COUNT(*) AS Expr1
FROM ApplicationLog ) AS TotalRecords
from ApplicationLog as appLog
left join LogSource as logSource on appLog.LogSourceId = logSource.LogSourceId
)

Stored procedure execute Immediate error with WHERE clause

I am trying to copy over one row from my archive table to my original table.
Without my WHERE clause, the whole table of table2 gets copied to table1.
I don't want this of course. So based on the gridview's ID value listed, the table will copy over only the row whose ID is the same.
When I debug the lines I get the correct ID listed for DisplaySup.Rows(0).Cells(2).Text.
(
val_ID table2.V_ID%type
)
is
begin
execute immediate 'insert into table1 (select * from table2 where V_ID = val_ID)';
end;
Yet I get the error
ORA-00904: "VAL_ID": invalid identifier
Table2 and Table1 have identical columns; so they both have column titled V_ID. I am unsure why Val_ID is flagging an error.
VB.net line of coding:
SupArchive.Parameters.Add("val_ID", OleDbType.VarChar).Value = DisplaySup.Rows(0).Cells(2).Text
So I tried to reference: EXECUTE IMMEDIATE with USING clause giving errors
Like so to fix WHERE:
(
val_ID table2.V_ID%type
)
is
begin
execute immediate 'insert into table1 (select * from table2 where V_ID = '||val_ID||')';
end;
but I get error:
ORA-00904: "val_ID": invalid identifier
Any suggestions on how to fix my stored procedure?
UPDATE:
Tried to do the suggested:
(
val_ID table2.V_ID%type
)
AS
BEGIN
execute immediate 'insert into table1 (col1, col2, col3...)(select col1, col2, col3... from table2 where V_ID = :val_ID)' using val_ID;
end;
but get error:
ORA-00904: "col72": invalid identifier
for col72 after Select statement
EXAMPLE OF MY TABLES (both are identical) purpose of table2 is when a row is deleted in table1, table2 can re-create the user that was deleted
Table1
ID CompanyName FirstName LastName ....(72 cols)
Table2
ID CompanyName FirstName LastName... (72 cols)
You would do best to use a bind variable in your insert statement. Also, you need to list the columns you're inserting into as well as those you're inserting, to avoid the "too many values" error.
Eg:
declare
val_ID table2.V_ID%type := 1;
begin
execute immediate 'insert into table1 (col1, col2, ...) (select col1, col2, ... from table2 where V_ID = :val_ID)' using val_id;
end;
/
Although in this instance there is absolutely no need to use dynamic sql at all, so you could just do:
declare
val_id table2.v_id%type := 1;
begin
insert into table1 (col1, col2, ...)
select col1, col2, ...
from table2
where v_id = val_id;
end;
/
Don't forget to commit after you've run the procedure!

Resources