JDBC retrieve foreign keys columns name (sybase ase) - jdbc

I'm trying to retrieve FK of a given table with JDBC metadata.
For that, I'm using the "getImportedKeys" function.
For my table 'cash_mgt_strategy', it give in resultset:
PKTABLE_CAT : 'HAWK'
PKTABLE_SCHEM : 'dbo'
PKTABLE_NAME : 'fx_execution_strategy_policy'
PKCOLUMN_NAME : 'fx_execution_strategy_policy_id'
FKTABLE_CAT : 'HAWK'
FKTABLE_SCHEM : 'dbo'
FKTABLE_NAME : 'cash_mgt_strategy'
FKCOLUMN_NAME : 'fx_est_execution_strategy_policy'
KEY_SEQ : '1'
UPDATE_RULE : '1'
DELETE_RULE : '1'
FK_NAME : 'fk_fx_est_execution_strategy_policy'
PK_NAME : 'cash_mgt_s_1283127861'
DEFERRABILITY : '7'
The problem is that the "FKCOLUMN_NAME : 'fx_est_execution_strategy_policy'" is not a real column of my table, but it seems to be truncated? (missing "_id" at the end)
When using an official Sybase sql client (Sybase Workspace), displaying the DDL of the table give for this constraint / foreign key:
ALTER TABLE dbo.cash_mgt_strategy ADD CONSTRAINT fk_fx_est_execution_strategy_policy FOREIGN KEY (fx_est_execution_strategy_policy_id)
REFERENCES HAWK.dbo.fx_execution_strategy_policy (fx_execution_strategy_policy_id)
So I'm wondering how to retrieve the full FKCOLUMN_NAME ?
Note that I'm using jconnect 6.0.
I've tested with jconnect 7.0, same problem.
Thanks

You haven't provided your ASE version so I'm going to assume the following:
dataserver was running ASE 12.x at some point (descriptor names limited to 30 characters)
dataserver was upgraded to ASE 15.x/16.x (descriptor names extended to 255 characters)
DBA failed to upgrade/update the sp_jdbc* procs after the upgrade to ASE 15.x/16.x (hence the old ASE 12.x version of the procs - descriptors limited to 30 characters - are still in use in the dataserver)
If the above is true then sp_version should show the older versions of the jdbc procs running in the dataserver.
The (obvious) solution would be to have the DBA load the latest version of the jdbc stored procs (typically found under ${SYBASE}/jConnect*/sp).
NOTE: Probably wouldn't hurt to have the DBA review the output from sp_version to see if there are any other upgrade scripts that need to be loaded (eg, installmodel, installsecurity, installcommit, etc).

Ok, so I've done some search on my DB server and I've found the code of stored proc sp_jdbc_importkey. In this code can see:
create table #jfkey_res(
PKTABLE_CAT varchar(32) null,
PKTABLE_SCHEM varchar(32) null,
PKTABLE_NAME varchar(257) null,
PKCOLUMN_NAME varchar(257) null,
FKTABLE_CAT varchar(32) null,
FKTABLE_SCHEM varchar(32) null,
FKTABLE_NAME varchar(257) null,
FKCOLUMN_NAME varchar(257) null,
KEY_SEQ smallint,
UPDATE_RULE smallint,
DELETE_RULE smallint,
FK_NAME varchar(257),
PK_NAME varchar(257) null)
create table #jpkeys(seq int, keys varchar(32) null)
create table #jfkeys(seq int, keys varchar(32) null)
The temporary tables #jpkeys and #jfkeys used to store the column names (for PK and FK) are typed with varchar(32) instead of 257!!
Need to search how to patch / update theses stored proc now.

Related

SQL syntax change with H2 version update

