Dropping a global temp table does not drop its index - sql

Problem summary:
I created a global temp table and then I created a clustered index (added a primary key clustered constraint) on the table. I dropped the table assuming that it will also drop the index. I then recreated the table with the same name without problems. Then, when I tried to recreate the same index with the same name I get the error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.##MyTempTable' and the index name 'PK_TempSampleID'.
Problem details:
I need to create a global temp table and load records into this table in a particular order using:
SELECT FROM SomeTable INTO ##MyTempTable WHERE SomeCondition
ORDER BY does not do the job here, so I created a clustered index (primary key clustered constraint). This did the trick and my records were ordered by the respective field.
However, I encountered a different problem: I dropped the table and recreated it without problems but when I tried recreating the index I got the above mentioned error.
I tried dropping the index using:
DROP INDEX PK_TempSampleID ON ##MyTempTable
And I got this error message:
Cannot drop the index '##TempFormattedSnapshot.PK_TempSampleID', because it does not exist or you do not have permission.
I researched posts on this and other forums and all seem to advise that when dropping a temp table the index on that table is also dropped. My experience shows me otherwise.

The error message
The CREATE UNIQUE INDEX statement terminated because a duplicate key
was found for the object name 'dbo.##MyTempTable' and the index name
'PK_TempSampleID'.
means that there are duplicate values in the column(s) for which you are trying to create a unique index. In other words, not all values are unique.
It has nothing to do with the previously existed index of the same name.
When you drop a table, all indexes on that table are dropped as well.
You have another problem, which is out of the scope of this question. You said "load records into this table in a particular order". You'd better ask another question explaining what you are trying to achieve, because there is no such thing as "inserting rows into a table in a particular order". The only thing that you can do is generate IDENTITY values in a particular order when inserting rows.
Anyway, this is not the point of this question.

Related

Query to Alter Primary Key to any column with keyword

I have a database with several tables that I am looking to add primary keys to any column with the keyword "KEY" in its name. The first problem that doesn't seem fixable is to run a query against all tables rather than one by one... Secondly I don't see how I can Add Primary key or even drop constraints on wildcard column searches.
For those of you who are visual, this is what I am trying to achieve:
ALTER TABLE *
ADD PRIMARY KEY (%KEY%);
Keeping in mind SOME tables already have Primary Keys attached, so I may need to Drop Constraints on all first then re-constrain them. If even possible?
If you want to define existing autonumber fields as primary key, consider:
ALTER TABLE tablename ADD CONSTRAINT fieldname PRIMARY KEY(fieldname)
However, field cannot already be set with an index and table cannot already have a primary key. Again, use ALTER TABLE to remove index.
ALTER TABLE tablename DROP CONSTRAINT indexname
Will have to run this SQL for each table that must be modified. If this is a one-time only requirement (why would it not be?), probably just as fast to open each table and manually modify design.
MS documentation https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/alter-table-statement-microsoft-access-sql
The alternative is VBA using TableDefs to modify table structure. Search web for examples.

HANA: How to add a unique contraint on a column that is already indexed?

Having the following schema:
CREATE TABLE test_table(
cryptid varchar(255)
);
CREATE INDEX cryptid_index ON test_table (cryptid);
I am trying to a unique contraint to the column.
ALTER TABLE test_table ADD constraint crypid_unique_contraint UNIQUE(cryptid);
But this runs into an error:
Could not execute 'ALTER TABLE test_table ADD constraint crypid_unique_contraint ...'
Error: (dberror) [261]: invalid index name: column list already indexed
I can understand that the column is already indexed because I have created the index by myself. But I want the column to be unique. Is there a way to do this?
This is indeed an undocumented limitation in the current HANA versions.
The only way to create a unique constraint on this column is to first drop the single-column index present on this column.
I would consider the fact that this is not documented a (docu-)bug. However, the fact that existing indexes cannot be generally reused for uniqueness checks is not.
Single-column indexes in HANA's column store (which is what you use by default) tables are not B-tree indexes. Instead, these are inverted indexes into the column store structure of the main store-part of a column store table column.
These inverted structures cannot be checked for duplicates in the current transactional context as easily as B-tree indexes could.
This, I believe, is the reason for
a) implementing the uniqueness check only on a specific index implementation in the column store,
and
b) making the system behavior (not allowing the "conversion" of an existing index into a unique index) consistent across all table types.
As a general comment: for column store tables the benefit of single-column indexes for lookup/point-read scenarios is very often not worth the additional storage & compute resource consumption. This type of index practically doubles the memory requirement for the indexed column. So the speed-up in looking up a specific value should be worthwhile this additional permanent resource consumption.
You may check the documentation on INDEXES system view. They listed this index types:
Type of row store indexes: BTREE, BTREE_UNIQUE, CPBTREE, and CPBTREE_UNIQUE.
"Simple" index and unique index are a different index types at a build time, so there's no way to change it after the index was declared.
In other databases when you add unique constraint, it creates a new unique index (like in T-SQL or MySQL or Postgers) or reuses current index with this column (as in Oracle). But HANA doesn't allow you to create ether additional index on the same column (due to unknown reason, I didn't find it documented) or enforce constraint using existing index (due to poor implementation of mixture of uniqueness and index type).
The only way to go is to drop existing index and create it as unique (it is equivalent to unique constraint from the metadata point of view) from scratch, which you cannot due to authorizations. Sad but...

