DB2 creating temporal table creating column with CURRENT PACKAGESET or CLIENT_APPNAME - sql

Does anyone know which of the DB2 special registers are allowed in CREATE TABLE statement for DB2 temporal tables or in general in CREATE TABLE statement?
I am trying to CREATE TABLE COLUMNS WITH CURRENT PACKAGESET or CLIENT_APPNAME, they are not being identified by DB2. I tried almost all combinations of key words (marked in bold).
Create table Statement
CREATE TABLE EMPLOYEE
(EMP_NR INT NOT NULL
,FIRST_NAME CHAR(20) NOT NULL
,LAST_NAME CHAR(20) NOT NULL
,TSROWBEGIN TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW BEGIN
,TSROWEND TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW END
,TSPGMSTART TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS TRANSACTION START ID
**,IDTERMANV CHAR(8) GENERATED DEFAULT WITH CURRENT PACKAGESET
,IDTERM VARCHAR(128) GENERATED DEFAULT WITH CLIENT_APPLNAME**
,STDB2ACTION CHAR(1) GENERATED ALWAYS AS ( DATA CHANGE OPERATION )
,PERIOD SYSTEM_TIME(TSROWBEGIN, TSROWEND)
);
It results in
ILLEGAL USE OF KEYWORD CURRENT. TOKEN WAS EXPECTED. SQLCODE=-199, SQLSTATE=42601, DRIVER=3.68.61
or
ILLEGAL USE OF KEYWORD CLIENT_APPLNAME. TOKEN WAS EXPECTED. SQLCODE=-199, SQLSTATE=42601, DRIVER=3.68.61
Any suggestions on how to create column with default value of program name which is doing CUD operation on the table?

You can use the special registers for current date / time / timestamp and for user information (user, session user, system user). Take a look at the CREATE TABLE reference.
The same reference also has a section about what cannot be used, in case you try to use a function or put the CREATE statement into a procedure. Among other things, the GENERATED value cannot be based on the following:
Special registers and built-in functions that depend on the value of a special register.

Related

Updating current time for a column in SQL

So i am trying to store the time at which any changes were made to any row.
I was using the following query:
ALTER TABLE SPRD_MGMT_INP_INDEX_CHANGE_RATE
CHANGE "UPLOAD TIME"
"UPLOAD TIME" TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
I am getting the following error:
SQL compilation error: syntax error line 2 at position 0 unexpected 'CHANGE'. Please help
The syntax uses alter column and set, but the bigger issue is that you can't change the default of a column in Snowflake with the exception noted here:
https://docs.snowflake.com/en/sql-reference/sql/alter-table-column.html
In that page, it states the following:
Change the default for a column, unless the default is a sequence.
In that table for the action quoted above it has a checkmark by Unsupported.
You will need to create a new table with this default. You can then copy your rows from the original table using an insert from select.
You can specify the default in your new table like this:
create or replace table T1
(COL1 int, COL2 string, UPLOAD_TIME timestamp_tz default current_timestamp());

Failed to execute query. Error: String or binary data would be truncated in table xdbo.user_info', column 'uid'

I have problem inserting values in my SQL server database on Azure, I am getting the following error:
Failed to execute query. Error: String or binary data would be truncated in table 'dummy_app.dbo.user_info', column 'uid'. Truncated value: 'u'.
The statement has been terminated.
I don't understand where I am wrong, I just created the server, and I am trying to experiment but cant fix this.
if not exists (select * from sysobjects where name='user_info' and xtype='U')
create table user_info (
uid varchar unique,
name varchar,
email varchar
)
go;
INSERT INTO dbo.user_info(uid, name, email) VALUES('uids', 'name', 'email') go;
Creating the table works fine, the only thing that doesn't work is the second command INSERT
I suspect that the reason is that you haven't defined a lenght for varchar and it defaults to 1 as length. Therefore your value gets truncated.
Set a varchar length to something like varchar(200) and you should be good to go.
This looks like the fact that the CREATE portion of your procedure for the table doesn't include a length of varchar, so you'd have to specify a length such as varchar(50) since the default is 1. Refer to the official MS docs in the link, in the remarks.
docs.miscrosoft.com
Also, here is the syntax for the CREATE TABLE in Azure which might be helpful as well.
Syntax of Azure CREATE TABLE

Discover DB2 procedure default parameters using SYSCAT tables

