SQL queries to pull data from IBM i (AS400) - How to separate multiple queries - ssrs-2008

What is the query separator used in AS400 to run multiple statements in same SQL . We have GO statement in MS SQL similarly I though semicolon is used in AS400 to separate multiple queries but for some reason it’s not working.
I actually have multiple steps in this query
Crete a GLOBAL TEMPORARY TABLE
Insert the data in to this Global temp table
Some logic to update the data on this Global temp table by
joining with other table.
Select the value from this Global temp table
When I use semicolon to separate each step I get error saying semicolon is not recognized as query separator… Below is the snippet of the query
DECLARE GLOBAL TEMPORARY TABLE SESSION.FinalRes
(
SLSTRTY CHAR(4)
,SLSMAN CHAR(5)
,CSTNAM CHAR(30)
,CustN CHAR(16)
,ADR1 CHAR(30)
,ADR4 CHAR(30)
,"STATE" CHAR(2)
,ZIPCD CHAR(12)
,DTEADDED DATE
,SalesCM DECIMAL(22,7)
,SalesYTD DECIMAL(22,7)
,SalesPY DECIMAL(22,7)
,EXTGPCM DECIMAL(22,7)
,EXTGPYTD DECIMAL(22,7)
,EXTGPPY DECIMAL(22,7)
,GMYTD DECIMAL(22,7)
,GMCM DECIMAL(22,7)
,GMPY DECIMAL(22,7)
,SalesPYM DECIMAL(22,7)
,SalesPYTD DECIMAL(22,7)
,STATIND CHAR(1)
,CSTCLS CHAR(3)
,CSort NUMERIC(5)
) WITH REPLACE ON COMMIT PRESERVE ROWS ;
SELET * from SESSION.FinalRes
This is the error I get when I try to execute the query
SQL0104: Token ; was not valid. Valid tokens: END-OF-STATEMENT.
Cause . . . . . : A syntax error was detected at token ;. Token ;
is not a valid token. A partial list of valid tokens is
. This list assumes that the statement is correct
up to the token. The error may be earlier in the statement, but the
syntax of the statement appears to be valid up to this point. Recovery
. . . : Do one or more of the following and try the request again:
-- Verify the SQL statement in the area of the token ;. Correct the statement. The error could be a missing comma or quotation mark, it
could be a misspelled word, or it could be related to the order of
clauses. -- If the error token is , correct the SQL
statement because it does not end with a valid clause.

The DB2 for i SQL will prepare and execute [EXECUTE IMMEDIATE] only one dynamic statement per invocation. Although I have not had the opportunity to use the feature, since the DB2 for IBM i 7.1, there is apparently support for a Dynamic Compound Statement to be accepted. The statement separator [for both declarative and procedural statements] in a compound statement, is the semicolon.
http://www.itjungle.com/fhg/fhg011514-story02.html
Dynamic Compound Statements In DB2 For i
Published: January 15, 2014
by Michael Sansoterra

Probably this has already been accounted for, but your 'select' keyword is missing a 'c'. Also try putting an additional semicolon after the select statement.

Related

Nifi expression language for postgres "insert into" single quote varchars

I am trying to use nifi expression for
INSERT INTO public.demo (col1,col2,col3) VALUES (?,?,?) ON CONFLICT (col1) DO UPDATE set col2 = '${sql.args.2.value:replaceAll("*regex for single quote*","regex for double quote ")}'
So col2 is in a Oracle database often having a single quote.
Ex. " user's " which is creating problems for postgres insertion as postres uses a single quote to start and end varchar values.
I read about nifi expression language and am using it like the above but its throwing a syntax error.
What should it be like?
I guess I also need to be replacing the ? In values With the same sql.args.

Not able to drop schema in DB2 Using ADMIN_DROP_SCHEMA Stored Procedure