I am having the following script for H2 DB used in SpringBoot application tests:
create TABLE PARAMETER (
ID long auto_increment,
TYPE VARCHAR(100) not null,
VALUE VARCHAR(100) not null,
SORT_ORDER int not null
);
CREATE SEQUENCE PARAMETER_ID_SEQ MINVALUE 1 START WITH 1;
This script executes with previous H2 version <h2.version>1.4.196</h2.version>, but when updating to <h2.version>2.1.210</h2.version> the following error ocures and I cannot understand what the problem. Is there a new syntax with the upper version?
ERROR:
Reason: liquibase.exception.DatabaseException: Syntax error in SQL statement "create TABLE PARAMETER (\000a ID long [*]auto_increment,\000a TYPE VARCHAR(100) not null,\000a VALUE VARCHAR(100) not null,\000a SORT_ORDER int not null\000a);\000a\000aCREATE SEQUENCE PARAMETER_ID_SEQ MINVALUE 1 START WITH 1;"; expected "RAW, ARRAY, INVISIBLE, VISIBLE, NOT, NULL, AS, DEFAULT, GENERATED, ON, NOT, NULL, DEFAULT, NULL_TO_DEFAULT, SEQUENCE, SELECTIVITY, COMMENT, CONSTRAINT, COMMENT, PRIMARY, UNIQUE, NOT, NULL, CHECK, REFERENCES, ,, )"; SQL statement:
create TABLE PARAMETER (
ID long auto_increment,
TYPE VARCHAR(100) not null,
VALUE VARCHAR(100) not null,
SORT_ORDER int not null
);
CREATE SEQUENCE PARAMETER_ID_SEQ MINVALUE 1 START WITH 1; [42001-210] [Failed SQL: (42001) create TABLE PARAMETER (
ID long auto_increment,
TYPE VARCHAR(100) not null,
VALUE VARCHAR(100) not null,
SORT_ORDER int not null
);
CREATE SEQUENCE PARAMETER_ID_SEQ MINVALUE 1 START WITH 1;]
There is no such data type as long in SQL, where did you find it? You need to use BIGINT. H2 accepts long too, but it depends on compatibility mode, for example, it isn't allowed in PostgreSQL compatibility mode.
AUTO_INCREMENT should also be used only in MySQL and MariaDB compatibility modes, H2 also accepts it in REGULAR and LEGACY modes, but normally you need to use GENERATED BY DEFAULT AS IDENTITY.
VALUE is a keyword in H2 and it also a reserved word in the SQL Standard (even in archaic SQL-92). You cannot use it as an identifier without quotes, you need to write it as "VALUE" or "value" depending on case you want (quoted identifiers are case-sensitive by default). Actually there is a compatibility setting, you can add ;NON_KEYWORDS=VALUE to JDBC URL of H2, but it would be better to quote it in your scripts and application.

H2DB - executeUpdate() returns 0 or 1 on DELETE depending on table definition

I wonder if someone could explain the behaviour of the H2 JDBC driver when deleting an entry from a rather simple table.
When using the following table definition, the method executeUpdate() for a PreparedStatement instance returns 1 if one entry has been deleted (expected behaviour).
CREATE TABLE IF NOT EXISTS "MATERIAL" (
"CODE" VARCHAR(5) NOT NULL,
"NAME" VARCHAR(100) NOT NULL
);
When adding a PRIMARY KEY constraint on the CODE column, the same method returns 0 although the entry gets deleted successfully (behaviour not expected).
CREATE TABLE IF NOT EXISTS "MATERIAL" (
"CODE" VARCHAR(5) NOT NULL,
"NAME" VARCHAR(100) NOT NULL,
PRIMARY KEY ("CODE")
);
Most interestingly, when adding an INT typed column to serve as PRIMARY KEY the return value is 1 again:
CREATE TABLE IF NOT EXISTS "MATERIAL" (
"ID" INT NOT NULL AUTO_INCREMENT,
"CODE" VARCHAR(5) NOT NULL,
"NAME" VARCHAR(100) NOT NULL,
PRIMARY KEY ("ID")
);
Is someone able to reconstruct this behaviour and probably somehow explain it to me?
I have included the current version of H2 DB using maven.
EDIT:
If I eventually add a UNIQUE constraint for the CODE column, the return value is 0 again ...
CREATE TABLE IF NOT EXISTS "MATERIAL" (
"ID" INT NOT NULL AUTO_INCREMENT,
"CODE" VARCHAR(5) NOT NULL UNIQUE,
"NAME" VARCHAR(100) NOT NULL,
PRIMARY KEY ("CODE")
);
EDIT 2:
The query used to delete an entry looks like the following (used in PreparedStatement):
DELETE FROM MATERIAL WHERE CODE = ?
SOLUTION:
I'm sorry to have you bothered with this. Actually, there was no problem with the table definition or the JDBC driver. It was my test data - from earlier testing I had wanted to INSERT two entries having the same CODE. It was a multiple row insert - obviously this failed, when CODE was the PK or having a UNIQUE index. Thus, in this cases executeUpdate() could only return 0 because there was no data in the table at all.