Conditionally apply a unique index

I am implementing functionality for a table that when an edit/change is made it will save a copy of the pre-edit row and mark it as is_deleted=TRUE, this is inorder to create a history of changes made to a row.
The email column in the table has a unique index which is preventing this functionality from being successful.
PostgreSQL said: duplicate key value violates unique constraint "users_email_unique"
Detail: Key (email)=(TEST) already exists.
Is there a way to apply the unique index only to rows that are marked is_deleted=FALSE, thus allowing for the changes to occur.
Since version 7.2, you can use partial indexes in PostgreSql
Add a where clause to the create index statement to make it a partial index:
CREATE UNIQUE INDEX users_email_unique ON tests (email)
WHERE NOT is_deleted; -- assuming is_deleted is Boolean
Though PostgreSql supports Alter index, from what I understand from the documentation the alter is limited to either rename or setting the tablespace.
This means that you will need to drop and re-create the index in order to change it into a partial index:
DROP INDEX users_email_unique;
CREATE UNIQUE INDEX users_email_unique ON tests (email)
WHERE NOT is_deleted; -- assuming is_deleted is Boolean

Create autoserial column in informix

is it possible to create a autoserial index in order 1,2,3,4... in Informix and what would be the syntax. I have a query and some of my timestamps are identical so I was unable to query using a timestamp variable. Thanks!
These are the commands that I ran to add an id field to an existing table. While logged in to the dbaccess console.
alter table my_table add id integer before some_field;
create sequence myseq;
update my_table set id = myseq.nextval;
drop sequence myseq;
alter table my_table modify (id serial not null);
Thanks to #ricardo-henriques for pointing me in the right direction. These commands will allow you to run the instructions explained in his answer on your database.
That would be the SERIAL data type.
You can use, as #RET mention the SERIAL data type.
Next you will struggle with the fact that you can't add a SERIAL column to an existing table. Ways to work around:
Add an INTEGER column, populate with sequential numbers and then alter the column to SERIAL.
Unload the data to a file, drop the table and recreate it with the new column.
Create a new table with the new column, populate the new table with the data from the old, drop the old and rename the new.
...
Bear in mind that they may not be unique. Hence you have to create an unique index or a primary key or an unique constraint in the column to prevent duplicates.
Another notes you should be aware:
- Primary key don't allow NULLS, unique index and unique constraints allow (as long there is only one record), so you should specify NOT NULL on the column definition.
- If you use a primary key or a unique constraint you can create a foreign key to it.
- In primary key and unique constraint the validation of the uniqueness of the record is done in the end of the DML, for the unique index it is done row a row.
Seems you're getting your first touch with informix, welcome. Yes it can be a little bit hard on the beginning just remember:
Always search before asking, really search.
When in doubt or reached a dead end then ask away.
Try to trim down your case scenario, built your own case the simple away you can, these will not only help us to help us but you will practice and in some cases find the solution by yourself.
When error is involve always give the error code, in informix it is given at least one error code and sometimes an ISAM error too.
Keen regards.

Deleting an entry and releasing from unique key index

For a project with offline storage, I created a database with a primary key for the id and also a unique field holding the date.
When I delete an entry, I can not create a new one with the same date the deleted entry had.
What can I do to get the date out of the index when I delete that entry?
This is how I create Table:
CREATE TABLE IF NOT EXISTS userdata (id INTEGER PRIMARY KEY ASC, entrydate DATE UNIQUE, strength, comments
I wonder if I need to add something to tell the DB server to allow me to use the same value again as soon it is free again. Maybe I need to run some kind of an update, where SQLite updates its internal records.
I think there are a few possibilities here.
Your delete statement is in an uncommitted transaction. So the unique value hasn't actually been removed from the table before your attempt to insert.
The value you are deleting and the new value you are inserting are not actually the same value. Run a select and make sure the value you are attempting to insert is actually available.
You have a corrupt index and need to reindex it.