set schema_search_path does not work with sequencs in h2 - h2

Script
drop schema vending if exists cascade;
drop schema joblog if exists cascade;
drop schema conditions if exists cascade;
create schema if not exists vending;
create schema if not exists joblog;
create schema if not exists conditions;
set schema_search_path vending,joblog,conditions;
set schema joblog;
create sequence job_log_id_seq;
select nextval('JOBLOG.JOB_LOG_ID_SEQ');
select nextval('JOB_LOG_ID_SEQ');
only the last statement doesn't work.
Save as h2_bug.sql and run with
H2JAR=~/.m2/repository/com/h2database/h2/1.4.199/h2-1.4.199.jar
java -cp $H2JAR org.h2.tools.RunScript -url jdbc:h2:~/tmp/h2_bug -script h2_bug.sql

All statements from your script work properly in H2 1.4.199.
NEXTVAL is a legacy compatibility-only function, you shouldn't use it in H2. It actually doesn't use schema search path and the last command works only because the sequence was found in the current schema. The proper method to fetch sequence values in H2 is a standard NEXT VALUE FOR [schemaName.]sequenceName expression. VALUES NEXT VALUE FOR JOB_LOG_ID_SEQ; will check schema search path after the current schema, unlike function that you use.
It's rarely appropriate to use the sequence directly, in the most cases identity columns should be used (ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY or something like it), but you may have own reasons to use the sequence, for example, if you really need to generate the value before row insertion.

Related

Creating a Cross-Schema Spatial Index in Oracle impossible with single user?

The oracle documentation here:
https://docs.oracle.com/en/database/oracle/oracle-database/21/spatl/indexing-querying-spatial-data.html#GUID-8E6AE949-758B-4A5E-9453-CC3D00647497
Talks about creating an index in schema A with user B
CREATE INDEX t1_spatial_idx on A.T1(geometry) INDEXTYPE IS mdsys.spatial_index_v2;
This, however, requires you to insert into user_sdo_geom_metadata. I'm trying to do this as one single connected user and that seems impossible. Let's say I'm user B, whenever I insert into user_sdo_geom_metadata the resulting changes won't get picked up by the view that the CREATE INDEX statement uses, which is ALL_SDO_GEMO_METADATA. As an example try:
INSERT INTO user_sdo_geom_metadata (table_name,column_name,diminfo,srid) VALUES
('T1','geometry', sdo_dim_array(sdo_dim_element('X',-180.0,180.0, 0.005),sdo_dim_element('Y',-90.0,90.0, 0.005)), 4326);
There is no way to specify the schema to get this into the correct format. In fact, if the T1 table here doesn't exist in your schema then nothing appears in ALL_SDO_GEMO_METADATA. I've tried
ALTER SESSION SET CURRENT_SCHEMA = 'A'
But that doesn't work. I'm trying to use Schemas as a way of collating together self-contained groupings of tables, views, indexes, etc. like you would in a normal database. In other words, I'm trying to use them like actual schemas. Oracle makes this challenging at the best of times, and I don't want to manage separate logins for each schema, but I can't see how it's possible to do this for spatial indexes.
Well, this was an epic struggle but got there in the end. The only way to create the metadata AND the index as another user is to create a stored procedure that does the INSERT but it's not as easy as just following the instructions, you have to call the package proc directly like so:
CREATE OR REPLACE PROCEDURE "<user name>".ADDMETADATA(
schema_name VARCHAR2, table_name VARCHAR2, column_name VARCHAR2, srid NUMBER, bounds MDSYS.SDO_DIM_ARRAY)
IS
BEGIN
mdsys.sdo_meta.insert_all_sdo_geom_metadata(schema_name, table_name, column_name, bounds, srid);
END ADDMETADATA;
Which almost certainly isn't supported but the standard way is broken so you have to. You then need to create this in every single new schema along with giving the schema user CREATE TABLE and CREATE SEQUENCE permissions. So to create a schema programmatically and have it all work boils down to the following steps:
CREATE the Schema/User and set the tablespace
GRANT CREATE SEQUENCE to the Schema/User
GRANT CREATE TABLE to the Schema/User
ALTER the quota on the TABLESPACE for the Schema/User
CREATE the stored proc above
CALL the stored proc
CALL create INDEX
Painfully long-winded but works. The whole schema-as-user thing remains a terrible idea, most databases can do all this with one SQL statement.

