I have a test application coded in Java for creating an indexed and non indexed table in a MySQL, PostgreSQL, Oracle and Firebird database (Amongst other things).
Is it simply a case that PostgreSQL doesnt allow the auto increment feature? If not, what is the normal procedure for having an indexed coloumn?
Thanks in advance
You may use SERIAL in PostgreSQL to generate auto increment field,
For eg:-
CREATE TABLE user (
userid SERIAL PRIMARY KEY,
username VARCHAR(16) UNIQUE NOT NULL
)
This will create userid as auto-increment primary key indexed.
If you don't want this as primary key, just remove PRIMARY KEY.
Use a column of type SERIAL. It works the same way as AUTOINCREMEMT on some other DBs. (Check the docs for other features you can use with it.)
With current Postgres, you can just use SERIAL for the column type.
With older versions of Postgres, you can implement this using SEQUENCE; the relevant procedure is:
CREATE SEQUENCE mytable_myid_seq;
ALTER TABLE mytable ALTER COLUMN myid SET DEFAULT NEXTVAL('mytable_myid_seq');
A good article on this is MySQL versus PostgreSQL: Adding an Auto-Increment Column to a Table
Related
I'm in the process of masking my ids from the url. I solved this by having a GUID in the URL instead of the primary key (which someone could easily guess). This GUID will map itself to the record just like a primary key.
Is this a decent solution? Someone would have to guess the GUID to see other people's data. Is there a security loophole I'm missing here.
How could I update my existing database to loop through records using PostgreSQL to update each record with a unique GUID?
You may also create the GUIDs without a Postgres extension, e. g.:
ALTER TABLE my_table ADD COLUMN guid UUID
DEFAULT MD5(RANDOM()::TEXT || ':' || CURRENT_TIMESTAMP)::UUID NOT NULL;
If you need not to define the GUID with a default value, you can use row data for the generation, the primary key for instance:
BEGIN;
ALTER TABLE my_table ADD COLUMN guid UUID;
UPDATE my_table SET guid = MD5(id::TEXT || ':' || CURRENT_TIMESTAMP)::UUID;
ALTER TABLE my_table ALTER guid SET NOT NULL;
END;
The uuid-ossp extension has functions for generating random uuids.
First:
create extension "uuid-ossp";
then:
alter table url add column guid uuid not null default uuid_generate_v4();
I am trying to change a primary key Id to identity to increment 1 on each entry. But the column has been referenced already by other tables. Is there any way to set primary key to auto increment without dropping the foreign keys from other tables?
If the table isn't that large generate script to create an identical table but change the schema it created to:
CREATE TABLE MYTABLE_NEW (
PK INT PRIMARY KEY IDENTITY(1,1),
COL1 TYPEx,
COL2 TYPEx,
COLn
...)
Set your database to single-user mode or make sure no one is in the
database or tables you're changing or change the table you need to
change to READ/ONLY.
Import your data into MYTABLE_NEW from MYTABLE using set IDENTITY_INSERT on
Script your foreign key constraints and save them--in case you need
to back out of your change later and/or re-implement them.
Drop all the constraints from MYTABLE
Rename MYTABLE to MYTABLE_SAV
Rename MYTABLE_NEW to MYTABLE
Run constraint scripts to re-implement constraints on MYTABLE
p.s.
you did ask if there was a way to not drop the foreign key constraints. Here's something to try on your test system. on Step 4 run
ALTER TABLE MYTABLE NOCHECK CONSTRAINT ALL
and on Step 7 ALTER TABLE MYTABLE CHECK CONSTRAINT ALL. I've not tried this myself -- interesting to see if this would actually work on renamed tables.
You can script all this ahead of time on a test SQL Server or even a copy of the database staged on a production server--to make implementation day a no-brainer and gauge your SLAs for any change control procedures for your company.
You can do a similar methodology by deleting the primary key and re-adding it back, but you'll need to have the same data inserted in the new column before you delete the old column. So you'll be deleting and inserting schema and inserting primary key data with this approach. I like to avoid touching a production table if at all possible and having MYTABLE_SAV around in case "anything" unexpected occurs is a comfort to me personally--as I can tell management "the production data was not touched". But some tables are simply too large for this approach to be worthwhile and, also, tastes and methodologies differ largely from DBA to DBA.
In Interbase (I'm using 2007, I don't know if it matters) is there a command to get the identity of a newly-inserted record, similar to SCOPE_IDENTITY() in SQL Server?
No, InterBase doesn't really have an identity feature.
What InterBase has, instead, is a generator feature. Generators are kind of like identity, but they are logically separated from the primary key column. A generator, in other words, will give you a guaranteed unique value, but what you do with that value is up to you.
You could use that value as the primary key values for a single table, or for multiple tables. But actually assigning the primary key value is something you must do yourself.
In addition to not having a feature like SCOPE_IDENTITY, InterBase does not have any kind of feature to return values from an INSERT statement. So not only can you not get a generated primary key value back from an INSERT statement, you also cannot get any other values, such as values set by a trigger.
Workarounds
One possible workaround for this is to generate the primary key value in advance. So you could do something like the following (I'm going to use InterBase stored procedure syntax for this example, since I don't know what programming language you are using, but you can do the same thing in any programming language):
DECLARE VARIABLE ID INTEGER;
BEGIN
ID = SELECT GEN_ID(MY_GENERATOR, 1) FROM RDB$DATABASE;
INSERT INTO MY_TABLE (ID, DESCRIPTION) VALUES (:ID, "Foo");
RDB$DATABASE is a system table which has only one record. Knowing the value of ID, you can return it from the proc.
A second workaround is to SELECT the record using an alternate key and read the generated ID that way.
I want to build an employees table using SQL SERVER 2008 , and in my table I want to have an ID for each employee .
I heared about GUID and I kind of understood that its a data type , But I couldn't use it
could you please show me the way to use it ...
by the way , lets say I want something like this :
CREATE TABLE Employees (
ID guid PRIMARY KEY,
Name NVARCHAR(50) NOT NULL
)
How can I do it ?? because I want to benefit from it , but I couldn't find out how to do that
It's not called GUID in SQL Server. It's called uniqueidentifier
The type is called UNIQUEIDENTIFIER as others have pointed out already. But I think you absolutely must read this article before proceeding: GUIDs as PRIMARY KEYs and/or the clustering key
They are called uniqueidentifier
Don't use uniqueidentifier as primary key if clustered (which is the default for PKs)
Seriously: use a standard IDENTITY instead
You can also consider using NEWSEQUENCIALID as the default value for your ID column as it would be faster than using NEWID() generate the GUIDs.
BUT (from the same link above):-
If privacy is a concern, do not use this function. It is possible to guess the value of the next generated GUID and, therefore, access data associated with that GUID.
Practical demo, FWIW
DECLARE #guid1 AS uniqueidentifier
SET #guid1 = NEWID()
SELECT #guid1
The GUID in sql server is known by UNIQUEIDENTIFIER data type. below is the desired code.
CREATE TABLE Employees
(
Id UNIQUEIDENTIFIER PRIMARY KEY,
Name NVARCHAR (50) not null
)
GO
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I create unique constraint that also allows nulls in sql server
I have a table where I need to force a column to have unique values.
This column must be nullable and by business logic multiple NULL values should be permitted, whereas other duplicate values are not.
SQL Server UNIQUE constraint is no good in this situation because it considers NULL as regular values, so it will reject duplicate NULLs.
Currently, value uniqueness is granted by the BLL so I'm not looking for a dirty hack to make it work.
I just would like to know if there is a clean solution to enforce this constraint in the DB.
And yeah, I know I can write a trigger to do that: is a trigger the only solution? (or the best solution anyway?)
If you're using SQL Server 2008 (won't work for earlier version) there is the concept of a filtered index. You can create the index on a filtered subset of the table.
CREATE UNIQUE INDEX indexName ON tableName(columns) INCLUDE includeColumns
WHERE columnName IS NOT NULL
Duplicate of this question?
The calculated column trick is widely known as a "nullbuster"; my notes credit Steve Kass:
CREATE TABLE dupNulls (
pk int identity(1,1) primary key,
X int NULL,
nullbuster as (case when X is null then pk else 0 end),
CONSTRAINT dupNulls_uqX UNIQUE (X,nullbuster)
)
Works on SQL Server 2000. You may need ARITHABORT on e.g.
ALTER DATABASE MyDatabase SET ARITHABORT ON
If you're using SQL Server 2008, have a look into Filtered Indexes to achieve what you want.
For older version of SQL Server, a possible alternative to a trigger involves a computed column:
Create a computed column which uses the value of your "unique" column if it's not NULL, otherwise it uses the value of the row's Primary Key column (or any column which will be unique).
Apply a UNIQUE constraint to the computed column.
http://www.sqlmag.com/article/articleid/98678/sql_server_blog_98678.html
will work only in Microsoft SQL Server 2008
You can create a view in which you select only not null values and create an index on it.
Here is the source - Creating Indexed Views
You should use UNIQUEIDENTIFIER in that column, can be NULL and also is unique by definition.
Hope that helps.