I found at several places to be able to drop a schema in DB2 along with all of its contents (indexes, SPs, triggers, sequences etc) using
CALL SYSPROC.ADMIN_DROP_SCHEMA('schema_name', NULL, 'ERRORSCHEMA', 'ERRORTAB');
However, I am getting the following error while using this command:
1) [Code: -469, SQL State: 42886] The parameter mode OUT or INOUT is not valid for a parameter in the routine named "ADMIN_DROP_SCHEMA" with specific name "ADMIN_DROP_SCHEMA" (parameter number "3", name "ERRORTABSCHEMA").. SQLCODE=-469, SQLSTATE=42886, DRIVER=4.22.29
2) [Code: -727, SQL State: 56098] An error occurred during implicit system action type "2". Information returned for the error includes SQLCODE "-469", SQLSTATE "42886" and message tokens "ADMIN_DROP_SCHEMA|ADMIN_DROP_SCHEMA|3|ERRORTABSCHEMA".. SQLCODE=-727, SQLSTATE=56098, DRIVER=4.22.29
Can anyone help me suggest what's wrong here? I tried to look at several places but didn't get any idea. It doesn't seem it's an authorization issue. Using DB2 version 11.5.
You are using the ADMIN_DROP_SCHEMA procedure parameters incorrectly, assuming you are CALLing the procedure from SQL and not the CLP.
The third and fourth parameters cannot be a literal (despite the documentation giving such an example), instead they must be host-variables (because the the procedure requires them to be input/output parameters).
If the stored-procedure completes without errors it sets these parameters to NULL. so your code should check for this.
If the stored-procedure detects errors, it creates and adds rows to the specified table and leaves the values of these parameters unchanged, and you must then query that table to list the error(s). You should drop this table before calling the stored procedure otherwise the procedure will fail with -601.
Example:
--#SET TERMINATOR #
drop table errschema.errtable#
set serveroutput on#
begin
declare v_errschema varchar(20) default 'ERRSCHEMA';
declare v_errtab varchar(20) default 'ERRTABLE';
CALL SYSPROC.ADMIN_DROP_SCHEMA('SOMESCHEMA', NULL, v_errschema, v_errtab);
if v_errschema is null and v_errtab is null
then
call dbms_output.put_line('The admin_drop_schema reported success');
else
call dbms_output.put_line('admin_drop_schema failed and created/populated table '||rtrim(v_errschema)||'.'||rtrim(v_errtab) );
end if;
end#
You can use global variables if you would like to use ADMIN_DROP_SCHEMA outside of compound SQL
E.g.
CREATE OR REPLACE VARIABLE ERROR_SCHEMA VARCHAR(128) DEFAULT 'SYSTOOLS';
CREATE OR REPLACE VARIABLE ERROR_TAB VARCHAR(128) DEFAULT 'ADS_ERRORS';
DROP TABLE IF EXISTS SYSTOOLS.ADS_ERRORS;
CALL ADMIN_DROP_SCHEMA('MY_SCHEMA', NULL, ERROR_SCHEMA, ERROR_TAB);

PostgreSQL how to identify if values need to be quoted

