Postgres Import from different table - sql

I'm still fairly new to postgres. I have a table named: university_table with fields: name,
nationality, abbreviation, adjective, person.
I found this sql query to insert data from: https://stackoverflow.com/a/21759321/9469766
Snippet of query below.
How can alter the query to insert these values into my university_country table
-- Create and load Nationality Table - English
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Nationality]') AND type in (N'U'))
DROP TABLE [dbo].[Nationality]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-------------------------------------------------------------------
-- TABLE: [dbo].[Nationality]
-- Creation Date: 02/12/2014
-- Created by: Dan Flynn, Sr. DBA
--
-------------------------------------------------------------------
CREATE TABLE [dbo].[Nationality]
(
[NationalityID] [int] IDENTITY(1,1) NOT NULL,
[Country] [nvarchar](50) NULL,
[Abbreviation] [nvarchar](5) NULL,
[Adjective] [nvarchar] (130) NULL,
[Person] [nvarchar] (60) NULL
) ON [PRIMARY]
GO
-------------------------------------------------------------------------------
-- INSERT VALUES
-------------------------------------------------------------------------------
INSERT INTO [dbo].[Nationality](Country, Abbreviation, Adjective, Person )
VALUES ( 'AMERICAN - USA','US','US (used attributively only, as in US aggression but not He is US)','a US citizen' ),
( 'ARGENTINA','AR','Argentinian','an Argentinian' ),
( 'AUSTRALIA','AU','Australian','an Australian' ),
( 'BAHAMAS','BS','Bahamian','a Bahamian' ),
( 'BELGIUM','BE','Belgian','a Belgian' ),
GO
-------------------------------------------------------------------------------
-- ADD CLUSTERED INDEX
-------------------------------------------------------------------------------
CREATE CLUSTERED INDEX [idxNationality] ON [dbo].[Nationality]
(
[NationalityID] ASC,
[Country] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
EXEC sys.sp_addextendedproperty #name=N'TableDiscription', #value=N'CreatedBy: Dan Flynn, Sr. SQL Server DBA
CreationDate: 02/12/2014
Nationality table contains five columns, i.e.:
1. NationalityID, 2. Country, 3. Abbreviation, 4. Adjective, 5. Person
IDs 1 to 34 are alphabetical countries that are statistically the most popular as far as interaction with the United States. IDs 35 to 248 are also alphabetical for the rest of the countries.
' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'TABLE',#level1name=N'Nationality'
GO

To convert T-SQL to be compatible with Postres' SQL dialect you can use the following steps.
Remove all square brackets (they are illegal in SQL identifiers). If you have identifiers that require them use double quotes " but I would highly recommend to avoid quoted identifiers completely (so never use " in SQL)
Remove all GO statements and end the statements with ; (Something that is recommended for SQL Server as well)
Remove the [dbo]. schema prefix if you didn't create one in Postgres (you typically don't)
Remove the ON [Primary] option it's not needed in Postgres (the equivalent would be to define a tablespace, but that's hardly ever needed in Postgres)
There is no IF in SQL (or Postgres), to conditionally drop a table use DROP TABLE IF EXISTS ....
There are no clustered indexes in Postgres, so just make that a regular index and remove all the options that are introduced by the WITH keyword.
Comments on tables are defined through comment on, not by calling a stored procedure
identity(x,y) needs to be replaced with the standard SQL generated always as identity
There is no nvarchar type, just make everything varchar and make sure your database was created with an encoding that can store multi-byte characters (by default it's UTF-8, so that should be fine)
Not required, but: it's highly recommended to use snake_case identifiers, rather than CamelCase in Postgres
Putting that all together the script should be something like this:
DROP TABLE IF EXISTS Nationality CASCADE;
CREATE TABLE nationality
(
Nationality_id int generated always as IDENTITY NOT NULL,
Country varchar(50) NULL,
Abbreviation varchar(5) NULL,
Adjective varchar (130) NULL,
Person varchar (60) NULL
);
INSERT INTO Nationality (Country, Abbreviation, Adjective, Person )
VALUES ( 'AMERICAN - USA','US','US (used attributively only, as in US aggression but not He is US)','a US citizen' ),
( 'ARGENTINA','AR','Argentinian','an Argentinian' ),
( 'AUSTRALIA','AU','Australian','an Australian' ),
( 'BAHAMAS','BS','Bahamian','a Bahamian' ),
( 'BELGIUM','BE','Belgian','a Belgian' );
CREATE INDEX idx_Nationality ON Nationality
(
Nationality_ID ASC,
Country ASC
);
comment on table nationality is 'CreatedBy: Dan Flynn, Sr. SQL Server DBA
CreationDate: 02/12/2014
Nationality table contains five columns, i.e.:
1. NationalityID, 2. Country, 3. Abbreviation, 4. Adjective, 5. Person
IDs 1 to 34 are alphabetical countries that are statistically the most popular as far as interaction with the United States. IDs 35 to 248 are also alphabetical for the rest of the countries.
';
I am a bit surprised that there is no primary key defined. You probably want to add:
alter table nationality
add primary key (nationality_id);

There is an SQL standard, but nobody implements it fully. Some database systems like PostgreSQL are better at sticking to the standard, others like Microsoft SQL Server are not.
The upshot of this is that you cannot take SQL that works on one RDBMS and use it with another one. You will have to translate that to the PostgreSQL dialect.

Related

What is the source column of each column in view

How can I know for each column in view, or procedure the source column
For example,
I have this table:
CREATE TABLE [dbo].[tbl_Address](
[iAddressId] [int] IDENTITY(1,1) NOT NULL,
[nvStreet] [nvarchar](50) NULL,
[iHouseNum] [int] NULL,
[nvEnterance] [nvarchar](10) NULL,
[iFloor] [int] NULL,
[nvNeighberwood] [nvarchar](20) NULL,
[nvCity] [nvarchar](20) NULL,
[nvNote] [nvarchar](50) NULL,
CONSTRAINT [PK_tbl_Address] PRIMARY KEY CLUSTERED
(
[iAddressId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
And this view:
CREATE VIEW ViewALIAS
AS
SELECT a.nvStreet myStreet,a.nvCity manyStreeats FROM tbl_Address a
The required answer:
nameObject | nameColumn | SourceObject | SourceColumn
-----------------------------------------------------
tbl_Address| nvStreet | ViewALIAS | myStreet
tbl_Address| nvCity | ViewALIAS | manyStreeats
I know how to make the columns: nameObject, nameColumn, SourceObject
or the table: nameObject, SourceObject, SourceColumn
But I do not know how to match x and t
I think that you can't get exactly what you want (see explanation below) but you can get an approximation, first you can get all the columns of the view using:
select name, column_id from sys.columns where object_id=object_id('ViewALIAS')
and then you can get the columns referenced by the view using column dependencies, note that this include all the columns used in any part of the query, not only columns in the select list (for example it would list a column used in a WHERE condition):
select dependencies.referenced_entity_name as referenced_name,
entities.referenced_minor_id as column_id, entities.referenced_minor_name as column_name
from sys.sql_expression_dependencies as dependencies
join sys.objects as objects on object_id=referencing_id
join sys.schemas as schemas on schemas.schema_id=objects.schema_id
cross apply sys.dm_sql_referenced_entities(schemas.name+'.'+objects.name,'OBJECT') as entities
where entities.referenced_entity_name=dependencies.referenced_entity_name
and (is_schema_bound_reference=0 or entities.referenced_minor_id=dependencies.referenced_minor_id)
and entities.referenced_minor_id!=0
and referencing_id=object_id('ViewALIAS')
You can't link the two results because as far as I know there is no way in SQL Server of getting the relation between view columns and referenced columns in the object catalog views, I don't know the exact reason but I'm quite sure that the primary cause is that a view column could be almost anything, so it's not always possible match it to a table column, a few examples:
CREATE VIEW ExampleView AS
SELECT ID, -- table column
(Value1+Value2)*Value3 as Total, -- multiple columns
12345 as Value, -- literal value
getdate() as CurrentDate, -- scalar function
dbo.fnMyFunction(Value1,Value2) as ScalarColumn, -- scalar function with parameters
TableFunctionColumn, -- column from a table function (which can be almost anything)
CASE WHEN Value1<10000 THEN Value2
WHEN Value1>20000 THEN Value3
ELSE Value2+Value3 END AS CaseColumn, -- different columns based on another value
(SELECT SUM(OtherValue) FROM OtherTable
WHERE OtherID=ID GROUP BY OtherValue) AS SubqueryColumn -- subquery result
FROM ExampleTable
CROSS APPLY dbo.fnTableFunction(ID)
I think the CASE column is the most representative example because the table columns used by the view column depends on the value of another column which is not used directly for the column value.

Creating a partitioned view in SQL Server 2008 R2 Enterprise

I'm extending some legacy software that splits data up in to multiple schemas by company, for example CP1.ACCOUNTS, CP2.ACCOUNTS, CPN.ACCOUNTS. I'm attempting to create an updatable view of these tables using partitioning, but I'm getting the typical "not updatable because a partitioning column was not found" error. The column I'm trying to partition on is the primary key, and as far as I can tell, isn't any of the things it isn't allowed to be.
So, with table definitions like so:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [CP1].[ACCOUNTS](
[ACCOUNTID] [char](10) NOT NULL,
[LASTNAME] [varchar](60) NOT NULL,
[FIRSTNAME] [varchar](35) NOT NULL,
[MIDDLE] [varchar](26) NULL,
[SUFFIX] [varchar](10) NULL,
[ADDRESS1] [varchar](55) NULL,
[ADDRESS2] [varchar](55) NULL,
[SOME_FLAG] [tinyint] NULL,
CONSTRAINT [ARM_CODE_KEY] PRIMARY KEY CLUSTERED
(
[CODE_] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [CP1].[ACCOUNTS] WITH CHECK ADD CONSTRAINT [CK__ACCOUNTS__CODE___4DD705FF] CHECK ((left([ACCOUNTID],(3))='CP1'))
GO
ALTER TABLE [CP1].[ACCOUNTS] CHECK CONSTRAINT [CK__ACCOUNTS__CODE___4DD705FF]
GO
ALTER TABLE [CP1].[ACCOUNTS] ADD DEFAULT ((0)) FOR [SOME_FLAG]
GO
and the rest of the tables defined exactly as above, following the CP2, CP3, CPN pattern, and the view definition being a simple:
CREATE VIEW [ALL].[ACCOUNTS] AS
SELECT * FROM CP1.ACCOUNTS
UNION ALL
SELECT * FROM CP2.ACCOUNTS
--UNION ALL etc...
Inserts would be like:
INSERT INTO [ALL].[ACCOUNTS]
([ACCOUNTID]
,[LASTNAME]
,[FIRSTNAME]
,[MIDDLE]
,[SUFFIX]
,[ADDRESS1]
,[ADDRESS2]
,[SOME_FLAG])
VALUES
('CP1XYZ0001',
'SMITH',
'JOHN',
'Q',
'',
'123 Fake St',
'Apt 2',
0,
GO
generates an error like:
Msg 4436, level 16, State 12, Line 1
UNION ALL view 'ALL.ACCOUNTS' is not updatable because a partitioning column was not found.
Am I missing something simple? Am I just way out in left field here?
You need a constraint that defines which column is used as a partitioning column. As the error suggests, you don't have one defined. As described in the documentation:
To perform updates on a partitioned view, the partitioning column must
be a part of the primary key of the base table. If a view is not
updatable, you can create an INSTEAD OF trigger on the view that
allows updates. You should design error handling into the trigger to
make sure that no duplicate rows are inserted. For an example of an
INSTEAD OF trigger designed on a view, see Designing INSTEAD OF
Triggers.
In other words, SQL Server needs to be able to figure out which table gets the update.
You might be able to alter the tables to contain a company name column, which is then used as part of the primary key. Something like this might work:
create table . . .
CompanyName as 'CompanyA',
primary key (AccountId, CompanyName)
. . .
The alternative is to use an instead of trigger, as suggested in the documentation.
In case someone comes upon this, you can use a computed column for partitioning, just make sure to make it a persisted computed column.
In this case, the computed column should be left([ACCOUNTID],(3) and the partition constraint would be <computed column> = 'CP1'. Note: using left() in the constraint will cause it to still scan all partitions. The CHECK constraints can only use these operators: BETWEEN, AND, OR, <, <=, >, >=, =.
Also, since the question referenced enterprise edition, you'd get better performance using a partitioned table instead of a partitioned view.

T-SQL How to create tables dynamically in stored procedures?

Code like this, but it's wrong:
CREATE PROC sp_createATable
#name VARCHAR(10),
#properties VARCHAR(500)
AS
CREATE TABLE #name
(
id CHAR(10) PRIMARY KEY,
--...Properties extracted from #properties
);
Could you tell me how to deal with it? It really troubles me.
You are using a table variable i.e. you should declare the table. This is not a temporary table.
You create a temp table like so:
CREATE TABLE #customer
(
Name varchar(32) not null
)
You declare a table variable like so:
DECLARE #Customer TABLE
(
Name varchar(32) not null
)
Notice that a temp table is declared using # and a table variable is declared using a #.
Go read about the difference between table variables and temp tables.
UPDATE:
Based on your comment below you are actually trying to create tables in a stored procedure. For this you would need to use dynamic SQL. Basically dynamic SQL allows you to construct a SQL Statement in the form of a string and then execute it. This is the ONLY way you will be able to create a table in a stored procedure. I am going to show you how and then discuss why this is not generally a good idea.
Now for a simple example (I have not tested this code but it should give you a good indication of how to do it):
CREATE PROCEDURE sproc_BuildTable
#TableName NVARCHAR(128)
,#Column1Name NVARCHAR(32)
,#Column1DataType NVARCHAR(32)
,#Column1Nullable NVARCHAR(32)
AS
DECLARE #SQLString NVARCHAR(MAX)
SET #SQString = 'CREATE TABLE '+#TableName + '( '+#Column1Name+' '+#Column1DataType +' '+#Column1Nullable +') ON PRIMARY '
EXEC (#SQLString)
GO
This stored procedure can be executed like this:
sproc_BuildTable 'Customers','CustomerName','VARCHAR(32)','NOT NULL'
There are some major problems with this type of stored procedure.
Its going to be difficult to cater for complex tables. Imagine the following table structure:
CREATE TABLE [dbo].[Customers] (
[CustomerID] [int] IDENTITY(1,1) NOT NULL,
[CustomerName] [nvarchar](64) NOT NULL,
[CustomerSUrname] [nvarchar](64) NOT NULL,
[CustomerDateOfBirth] [datetime] NOT NULL,
[CustomerApprovedDiscount] [decimal](3, 2) NOT NULL,
[CustomerActive] [bit] NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED
(
[CustomerID] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Customers] ADD CONSTRAINT [DF_Customers_CustomerApprovedDiscount] DEFAULT ((0.00)) FOR [CustomerApprovedDiscount]
GO
This table is a little more complex than the first example, but not a lot. The stored procedure will be much, much more complex to deal with. So while this approach might work for small tables it is quickly going to be unmanageable.
Creating tables require planning. When you create tables they should be placed strategically on different filegroups. This is to ensure that you don't cause disk I/O contention. How will you address scalability if everything is created on the primary file group?
Could you clarify why you need tables to be created dynamically?
UPDATE 2:
Delayed update due to workload. I read your comment about needing to create a table for each shop and I think you should look at doing it like the example I am about to give you.
In this example I make the following assumptions:
It's an e-commerce site that has many shops
A shop can have many items (goods) to sell.
A particular item (good) can be sold at many shops
A shop will charge different prices for different items (goods)
All prices are in $ (USD)
Let say this e-commerce site sells gaming consoles (i.e. Wii, PS3, XBOX360).
Looking at my assumptions I see a classical many-to-many relationship. A shop can sell many items (goods) and items (goods) can be sold at many shops. Let's break this down into tables.
First I would need a shop table to store all the information about the shop.
A simple shop table might look like this:
CREATE TABLE [dbo].[Shop](
[ShopID] [int] IDENTITY(1,1) NOT NULL,
[ShopName] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Shop] PRIMARY KEY CLUSTERED
(
[ShopID] ASC
) WITH (
PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY]
GO
Let's insert three shops into the database to use during our example. The following code will insert three shops:
INSERT INTO Shop
SELECT 'American Games R US'
UNION
SELECT 'Europe Gaming Experience'
UNION
SELECT 'Asian Games Emporium'
If you execute a SELECT * FROM Shop you will probably see the following:
ShopID ShopName
1 American Games R US
2 Asian Games Emporium
3 Europe Gaming Experience
Right, so now let's move onto the Items (goods) table. Since the items/goods are products of various companies I am going to call the table product. You can execute the following code to create a simple Product table.
CREATE TABLE [dbo].[Product](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[ProductDescription] [nvarchar](128) NOT NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
[ProductID] ASC
)WITH (PAD_INDEX = OFF
, STATISTICS_NORECOMPUTE = OFF
, IGNORE_DUP_KEY = OFF
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Let's populate the products table with some products. Execute the following code to insert some products:
INSERT INTO Product
SELECT 'Wii'
UNION
SELECT 'PS3'
UNION
SELECT 'XBOX360'
If you execute SELECT * FROM Product you will probably see the following:
ProductID ProductDescription
1 PS3
2 Wii
3 XBOX360
OK, at this point you have both product and shop information. So how do you bring them together? Well we know we can identify the shop by its ShopID primary key column and we know we can identify a product by its ProductID primary key column. Also, since each shop has a different price for each product we need to store the price the shop charges for the product.
So we have a table that maps the Shop to the product. We will call this table ShopProduct. A simple version of this table might look like this:
CREATE TABLE [dbo].[ShopProduct](
[ShopID] [int] NOT NULL,
[ProductID] [int] NOT NULL,
[Price] [money] NOT NULL,
CONSTRAINT [PK_ShopProduct] PRIMARY KEY CLUSTERED
(
[ShopID] ASC,
[ProductID] ASC
)WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
So let's assume the American Games R Us shop only sells American consoles, the Europe Gaming Experience sells all consoles and the Asian Games Emporium sells only Asian consoles. We would need to map the primary keys from the shop and product tables into the ShopProduct table.
Here is how we are going to do the mapping. In my example the American Games R Us has a ShopID value of 1 (this is the primary key value) and I can see that the XBOX360 has a value of 3 and the shop has listed the XBOX360 for $159.99
By executing the following code you would complete the mapping:
INSERT INTO ShopProduct VALUES(1,3,159.99)
Now we want to add all product to the Europe Gaming Experience shop. In this example we know that the Europe Gaming Experience shop has a ShopID of 3 and since it sells all consoles we will need to insert the ProductID 1, 2 and 3 into the mapping table. Let's assume the prices for the consoles (products) at the Europe Gaming Experience shop are as follows: 1- The PS3 sells for $259.99 , 2- The Wii sells for $159.99 , 3- The XBOX360 sells for $199.99.
To get this mapping done you would need to execute the following code:
INSERT INTO ShopProduct VALUES(3,2,159.99) --This will insert the WII console into the mapping table for the Europe Gaming Experience Shop with a price of 159.99
INSERT INTO ShopProduct VALUES(3,1,259.99) --This will insert the PS3 console into the mapping table for the Europe Gaming Experience Shop with a price of 259.99
INSERT INTO ShopProduct VALUES(3,3,199.99) --This will insert the XBOX360 console into the mapping table for the Europe Gaming Experience Shop with a price of 199.99
At this point you have mapped two shops and their products into the mapping table. OK, so now how do I bring this all together to show a user browsing the website? Let's say you want to show all the product for the European Gaming Experience to a user on a web page – you would need to execute the following query:
SELECT Shop.*
, ShopProduct.*
, Product.*
FROM Shop
INNER JOIN ShopProduct ON Shop.ShopID = ShopProduct.ShopID
INNER JOIN Product ON ShopProduct.ProductID = Product.ProductID
WHERE Shop.ShopID=3
You will probably see the following results:
ShopID ShopName ShopID ProductID Price ProductID ProductDescription
3 Europe Gaming Experience 3 1 259.99 1 PS3
3 Europe Gaming Experience 3 2 159.99 2 Wii
3 Europe Gaming Experience 3 3 199.99 3 XBOX360
Now for one last example, let's assume that your website has a feature which finds the cheapest price for a console. A user asks to find the cheapest prices for XBOX360.
You can execute the following query:
SELECT Shop.*
, ShopProduct.*
, Product.*
FROM Shop
INNER JOIN ShopProduct ON Shop.ShopID = ShopProduct.ShopID
INNER JOIN Product ON ShopProduct.ProductID = Product.ProductID
WHERE Product.ProductID =3 -- You can also use Product.ProductDescription = 'XBOX360'
ORDER BY Price ASC
This query will return a list of all shops which sells the XBOX360 with the cheapest shop first and so on.
You will notice that I have not added the Asian Games shop. As an exercise, add the Asian games shop to the mapping table with the following products:
the Asian Games Emporium sells the Wii games console for $99.99 and the PS3 console for $159.99. If you work through this example you should now understand how to model a many-to-many relationship.
I hope this helps you in your travels with database design.
You will need to build that CREATE TABLE statement from the inputs and then execute it.
A simple example:
declare #cmd nvarchar(1000), #TableName nvarchar(100);
set #TableName = 'NewTable';
set #cmd = 'CREATE TABLE dbo.' + quotename(#TableName, '[') + '(newCol int not null);';
print #cmd;
--exec(#cmd);
First up, you seem to be mixing table variables and tables.
Either way, You can't pass in the table's name like that. You would have to use dynamic TSQL to do that.
If you just want to declare a table variable:
CREATE PROC sp_createATable
#name VARCHAR(10),
#properties VARCHAR(500)
AS
declare #tablename TABLE
(
id CHAR(10) PRIMARY KEY
);
The fact that you want to create a stored procedure to dynamically create tables might suggest your design is wrong.
This is a way to create tables dynamically using T-SQL stored procedures:
declare #cmd nvarchar(1000), #MyTableName nvarchar(100);
set #MyTableName = 'CustomerDetails';
set #cmd = 'CREATE TABLE dbo.' + quotename(#MyTableName, '[') + '(ColumnName1 int not null,ColumnName2 int not null);';
Execute it as:
exec(#cmd);
You can write the below code:-
create procedure spCreateTable
as
begin
create table testtb(Name varchar(20))
end
execute it as:-
exec spCreateTable

Auto increment table column

Using Postgres, I'm trying to use AUTO_INCREMENT to number my primary key automatically in SQL. However, it gives me an error.
CREATE TABLE Staff (
ID INTEGER NOT NULL AUTO_INCREMENT,
Name VARCHAR(40) NOT NULL,
PRIMARY KEY (ID)
);
The error:
********** Error **********
ERROR: syntax error at or near "AUTO_INCREMENT"
SQL state: 42601
Character: 63
Any idea why?
Postgres 10 or later
(serial columns remain unchanged, see below.)
Consider a standard-SQL IDENTITY column. Can be GENERATED BY DEFAULT or (stricter) GENERATED ALWAYS.
Basics in the manual for CREATE TABLE.
Details in this blog entry by its principal author Peter Eisentraut.
Create table with IDENTITY column
CREATE TABLE staff (
staff_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY
, staff text NOT NULL
);
Add IDENTITY column to existing table
Table may or may not be populated with rows.
ALTER TABLE staff ADD COLUMN staff_id int GENERATED ALWAYS AS IDENTITY;
To also make it the PK at the same time (table can't have a PK yet):
ALTER TABLE staff ADD COLUMN staff_id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY;
See:
How to add a PostgreSQL 10 identity column to an existing table with rows?
Replace serial with IDENTITY column
See:
How to change a table ID from serial to identity?
You can override system values or user input in INSERT commands with OVERRIDING {SYSTEM|USER} VALUE.
Postgres 9.6 or older
(Still supported in newer versions, too.)
Use the serial pseudo data type:
CREATE TABLE staff (
staff_id serial PRIMARY KEY,
, staff text NOT NULL
);
It creates and attaches the sequence object automatically and sets the DEFAULT to nextval() from the sequence. It does all you need.
I use legal, lower-case, unquoted identifiers in my examples. Makes your life with Postgres easier.
You do not specify which RDBMS you are using, however, in SQL Server you can use this syntax:
CREATE TABLE [dbo].[Staff]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] VARCHAR(40) NOT NULL,
CONSTRAINT [ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
In the SQL server database you can use Identity(1,1) like this:
CREATE TABLE Staff
(
ID INT IDENTITY(1,1) NOT NULL,
Name VARCHAR(40) NOT NULL,
PRIMARY KEY (ID)
);
PostgreSQL: If you absolutely must have your own auto increment value:
Then use a sequence:
ericlesc_schools=> drop table yar;
DROP TABLE
ericlesc_schools=> drop sequence user_id_seq;
DROP SEQUENCE
ericlesc_schools=> create sequence user_id_seq;
CREATE SEQUENCE
ericlesc_schools=> create table yar(
id int default nextval('user_id_seq'),
foobar varchar);
CREATE TABLE
ericlesc_schools=> insert into yar (foobar) values('hey alex');
INSERT 0 1
ericlesc_schools=> insert into yar (foobar) values('hey what derick');
INSERT 0 1
ericlesc_schools=> insert into yar (foobar) values('I look like a hushpuppy');
INSERT 0 1
ericlesc_schools=> select * from yar;
id | foobar
----+-----------------
1 | hey alex
2 | hey what derick
3 | I look like a hushpuppy
(3 rows)

SQL Server 2008 Unique Column that is Case Sensitive

Is there a way to make a column both UNIQUE and Case Sensitive?
I want to be able to put
abcde
and
ABCDE
in a unique column.
The uniqueness can be enforced with a unique constraint.
Whether or not the unique index is case-sensitive is defined by the server's (or the table's) collation.
You can get the current collation of your database with this query:
SELECT DATABASEPROPERTYEX('AdventureWorks', 'Collation') SQLCollation;
and you should get something like:
SQLCollation
————————————
SQL_Latin1_General_CP1_CI_AS
Here, the "CI_AS" at the end of the collation means: CI = Case Insensitive, AS = Accent sensitive.
This can be changed to whatever you need it to be. If your database and/or table does have a case-sensitive collation, I would expect that the uniqueness of your index will be case-sensitive as well, e.g. your abcdef and ABCDEF should be both acceptable as unique strings.
Marc
UPDATE:
I just tried this (SQL Server 2008 Developer Edition x64) - works for me (my database is generally using the "Latin1_General_CI_AS collation, but I can define a different one per table / per VARCHAR column even):
CREATE TABLE TestUnique
(string VARCHAR(50) COLLATE SQL_Latin1_General_Cp1_CS_AS)
CREATE UNIQUE INDEX UIX_Test ON dbo.TestUnique(string)
INSERT INTO dbo.TestUnique(string) VALUES ('abc')
INSERT INTO dbo.TestUnique(string) VALUES ('ABC')
SELECT * FROM dbo.TestUnique
and I get back:
string
ABC
abc
and no error about the unique index being violated.
In case some one needs to do it on an existing table which already has a unique key/index defined on a varchar/nvarchar column, here is the script.
ALTER TABLE [YourTable] DROP CONSTRAINT [UIX_YourUniqueIndex]
GO
ALTER TABLE [YourTable] ALTER COLUMN [YourColumn] [nvarchar](50) COLLATE Latin1_General_CS_AS NOT NULL;
GO
ALTER TABLE [YourTable] ADD CONSTRAINT [UIX_YourUniqueIndex] UNIQUE NONCLUSTERED
(
[YourColumn] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
I needed to import data from a case sensitive database. When I tried to put the primary key on the column that is the primary key on the source I couldn't do it because of duplicate keys. I changed the collation for the column (varchar) to case sensitive (Right click on the table, choose Design, highlight the column you want to change and click on the elipsis in Collation) and now it works fine. (SQL Server 2008 R2 64 bit).
Thanks #Devraj Gadhavi for the step by step as this is exactly what I needed to do as well. I was about to make those scripts but then (using SSMS 2008R2), I achieved the same in a more lazy :-) way. In the tree view I located my table and column and then right clicked on the column I wanted to change the collation on and chose 'Modify'. In the displayed window, I changed the collation in the properties to the case sensitive one, then anywhere in the open space at the top section of the window (where the columns are listed in table form) I right clicked and chose "Generate Change Script..."