Create POSTGRES table with VARCHAR[] in H2 in-memory database

I have DDL for my PostgreSQL database. One of the columns in the table is of type VARCHAR[]. H2 fails to create this table, even if the database is running in PosgtreSQL compatibility mode (url: jdbc:h2:mem:user-management;MODE=PostgreSQL)
Simplified DDL:
create table "users" (
"uuid" VARCHAR NOT NULL PRIMARY KEY,
"roles" VARCHAR[] NOT NULL
);
Is there any data type that is compatible between H2 and PostgreSQL and is actually a varchar array? Thanks!
It is possible to use array here, it's worked for me in h2 postgre mode.
create table "users" (
"uuid" VARCHAR NOT NULL PRIMARY KEY,
"roles" varchar array
);

IndexedDB: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. (error code 0)

I'm trying to migrate an IndexedDB database to a different instance of Firefox.
I can migrate it to a different site (or directory, for file URLs) just by copying ~/.mozilla/firefox/PROFILE/storage/default/file++++... to the new name.
I can also migrate to a different profile in the same Firefox instance.
But if I create a new home directory (export HOME=/tmp/test-home) and copy into that, then Firefox refuses to open the database, giving the error:
UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. (error code 0))
(I actually want to migrate to a new machine, but testing with the same machine, user, and FF version narrows down the problem)
What tests does FF do to decide whether to allow opening the database? I see a binary .metadata file with a path in, and also a .sqlite file with it in the "database" table (which I tried updating manually).
I'm testing with Firefox 40.0.3.
Update: found this in the Javascript console:
Security Error: Content at file:///home/.../ may not load data from file:///cache.manifest.
Quota 'idb' is not a valid schema!: QuotaManager.cpp:4932 <unknown>
Quota Origin 'idb' failed to parse, handled tokens: : QuotaManager.cpp:4858 <unknown>
IndexedDB UnknownErr: ActorsParent.cpp:573
The metadata file gives the old origin. Firefox's QuotaManager loads the metadata file, reads the old origin, and tries to scan the 'idb' directory for the old origin. This directory doesn't exist and so it aborts. If the metadata file is deleted, Firefox will recreate it with the correct contents.
Also, make sure the target Firefox instance is at least as new as the source one. I also got this error with Firefox 37 trying to read a file from Firefox 40.
Thanks for your post, it was helpful.
Let me explain what I'm doing, and I think it will help you to at least understand the problem. So far as I can tell the hidden file .metadata is not related to this problem.
I'm trying to move a sqlite database from FFOS 2.1 to FFOS 2.6. The application uses the indexDB and so far as the application is aware nothing has changed (applicaiton, code, applicaiton's database are unchanged). However Firefox changed the schema of the database that stores the application's database. This back-end storage database is agnostic to the application database.
Using sqlite3 and the .schema command I can explain the differences:
Older 2.1
CREATE TABLE database (name TEXT PRIMARY KEY, origin TEXT NOT NULL, version INTEGER NOT NULL DEFAULT 0, last_vacuum_time INTEGER NOT NULL DEFAULT 0, last_analyze_time INTEGER NOT NULL DEFAULT 0, last_vacuum_size INTEGER NOT NULL DEFAULT 0) WITHOUT ROWID;
CREATE TABLE index_data( index_id INTEGER NOT NULL, value BLOB NOT NULL, object_data_key BLOB NOT NULL, object_store_id INTEGER NOT NULL, value_locale BLOB, PRIMARY KEY (index_id, value, object_data_key), FOREIGN KEY (index_id) REFERENCES object_store_index(id) , FOREIGN KEY (object_store_id, object_data_key) REFERENCES object_data(object_store_id, key) ) WITHOUT ROWID;
CREATE INDEX index_data_value_locale_index ON index_data (index_id, value_locale, object_data_key, value) WHERE value_locale IS NOT NULL;
CREATE TABLE object_store( id INTEGER PRIMARY KEY, auto_increment INTEGER NOT NULL DEFAULT 0, name TEXT NOT NULL, key_path TEXT);
CREATE TABLE unique_index_data( index_id INTEGER NOT NULL, value BLOB NOT NULL, object_store_id INTEGER NOT NULL, object_data_key BLOB NOT NULL, value_localeBLOB, PRIMARY KEY (index_id, value), FOREIGN KEY (index_id) REFERENCES object_store_index(id) , FOREIGN KEY (object_store_id, object_data_key) REFERENCES object_data(object_store_id, key) ) WITHOUT ROWID;
CREATE INDEX unique_index_data_value_locale_index ON unique_index_data (index_id, value_locale, object_data_key, value) WHERE value_locale IS NOT NULL;
CREATE TABLE file (id INTEGER PRIMARY KEY, refcount INTEGER NOT NULL);
CREATE TRIGGER file_update_trigger AFTER UPDATE ON file FOR EACH ROW WHEN NEW.refcount = 0 BEGIN DELETE FROM file WHERE id = OLD.id; END;
CREATE TABLE object_data ( object_store_id INTEGER NOT NULL, key BLOB NOT NULL, index_data_values BLOB DEFAULT NULL, file_ids TEXT, data BLOB NOT NULL, PRIMARY KEY (object_store_id, key), FOREIGN KEY (object_store_id) REFERENCES object_store(id) ) WITHOUT ROWID;
CREATE TRIGGER object_data_insert_trigger AFTER INSERT ON object_data WHEN NEW.file_ids IS NOT NULL BEGIN SELECT update_refcount(NULL, NEW.file_ids);END;
CREATE TRIGGER object_data_update_trigger AFTER UPDATE OF file_ids ON object_data WHEN OLD.file_ids IS NOT NULL OR NEW.file_ids IS NOT NULL BEGIN SELECT update_refcount(OLD.file_ids, NEW.file_ids);END;
CREATE TRIGGER object_data_delete_trigger AFTER DELETE ON object_data WHEN OLD.file_ids IS NOT NULL BEGIN SELECT update_refcount(OLD.file_ids, NULL);END;
CREATE TABLE object_store_index ( id INTEGER PRIMARY KEY, object_store_id INTEGER NOT NULL, name TEXT NOT NULL, key_path TEXT NOT NULL, unique_index INTEGER NOT NULL, multientry INTEGER NOT NULL, locale TEXT, is_auto_locale BOOLEAN, FOREIGN KEY (object_store_id) REFERENCES object_store(id) );
Newer 2.6
CREATE TABLE database (name TEXT NOT NULL, version INTEGER NOT NULL DEFAULT 0);
CREATE TABLE index_data (index_id INTEGER NOT NULL, value BLOB NOT NULL, object_data_key BLOB NOT NULL, object_data_id INTEGER NOT NULL, PRIMARY KEY (index_id,value, object_data_key), FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE CASCADE, FOREIGN KEY (object_data_id) REFERENCES object_data(id) ONDELETE CASCADE);
CREATE INDEX index_data_object_data_id_index ON index_data (object_data_id);
CREATE TABLE object_store (id INTEGER PRIMARY KEY, auto_increment INTEGER NOT NULL DEFAULT 0, name TEXT NOT NULL, key_path TEXT, UNIQUE (name));
CREATE TABLE unique_index_data (index_id INTEGER NOT NULL, value BLOB NOT NULL, object_data_key BLOB NOT NULL, object_data_id INTEGER NOT NULL, PRIMARY KEY (index_id, value, object_data_key), UNIQUE (index_id, value), FOREIGN KEY (index_id) REFERENCES object_store_index(id) ON DELETE CASCADE FOREIGN KEY (object_data_id) REFERENCES object_data(id) ON DELETE CASCADE);
CREATE INDEX unique_index_data_object_data_id_index ON unique_index_data (object_data_id);
CREATE TABLE file (id INTEGER PRIMARY KEY, refcount INTEGER NOT NULL);
CREATE TRIGGER file_update_trigger AFTER UPDATE ON file FOR EACH ROW WHEN NEW.refcount = 0 BEGIN DELETE FROM file WHERE id = OLD.id; END;
CREATE TABLE object_data (id INTEGER PRIMARY KEY, object_store_id INTEGER NOT NULL, key_value BLOB DEFAULT NULL, file_ids TEXT, data BLOB NOT NULL, UNIQUE (object_store_id, key_value), FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE CASCADE);
CREATE TRIGGER object_data_insert_trigger AFTER INSERT ON object_data FOR EACH ROW WHEN NEW.file_ids IS NOT NULL BEGIN SELECT update_refcount(NULL, NEW.file_ids); END;
CREATE TRIGGER object_data_update_trigger AFTER UPDATE OF file_ids ON object_data FOR EACH ROW WHEN OLD.file_ids IS NOT NULL OR NEW.file_ids IS NOT NULL BEGIN SELECT update_refcount(OLD.file_ids, NEW.file_ids); END;
CREATE TRIGGER object_data_delete_trigger AFTER DELETE ON object_data FOR EACH ROW WHEN OLD.file_ids IS NOT NULL BEGIN SELECT update_refcount(OLD.file_ids, NULL); END;
CREATE TABLE object_store_index (id INTEGER PRIMARY KEY, object_store_id INTEGER NOT NULL, name TEXT NOT NULL, key_path TEXT NOT NULL, unique_index INTEGER NOTNULL, multientry INTEGER NOT NULL, UNIQUE (object_store_id, name), FOREIGN KEY (object_store_id) REFERENCES object_store(id) ON DELETE CASCADE);
I have been unable to find a script written by mozilla that addresses this. But I suspect you could trick firefox into repairing this issue for you-- downgrade Firefox insert old database then upgrade firefox. Allow upgrade script to rewrite the database.
Unfortunately these changes look more complex than a simple adding/columns so I doubt you could safely just change or upgrade the existing database. So unless someone at Mozilla left a script lying around I believe there is no other solution.
I met this error with Firefox 63, end of 2018.
IndexedDB: UnknownError: The operation failed for reasons unrelated to the database itself and not covered by any other error code. (error code 0)
It comes from many updates over the same user profile.
localStorage panel from the debugger was empty, whith keys still accessible.
devdocs refused to install offline, with an error indexedDB.
Solution: This mozilla page and click the refresh Firefox button.