I am trying to write a function that will dynamically create the sql statement, but I am facing problems with typecasts so, how can I identify using the type of field if it needs to be quoted
-- using this I can recover the types of each field
-- but I do not have a simple way to express that for a specific type it need
-- to quote
create table test (
id serial not null,
employee_name text,
salary decimal(12,2),
hire_date date,
active boolean
);
select column_name,data_type, null as need_to_be_quoted
from information_schema.columns
where table_name = 'table_name';
column type need to be quoted (this is a missing information)
-------------------------------------
id integer false
employee_name text true
salary decimal false
hire_date date true
active boolean false
quote_ident docs says:
Return the given string suitably quoted to be used as an identifier in an SQL statement string. Quotes are added only if necessary
But it is not what I was expecting:
insert into test (employee_name, salary, hire_date, active)
values (quote_identy('John Doe'), quote_identy(100000), quote_identy(current_date), quote_identy(true));
This is kind of necessary because I am trying to generate the statement string dinamically.
I have values to be inserted in some table, I can discover the type of each value, but to generated the insert string statement, I should know if a specific value type should be quoted or not for example
text: type should be quoted in the string statement
boolean: should not be quoted
numeric: should not be quoted
date: should be quoted
Don't quote. Quoting adds complexity and if you don't get it just right it has syntax and security issues.
Instead use bind parameters. The details depend on what database library you're working with, but the basic idea is always the same. First prepare the statement with placeholders for your values. Then execute it passing in the values. The database takes care of putting the values into the statement. You can execute the same prepared statement multiple times optimizing your coding and database calls.
Here's how you'd do it in PL/pgSQL with EXECUTE. The linked documentation has lots of information about safely executing dynamic queries.
do $$
begin
execute '
insert into test (employee_name, salary, hire_date, active)
values ($1, $2, $3, $4)
' using 'John Doe', 100000, current_date, true;
end;
$$;
Furthermore, while writing a SQL builder is a good exercise, it's also very complicated and very easy to get subtly wrong. There are plenty of libraries which will build SQL for you.
Here's your statement using PHP's Laravel.
DB::table('test')->insert([
'employee_name' => 'John Doe',
'salary' => 100000,
'hire_date' => current_date,
'active' => true
);
If you're curious about how SQL builders work, you can dig inside Laravel for ideas. Writing one in PL/pgSQL is ambitious, but I don't know of one that exists. Good luck!

How to return values from dynamically generated "insert" command?

I have a stored procedure that performs inserts and updates in the tables. The need to create it was to try to centralize all the scan functions before inserting or updating records. Today the need arose to return the value of the field ID of the table so that my application can locate the registry and perform other stored procedures.
Stored procedure
SET TERM ^ ;
CREATE OR ALTER procedure sp_insupd (
iaction varchar(3),
iusuario varchar(20),
iip varchar(15),
imodulo varchar(30),
ifieldsvalues varchar(2000),
iwhere varchar(1000),
idesclogs varchar(200))
returns (
oid integer)
as
declare variable vdesc varchar(10000);
begin
if (iaction = 'ins') then
begin
vdesc = idesclogs;
/*** the error is on the line below ***/
execute statement 'insert into '||:imodulo||' '||:ifieldsvalues||' returning ID into '||:oid||';';
end else
if (iaction = 'upd') then
begin
execute statement 'select '||:idesclogs||' from '||:imodulo||' where '||:iwhere into :vdesc;
execute statement 'execute procedure SP_CREATE_AUDIT('''||:imodulo||''');';
execute statement 'update '||:imodulo||' set '||:ifieldsvalues||' where '||:iwhere||';';
end
insert into LOGS(USUARIO, IP, MODULO, TIPO, DESCRICAO) values (
:iusuario, :iip, :imodulo, (case :iaction when 'ins' then 1 when 'upd' then 2 end), :vdesc);
end^
SET TERM ; ^
The error in the above line is occurring due to syntax error. The procedure is compiled normally, that is, the error does not happen in the compilation, since the line in question is executed through the "execute statement". When there was no need to return the value of the ID field, the procedure worked normally with the line like this:
...
execute statement 'insert into '||:imodulo||' '||:ifieldsvalues||';';
...
What would be the correct way for the value of the ID field to be stored in the OID variable?
What is REAL VALUE in ifieldsvalues ?
you can not have BOTH
'insert into '||:imodulo||' '||:ifieldsvalues
'update '||:imodulo||' set '||:ifieldsvalues
because methods to specify column names and column values in INSERT and UPDATE statements is fundamentally different!!! You either would have broken update-stmt or broken insert-stmt!
The error in the above line is occurring due to syntax error
This is not enough. Show the real error text, all of it.
It includes the actual command you generate and it seems you had generated it really wrong way.
all the scan functions before inserting or updating records
Move those functions out of the SQL server and into your application server.
Then you would not have to make insert/update in that "strings splicing" way, which is VERY fragile and "SQL injection" friendly. You stepped into the road to hell here.
the error does not happen in the compilation
Exactly. And that is only for starters. You are removing all the safety checks that should had helped you in applications development.
http://searchsoftwarequality.techtarget.com/definition/3-tier-application
https://en.wikipedia.org/wiki/Multitier_architecture#Three-tier_architecture
http://bobby-tables.com
On modern Firebird versions EXECUTE STATEMENT command can have the same INTO clause as PSQL SELECT command.
https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-psql-coding.html#fblangref25-psql-execstmt
Use http://translate.ru to read http://www.firebirdsql.su/doku.php?id=execute_statement
Or just see SQL examples there. Notice, however, those examples all use SELECT dynamic command, not INSERT. So I am not sure it would work that way.
This works in Firebird 2.5 (but not in Firebird 2.1) PSQL blocks.
execute statement 'insert into Z(payload) values(2) returning id' into :i;
To run it from IBExpert/FlameRobin/iSQL interactive shell add that obvious boilerplate:
execute block returns (i integer) as
begin
execute statement 'insert into Z(payload) values(2) returning id' into :i;
suspend;
end

update remote db using dblink_exec fails

The below statement is failing by saying syntax error, I do not see the syntax error, please help:
SELECT dblink_exec(
'dbname=billing user=billing password=billing port=5432',
'insert into md.radacct values('2013-01-01 00:00:00+01:30')');
table was created like this
create table md.radacct(date_time timestamp with time zone);
You need to double up your single-quotes inside the outermost single-quotes.
select dblink_exec('...', ' insert into ... values(''2013-01-01 ... '')');