about SQLCODE -104 (error) during select in DB2 - db2

I have been trying to adapt a working "INSERT" into a SELECT statement and keep finding a error -104
a)Can someone please help me understand the reason why the "." on "where" clause (below) works when I run with an "insert" but gives me an error when using on a "select" clause?
b)How should the "INSERT" criteria be written correctly when using a SELECT?
Many thanks in advance for any assistance on this question
Insert:
INSERT INTO SISPD2.SIS_DAILY_RECALC
(CIN_NUM,PGM_DIV_FG,NON_CA_FG,PGM_EXCPT_FG,WTW_FG)
(SELECT C.CIN_NUM, C.PGM_DIV_FG, C.NON_CA_FG, C.PGM_EXCPT_FG,
C.WTW_FG
FROM SISPD2.SIS_INDV C
WHERE C.CIN_NUM NOT IN (SELECT CIN_NUM FROM SISPD2.SIS_DAILY_RECALC)
------------------------------------------------------------------------
Select :
SELECT C.CIN_NUM ||','||
C.PGM_DIV_FG ||','||
C.NON_CA_FG ||','||
C.PGM_EXCPT_FG ||','||
C.WTW_FG ||','||
WHERE (C.CIN_NUM NOT IN (SELECT A.CIN_NUM
FROM SISPD2.SIS_DAILY_RECALC A));
DSNT408I SQLCODE = -104, ERROR: ILLEGAL SYMBOL ".". SOME SYMBOLS THAT MIGHT
BE LEGAL ARE: , FROM INTO
DSNT418I SQLSTATE = 42601 SQLSTATE RETURN CODE

You shouldn't be concatenating a statement together unless you're building a dynamic statement you intend to PREPARE and EXECUTE
SELECT C.CIN_NUM
, C.PGM_DIV_FG
, C.NON_CA_FG
, C.PGM_EXCPT_FG
, C.WTW_FG
WHERE (C.CIN_NUM NOT IN (SELECT A.CIN_NUM
FROM SISPD2.SIS_DAILY_RECALC A));

Related

Why I can not use IF in here?

I am trying to remove and drop a table if the the table has no data or empty, so I wrote this Statement in PostgreSQL, but I am encountering an error saying syntax error near IF.
I can divide this to 2 different SQL statements, but I want to run this as one query.
IF (SELECT COUNT(*) FROM ${tableName}) > 0
BEGIN
DROP TABLE ${tableName}
END
I also tried this:
IF (SELECT COUNT(*) FROM zzz > 0) THEN
DROP TABLE zzz
END IF
ERROR: syntax error at or near "SELECT"
LINE 2: SELECT COUNT(*) FROM zzz > 0
^
SQL state: 42601
Character: 7
If you want to do this with SQL, you'll have to use a DO statement:
DO
$$BEGIN
IF (SELECT Count(*) FROM zzz) > 0 THEN
DROP TABLE zzz;
END IF;
END;$$;

function crosstab(unknown, unknown) does not exist but it does

I have a crosstab function that I've used successfully many times in the past, but now it's dumping all the data at the end instead of pivoting it into the output table. It can't seem to find Crosstab. I've researched it doing the following;
create extension if not exists tablefunc; --- answer is: extension "tablefunc" already exists
create extension tablefunc with schema animals; answer is: as above
select count(*) from information_schema.routines where routine_name like 'crosstab%'; ---- answer is 6.
The following is a section of the function code:
BEGIN
str := '" " text,'; -- blanks in A1 cell
FOR rec IN SELECT DISTINCT col_name
FROM an_in_tbl
ORDER BY col_name
LOOP
str := str || '"' || rec.col_name || '" text' ||',';
END LOOP;
str:= substring(str, 0, length(str));
EXECUTE 'CREATE EXTENSION IF NOT EXISTS tablefunc;
DROP TABLE IF EXISTS an_out_tbl;
CREATE TABLE an_out_tbl AS
SELECT *
FROM crosstab(''select row_name, col_name, row_value from an_in_tbl order by 1'',
''SELECT DISTINCT col_name FROM an_in_tbl ORDER BY 1'')
AS final_result ('|| str ||')';
select animal_pivot_fn()
NOTICE: extension "tablefunc" already exists, skipping
NOTICE: table "an_out_tbl" does not exist, skipping
ERROR: function crosstab(unknown, unknown) does not exist
LINE 5: FROM crosstab('select row_name, col_name, row_value from...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
QUERY: CREATE EXTENSION IF NOT EXISTS tablefunc;
DROP TABLE IF EXISTS an_out_tbl;
CREATE TABLE an_out_tbl AS
SELECT *
FROM crosstab('select row_name, col_name, row_value from an_in_tbl order by 1',
'SELECT DISTINCT col_name FROM an_in_tbl ORDER BY 1')
AS final_result (" " text,"CAT" text,"DOG" text,"SNAKE" text,"HORSE" text,"ELEPHANT" text,"MOUSE" text,"MONKEY"... and many more... HERE IS WHERE THE DATA GETS DUMPED AND NO PIVOTED TABLE GETS CREATED.
Need to run below query
Run \dx command .
if result like below need to run following query
CREATE EXTENSION tablefunc;
Run \dx command again,result should be like below.
Now you can run crosstab query it should be solved.

Remove parenthesis in postgresql loop

Can someone help me understand why I get a parenthesis around the schemaname nspname? And/or, a way to remove it, so the loop will work?
DO $$
DECLARE
views_ CURSOR FOR
SELECT nspname
FROM pg_catalog.pg_namespace
WHERE nspname LIKE '%scemanames%';
BEGIN
FOR nspname IN views_ LOOP
EXECUTE 'INSERT INTO forkert_ejendom_roert SELECT * FROM ' || nspname || '.viewname';
-- Do something with nbRow
END LOOP;
END$$;
The output i get is:
ERROR: syntax error at or near ")"
LINE 1: ...m_roert SELECT * FROM ('schemanames).bbr_punk...
^
QUERY: INSERT INTO forkert_ejendom_roert SELECT * FROM (name of the schema).viewname
CONTEXT: PL/pgSQL function inline_code_block line 9 at EXECUTE
********** Error **********
ERROR: syntax error at or near ")" SQL state: 42601
Context: PL/pgSQL function inline_code_block line 9 at EXECUTE
The loop variable is a record (actually containing a single column), try:
FOR rec IN views_ LOOP
EXECUTE 'INSERT INTO forkert_ejendom_roert SELECT * FROM ' || rec.nspname || '.viewname';

PostgreSQL left join with alias in a loop

Is it possible to iterate over a table's records and make a left join with them in a stored procedure?
Something like this:
FOR r IN SELECT tablename FROM tablewithtablenames ORDER BY tablename ASC
LOOP
INSERT INTO temp_Results
SELECT
temp_ids.Key as Key,
loggedvalue.pk_timestamp,
FROM
(temp_idS AS temp_ids
LEFT JOIN
quote_ident(r.tablename) AS loggedvalue
ON temp_ids.Key = loggedvalue.pk_fk_id);
END LOOP;
Unfortunately i get the following error message when i want to execute the stored procedure. (Function creation was successful.)
Error message:
ERROR: column loggedvalue.pk_fk_id does not exist LINE 29:
ON temp_ids.Key = "loggedvalue...
I have the feeling that i convert the record in a wrong way maybe because when i manually replaced the quote_ident(r.tablename) to the name of the table that i know the r contains it was fine, also i traced out the r.tablename in the loop and it was correct also.
As a_horse_with_no_name pointed out i should have use dynamic sql because in plpgsql you can not use a variable as a table name so i eliminated the loop and i used a union all:
CREATE OR REPLACE FUNCTION getaffectedtables(
OUT tableNames TEXT)
as $$
BEGIN
SELECT TRIM(TRAILING ' UNION ALL ' FROM string_agg('','SELECT * FROM "' || "tablename" || '" UNION ALL '))
INTO tableNames
FROM exampleTable;
END;$$
LANGUAGE plpgsql;
Then i used dynamic execute:
DECLARE
affectednames TEXT;
BEGIN
affectednames := getaffectedtables();
EXECUTE '
SELECT
temp_ids.Key as Key,
loggedvalue.pk_timestamp,
FROM
(temp_idS AS temp_ids
LEFT JOIN
('|| affectednames ||') AS loggedvalue
ON temp_ids.Key = loggedvalue.pk_fk_id);';

Using IF Exists function in postgreSQL pgadmin3 (syntax error ,SQL state: 42601 Character: 1)

I am trying to execute an SQL statement in pgadmin3 that do the following:
If a student with a specific name and age already exists then get the student_id else insert a new record with the specified name and age and then get the created student_id
I have tried this code:
IF EXISTS (SELECT 1 FROM main.student WHERE studentname='hhh' and studentage=15)
BEGIN
SELECT student_id FROM main.student WHERE studentname='hhh' and studentage=15
END
ELSE
BEGIN
INSERT INTO main.student(studentname,studentage) VALUES('hhh',15)
END;
END IF;
But I am always getting this error:
syntax error at or near "IF"
SQL state: 42601
Character: 1
Can you please tell me what I am doing wrong. Also how can I get the student_id after the insert statement?
Actually your statement is not SQL. it is PL/PGSQL statement.
So obviously when you send this to Postgres as SQL query it will throw an exception.
If you are doing this from pgAdmin3 it has nice feature to run pl/psql scripts. use it
IF EXISTS (SELECT 1 FROM main.student WHERE studentname='hhh' and studentage=15) THEN
SELECT student_id FROM main.student WHERE studentname='hhh' and studentage=15;
ELSE
INSERT INTO main.student(studentname,studentage) VALUES('hhh',15);
END IF;
Some points you need to consider:
For IF statement, you need to use THEN
To run just one syntax, you don't need the BEGIN/END
Use ; at the end of each statement
Also if you are running an ad-hoc statement, you need to run it within DO command
DO
$do$
IF EXISTS (SELECT 1 FROM main.student WHERE studentname='hhh' and studentage=15) THEN
SELECT student_id FROM main.student WHERE studentname='hhh' and studentage=15;
ELSE
INSERT INTO main.student(studentname,studentage) VALUES('hhh',15);
END IF;
END
$do$
For the last part of your question, you can return the id you are inserting
INSERT INTO main.student(studentname,studentage) VALUES('hhh',15) RETURNING student_id