How to solve SchemaVersionTrackingException in dbdeploy due to no default value in delta_set?

I am trying to do automatic DB migration. I am using dbdeploy for the same.
I followed the steps in this link http://blog.codeborne.com/2012/09/using-dbdeploy-in-gradle.html
I created the change log table as:
CREATE TABLE changelog (
change_number INTEGER NOT NULL,
delta_set VARCHAR(10) NOT NULL,
start_dt TIMESTAMP NOT NULL,
complete_dt TIMESTAMP NULL,
applied_by VARCHAR(100) NOT NULL,
description VARCHAR(500) NOT NULL
);
ALTER TABLE changelog ADD CONSTRAINT Pkchangelog PRIMARY KEY (change_number, delta_set);
The updateDatabase task in build.gradle is:
task updateDatabase << {
ant.dbdeploy(driver: dbDriver,
url: dbUrl,
userid: dbUsername,
password: dbPassword,
dir: './src/main/resources/deploy/sql',
dbms: 'mysql'
)
}
When I do gradle updateDatabase, I get com.dbdeploy.exceptions.SchemaVersionTrackingException: Could not update change log because: Field 'delta_set' doesn't have a default value.
I tried assigning 'main' as default value in the change table log file as:
delta_set VARCHAR(10) NOT NULL DEFAULT 'Main'
But, I still got the same exception.
I also removed the delta_set attribute, I got the same exception. This really confused me.
I am completely new to datamigration. So, any help regarding this error and how I should go about it will be deeply appreciated.
Thank you in advance.
The DBDeploy documentation isn't very explicit about this, but the changelog table format changed between versions 2.X and 3.X (see the upgrade instructions). I suspect that you are using DBDeploy 3.X.
You need to:
Remove the old changelog table:
DROP TABLE changelog;
Recreate it using the new format:
CREATE TABLE changelog (
change_number INTEGER NOT NULL,
complete_dt TIMESTAMP NOT NULL,
applied_by VARCHAR(100) NOT NULL,
description VARCHAR(500) NOT NULL
);
ALTER TABLE changelog ADD CONSTRAINT Pkchangelog PRIMARY KEY (change_number);
After this, everything should work.

Resources