Not able to create Materialized query on AS400 - sql

I get an error message when trying to create materialized query in as400
I use winSql for the connection.
The syntax seems valid.
Could you please point out what am I doing wrong?
This is the statement I am trying to execute
CREATE TABLE AAA.TEST_MQ AS
(
SELECT test.*
FROM
AAA.TABLE_NAME test
) REFRESH DEFERRED
This is the error message:
Error: SQL0104 - Token <END-OF-STATEMENT> was not valid. Valid tokens: IMMEDIATE <IDENTIFIER>. (State:37000, Native Code: FFFFFF98)
I Tried creating an immediate one as well.

Try this:
CREATE TABLE AAA.TEST_MQ AS (
SELECT test.*
FROM
AAA.TABLE_NAME test )
DATA INITIALLY DEFERRED
REFRESH DEFERRED
MAINTAINED BY USER
ENABLE QUERY OPTIMIZATION
;
I use JaySQL Lite and it works.

Related

How to use SET OPTION within a DB2 stored procedure

I read (and tried) that I cannot use WITH UR in DB2 stored procedures. I am told that I can use SET OPTION to achieve the same. However, when I implement it in my stored procedure, it fails to compile (I moved around its location same error). My questions are:
Can I really not use WITH UR after my SELECT statements within a procedure?
Why is my stored procedure failing to compile with the below error
message?
Here is a simplified version of my code:
CREATE OR REPLACE PROCEDURE MySchema.MySampleProcedure()
DYNAMIC RESULT SETS 1
LANGUAGE SQL
SET OPTION COMMIT=*CHG
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE AS (
SELECT 'testValue' as "Col Name"
) WITH DATA
BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_TABLE;
OPEN exitCursor;
END;
END
#
Error Message:
SQL0104N An unexpected token "SET OPTION COMMIT=*CHG" was found
following " LANGUAGE SQL
Here is code/error when I use WITH UR
CREATE OR REPLACE PROCEDURE MySchema.MySampleProcedure()
LANGUAGE SQL
DYNAMIC RESULT SETS 1
--#SET TERMINATOR #
BEGIN
DECLARE GLOBAL TEMPORARY TABLE TEMP_TABLE AS (
SELECT UTI AS "Trade ID" FROM XYZ WITH UR
) WITH DATA;
BEGIN
DECLARE exitCursor CURSOR WITH RETURN FOR
SELECT *
FROM SESSION.TEMP_TABLE;
OPEN exitCursor;
END;
END
#
line 9 is where the DECLARE GLOBAL TEMPORARY ... is
DB21034E The command was processed as an SQL statement because it was
not a valid Command Line Processor command. During SQL processing it
returned: SQL0109N The statement or command was not processed because
the following clause is not supported in the context where it is
used: "WITH ISOLATION USE AND KEEP". LINE NUMBER=9. SQLSTATE=42601
Specifying the isolation level:
For static SQL:
If an isolation-clause is specified in the statement, the value of that clause is used.
If an isolation-clause is not specified in the statement, the isolation level that was specified for the package when the package was bound to the database is used.
You need to bind the routine package with UR, since your DECLARE GTT statement is static. Before CREATE OR REPLACE use the following in the same session:
CALL SET_ROUTINE_OPTS('ISOLATION UR')
P.S.: If you want to run your routine not only 1 time in the same session without an error, use additional WITH REPLACE option of DECLARE.
If your Db2 server runs on Linux/Unix/Windows (Db2-LUW), then there is no such statement as SET OPTION COMMIT=*CHG , and so Db2 will throw an exception for that invalid syntax.
It is important to only use the matching Db2 Knowledge Centre for your Db2 platform and your Db2-version. Don't use Db2-Z/OS documentation for Db2-LUW development. The syntax and functionalities differ per platform and per version.
A Db2-LUW SQL PL procedure can use with ur in its internal queries, and if you are getting an error then something else is wrong. You have to use with ur in the correct syntax however, i.e in a statement that supports this clause. For your example you get the error because the clause does not appear to be valid in the depicted context. You can achieve the desired result in other ways, one of them being to populate the table in a separate statement from the declaration (e.g insert into session.temp_table("Trade ID") select uti from xyz with ur; ) and other ways are also possible.
One reason to use the online Db2 Knowledge Cenbtre documentation is that it includes sample programs, including sample SQL PL procedures, which are also available in source code form in the sample directory of your DB2-LUW server, in addition to being available on github. It is wise to study these, and get them working for you.