Like Oracle, DB2 supports parameter defaults in stored procedures. Oracle syntax:
CREATE OR REPLACE PROCEDURE p_default (
p_in_number IN number := 0,
p_out_number OUT number,
p_in_varchar IN varchar2 := '0',
p_out_varchar OUT varchar2,
p_in_date IN date := date '1981-07-10',
p_out_date OUT date
)
DB2 syntax:
CREATE PROCEDURE p_default (
IN p_in_number INTEGER DEFAULT(0),
OUT p_out_number INTEGER,
IN p_in_varchar VARCHAR(10) DEFAULT('0'),
OUT p_out_varchar VARCHAR(10),
IN p_in_date DATE DEFAULT('1981-07-10'),
OUT p_out_date DATE
)
With Oracle, I can discover defaults using this query:
SELECT argument_name, defaulted FROM all_arguments WHERE object_id = :proc_id
How can I discover this in DB2 selecting from SYSCAT tables? I don't see any useful column in SYSCAT.PROCPARMS or SYSCAT.FUNCPARMS. Note, I don't mind calling any stored procedure from SYSPROC if such a procedure exists...
Note, I have asked as similar question about SQL Server:
Discover SQL Server procedure default parameters using SYS or INFORMATION_SCHEMA tables
(This assumes you're looking for the information on DB2 Linux/Unix/Windows, it may vary for other platforms)
You can use the SYSCAT.ROUTINEPARMS catalog view to find this information. It lists all the parameter types that the function can accept (there can be multiple rows if the procedure has multiple signatures), and if applicable, their default (in the aptly-named DEFAULT column). If a default is not supplied, that column will be NULL.
For example, if you wanted to see the input parameters for SYSIBMADM.SUBMIT (which has optional parameters), you could use this query:
SELECT *
FROM SYSCAT.ROUTINEPARMS
WHERE ROUTINESCHEMA='SYSIBMADM'
AND ROUTINENAME ='SUBMIT'
AND ROWTYPE IN ('B', 'P')
ROWTYPE of B allows for both input and output variables, and P is for input-only. The other types are covered in the Info Center doc I linked above.

Update Table with Hibernate Problem

I'm not able to update a table with Hibernate.
The table is created with the following statement and stored in a PostgreSQL Database.
CREATE TABLE staat
(
sta_id serial NOT NULL, -- ID des Staates
sta_bezeichnung character varying(50) NOT NULL, -- Langbezeichnung
sta_lkz character varying(10) NOT NULL, -- Laenderkennzeichen
sta_vorwahl character varying(10), -- Telefon Landesvorwahl
sta_eu boolean DEFAULT false, -- Ist der Staaat ein EU-Mitglied?
CONSTRAINT staat_pkey PRIMARY KEY (sta_id),
CONSTRAINT staat_sta_bezeichnung_key UNIQUE (sta_bezeichnung)
)
WITH (
OIDS=FALSE
);
Rights are set correct, because select, insert and update are possible with a SQL Manager. The following update statement also works with the SQL Manager.
But now the problem: when I want to update the table with my application, it generates PSQLException with the following output:
WARNUNG: SQL Error: 0, SQLState: 22004 and ERROR: query string argument of EXECUTE is null
The source code:
Query q = s.createQuery("Update Staat set sta_bezeichnung = 'BlaBla' where sta_id = 1");
int status = q.executeUpdate();
I think the problem has something to do with NOT NULL columns, because tables without NOT NULL columns can be updated with the same source code...
Does anyone has an idea of what is wrong or what I have to do???
Edit: tried with SQL (q.executeSQLUpdate) and HQL
Transaction tr = s.beginTransaction();
staat = (Staat)s.get(Staat.class, new Integer(0));
staat.setStaBezeichnung("BlaBla");
s.update(staat);
tr.commit();
Generates followin error: ERROR: query string argument of EXECUTE is null and Could not synchronize database state with session
Edit2: update works fine without hibernate
Please check your Hibernate mapping file for Staat maybe you have not configured a not-null constraint for some attribute/field, which is not-null in database.
It looks like you are trying to use SQL query where HQL query is expected. Try
Query q = s.createSQLQuery(....);
Or better yet, use mapped classes with HQL. But I don't know your mapped classes, so can't speculate on specifics.

how to use the value of an Identity column for a diffent column in the same insert

I have created a table like this:
CREATE TABLE A
( ID BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (
START WITH +1
INCREMENT BY +1
NO MINVALUE
NO MAXVALUE
NO CYCLE
CACHE 20
NO ORDER )
, ID_MIRROR CHAR(20))
I would like to do an insert such that ID would be automatically set, and ID_MIRROR would be what is in ID, but prefixed with 'PRE'.
I have unsuccessfully tried the following:
INSERT INTO A (ID_MIRROR)
VALUES ( 'PRE' || CHAR(A.ID))
Error 12/4/2009 6:43:08
AM 0:00:00.296 DB2 Database Error:
ERROR [42703] [IBM][DB2/AIX64]
SQL0206N "A.ID" is not valid in the
context where it is used.
SQLSTATE=42703 1 0
insert into A (id_mirror)
VALUES (CONCAT('PRE', CHAR(identity_val_local())))
ID_MIRROR is NULL, subsequent inserts are previous value of ID.
insert into A (id_mirror)
VALUES (CONCAT('PRE', CHAR(scope_identity())))
Error 12/4/2009 6:11:11
AM 0:00:00.234 DB2 Database Error:
ERROR [42884] [IBM][DB2/AIX64]
SQL0440N No authorized routine named
"SCOPE_IDENTITY" of type "FUNCTION"
having compatible arguments was found.
SQLSTATE=42884 1 0
Another forum answered the question like this:
INSERT INTO A (ID_MIRROR) VALUES ( 'PRE' || IDENTITY_VAL_LOCAL());
Why would you ever need to do this when you could simply create this column on an ad hoc basis any time you wanted to, in a SELECT statement?