Spring Boot: How do I specify execute order of different schema.sql files?

I have created a table that has a foreign key constraint on spring-session-jdbc's spring_session table. The main motivation is that spring-session would delete the rows so that it would cascade and delete entries associated with the actual session. It became a "only works on my machine" problem because only me have had the table already in place when I start the development server. It would only work if others comment out the table first, initialize the server, then revert and do it again. Otherwise, nested exception is java.sql.SQLException: Failed to open the referenced table 'spring_session'.
I think the solution is to specify the run order of (or dependencies between) the initialization sql files. I cannot find that setting after some searching, so I am here.
schema.sql:
drop table if exists foo;
create table if not exists foo (
sid char(36) not null,
foreign key (sid) references spring_session (session_id) on delete cascade,
-- other columns and constraints
);
Possible workarounds:
Workaround #1: put an alter table add constraint statement like this in data.sql.
Workaround #2: grab spring-session-jdbc's schema.sql and put it into my schema.sql, then set spring.session.jdbc.initialize-schema=never in application.properties.
U can try flyway,it can manage your init sql files by giving them a version number. And it can record which sql have been executed, so if add another sql files, it will excute the sql you added, pass the others that have been executed.

Make an Oracle foreign key constraint referencing USER_SEQUENCES(SEQUENCE_NAME)?

I want to create a table with a column that references the name of a sequence I've also created. Ideally, I'd like to have a foreign key constraint that enforces this. I've tried
create table testtable (
sequence_name varchar2(128),
constraint testtableconstr
foreign key (sequence_name)
references user_sequences (sequence_name)
on delete set null
);
but I'm getting a SQL Error: ORA-01031: insufficient privileges. I suspect either this just isn't possible, or I need to add something like on update cascade. What, if anything, can I do to enforce this constraint when I insert rows into this table?
I assume you're trying to build some sort of deployment management system to keep track of your schema objects including sequences.
To do what you ask, you might explore one of the following options:
Run a report after each deployment that compares the values in your table vs. the data dictionary view, and lists any discrepancies.
Create a DDL trigger which does the insert automatically whenever a sequence is created.
Add a trigger to the table which does a query on the sequences view and raises an exception if not found.
I'm somewhat confused at what you are trying to achieve here - a sequence (effectively) only has a single value, the next number to be allocated, not all the values that have been previously allocated.
If you simply want to ensure that an attribute in the relation is populated from the sequence, then a trigger would be the right approach.

How to create a table identical to other table in structure and constraints in Oracle?

I want to create a table (lets say table_copy) which has same columns as other table (lets call it table_original) in Oracle database, so the query will be like this :
create table table_copy as (select * from table_original where 1=0);
This will create a table, but the constraints of table_original are not copied to table_copy, so what should be done in this case?
Only NOT NULL constraints are copied using Create Table As Syntax (CTAS). Others should be created manually.
You might however query data dictionary view to see the definitions of constraints and implement them on your new table using PL/SQL.
The other tool that might be helpful is Oracle Data Pump. You could import the table using REMAP_TABLE option specifying the name for the new table.
Use a database tool to extract the DDL needed for the constraints (SQL Developer does the job). Edit the resulting script to match the name of the new class.
Execute the script.
If you need to do this programmatically you can use a statement like this:
DBMS_METADATA.GET_DDL('TABLE','PERSON') from DUAL;

Drop Database called "User" from Oracle

Ok this is what happend...
One of my colleges run a script that created some tables which included one table called "User" on an Oracle XE 10g. Now we are unable to drop that table, we get an ORA-00903 every time we run a:
DROP TABLE USER CASCADE CONSTRAINTS
The same happens when ever we try to run any alter query on it (that means renaming doesn't work)
Do someone know how to deal with this?
have you tried fully qualifying with quotes:
drop table "myschema"."user"
Randy is right suggesting quoted identifiers. Note however that quoted identifiers are case-sensitive.
First, query ALL_TABLES or USER_TABLES to find the case-sensitive name of that table, and use that name in a statement such as
DROP TABLE "User";
or
ALTER TABLE "User" RENAME TO TBL_USERS;

Resources