Error in creating 2 tables in Green Screen STRSQL

I'm getting an error while trying to create 2 tables in Green Screen STRSQL.
CREATE TABLE QTEMP/CUSTOMER AS (SELECT * FROM CBHHUBFP/SSCUSTP)
CREATE TABLE QTEMP/ADDRESS AS (SELECT * FROM QTEMP/CUSTOMER)
ERROR: Keyword Create not expected
Valied Tokens End-Of-Statement
Am I missing something here?
Using STRSQL you can only execute one SQL statement at time.
Re my comment to the accepted answer by #dcieslak, the following is an example of a Dynamic Compound Statement (DCS) with syntax that should be valid for use with the /*SYS naming-option, on any system [level of DB2 for IBM i], since the availability of that DCS feature; notice the addition of the WITH DATA clause to make the statement syntactically correct, and enclosing the two semicolon separated requests as CREATE TABLE statements, inside of the BEGIN and END:
begin
CREATE TABLE QTEMP/CUSTOMER AS (SELECT * FROM qiws/qcustcdt )
with data
;
CREATE TABLE QTEMP/ADDRESS AS (SELECT * FROM QTEMP/CUSTOMER)
with data
;
end
-- Table ADDRESS created in QTEMP. /* <-- feedback of final rqs */
While that is possible to enter as a single request, there is likely no point in coding that, per the extra overhead; perhaps if run under isolation and doing more work and coding exception handling, then there would be value. IOW, the Start Interactive SQL Session (STRSQL) scripting environment allows the isolation and user decisions to react to exceptions when the statement are entered individually, successively, Enter pressed after each.
So unless the idea is to test what might be written in a routine [as a compound statement, statements between BEGIN-END pairs] without actually coding the CREATE PROCEDURE [or CREATE FUNCTION ¿or CREATE TRIGGER?] with a routine-body, then the implicitly created routine [as procedure] that is then run and deleted to implement the DCS, is probably mostly just a bunch of extra/unnecessary work.

SAS - Insert statement into existing SQL table

Here is my code:
PROC SQL;
connect to odbc (dsn=ODC uid=sa pwd=XXXXX);
EXECUTE ( INSERT INTO dbo.tblDLA_Backup SELECT * FROM &dlafile.) BY ODBC;
disconnect from odbc;
quit;
Im getting this error
ERROR: CLI execute error: [Microsoft][SQL Server Native Client 11.0][SQL Server]Invalid object name 'work.dlabackup'.
If i do this:
proc sql;
connect to odbc (dsn=ODC uid=sa pwd=XXXXX);
insert into tblDLA_Backup SELECT * FROM WORK.DLABACKUP;
disconnect from odbc;
quit;
I get this error:
ERROR: File WORK.TBLDLA_BACKUP.DATA does not exist.
Why is it that I can't reference my SAS dataset and just insert? it should be simple as that..
The first error occurs because you are executing an SQL instruction on SQL Server, and not locally. And since this instruction contains a reference to your local SAS dataset, an error occurs because SQL server thinks it is a table in its own database.
You take a wrong approach on that one.
Your second approach is correct because you are executing the SQL in SAS, which both knows the local dataset and the SQL server tables. And it is syntactically valid at first glance.
The error is clear: SAS doesn't found the local dataset WORK.TBLDLA_BACKUP
Thus, verify if this dataset exists and is not corrupted:
in your explorer window, click on Libraries, then Work, and verify if TBLDLA_BACKUP is there, and if yes open it and check if you see your data.
I can't say more at this point, but you should hopefully discover something.
You need to use libref it you want to write into the foreign database.
libname sqldb odbc dsn=ODC uid=sa pwd=XXXXX ;
PROC SQL;
INSERT INTO SQLDB.tblDLA_Backup SELECT * FROM &dlafile.;
quit;
Note that you also need fix it so that your macro variable contains the name of a table that exists.

How to demonstrate SQL injection in where clause?

I want to demonstrate the insecurity of some webservices that we have. These send unsanitized user input to an Oracle database Select statements.
SQL injection on SELECT statements is possible (through the WHERE clause), however I am having a hard time to demonstrate it as the same parameter gets placed in other queries as well during the same webservice call.
E.g:
' or client_id = 999'--
will exploit the first query but as the same WS request calls runs other SQL SELECTs, it will return an oracle error on the next query because the client_id is referred to by an alias in the second table.
I am looking to find something more convincing rather than just having an ORA error returned such as managing to drop a table in the process. However I do not think this is possible from a Select statement.
Any ideas how I can cause some data to change, or maybe get sensitive data to be included as part of an ORA error?
It's not very easy to change data, but it's still possible. Function that created with pragma autonomous_transaction can contain dml and may be called in where. For instance,
CREATE OR REPLACE FUNCTION test_funct return int
IS
pragma autonomous_transaction;
BEGIN
DELETE FROM test_del;
commit;
return 0;
end;
-- and then
SELECT null from dual where test_funct()=1;
Another option you try creating huge subquery in WHERE which in turn may cause huge performance issue on server.
You do not need a custom function, you can use a sub-query:
" or client_id = (SELECT 999 FROM secret_table WHERE username = 'Admin' AND password_hash = '0123456789ABCD')"
If the query succeeds then you know that:
There is a table called secret_table that can be seen by the user executing this query (even if there is not a user interface that would typically be used to directly interact with that table);
That it has the columns username and password_hash;
That there is a user called Admin; and
That the admin user has a password that hashes to 0123456789ABCD.
You can repeat this and map the structure of the entire database and check for any values in the database.

Oracle 10gR2 trigger error

I have Oracle 10gR2. I am trying to create autoincrement trigger.
Here is the sample:
CREATE SEQUENCE TEST_SEQ
INCREMENT BY 1
START WITH 1
NOMAXVALUE
/
CREATE TABLE TESTER (
ID_TESTER INTEGER NOT NULL,
VAL VARCHAR2(20) NOT NULL
)
/
CREATE OR REPLACE TRIGGER TIB_TESTER BEFORE INSERT
ON TESTER FOR EACH ROW
BEGIN
SELECT TEST_SEQ.NEXTVAL
INTO :NEW.ID_TESTER
FROM DUAL;
END;
/
Trigger creation gives warning:
warning : ORA-24344: success with
compilation error
And when I get error value:
select OCI_SUCCESS_WITH_INFO;
/
It gives error:
error : ORA-00923: FROM keyword not
found where expected
What client are you using to issue these commands? ORA-24344 is a perculiar error.
In SQL*PLus we can get more information about compilation errors like this:
SQL> show errors
As for the ORA-00923 error, that is because in Oracle's version of SQL we always have to select from a table. So you should execute
select OCI_SUCCESS_WITH_INFO
from dual
/
I'm not sure how much sense that makes, but at least you won't get the error.
"It was Navicat problem"
That doesn't surprise me, as I ran your code against my database and it built without a hitch.
Maybe it will be useful for somebody:
If you are using Oracle 10g and OCI driver, ORA-24344 shows when trigger have carriage return sign (\r) in code eg. file was created with Windows end of line style.