ERROR: column "EP_TEXT" specified more than once - sql

I try to use script to add column to table, no matter i change to which name, it always return error saying
Column names in each table must be unique. Column name 'xxx' in table
'TEST_TABLE' is specified more than once.
I randomly key in a name, it still saying that name is specified more than once. but actually not, there is no such column existed yet, and column finally is not added successfully also.
anyone had any idea?
thanks
below is my query:
GO
if not exists(SELECT * FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'TEST_TABLE' AND COLUMN_NAME = 'EP_TEXT')
begin
ALTER TABLE TEST_TABLE ADD EP_TEXT [dbo].[UDDT_MAXVARCHAR] NULL
end
GO

The problem is that INFORMATION_SCHEMA.TABLE does not have a COLUMN_NAME column. Try this:
IF NOT EXISTS(
SELECT * from INFORMATION_SCHEMA.TABLES t1
INNER JOIN INFORMATION_SCHEMA.COLUMNS t2 on t1.TABLE_NAME = t2.TABLE_NAME
where t1.TABLE_NAME = 'TEST_TABLE' and t2.COLUMN_NAME = 'EP_TEXT'
)

Related

Alter then update causes an error

I have simple script:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
UPDATE Table T1
SET C1 = 1
END
GO
I am getting error
Incorrect syntax near the keyword 'Table'.
I tried this solution but it didn't update column value. I came accross this but I think this is not my case as I don't want to catch exceptions or do any transaction. Do I have easy option to do this?
Putting GO seperator didn't help too.
As Joe Taras pointed out, I have changed my script but now getting error
Invalid column name 'C1'.
You need to ensure that that UPDATE isn't compiled until after you're actually created the column.
Put it in a separate context by using EXEC:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
EXEC('UPDATE Table T1
SET C1 = 1')
END
GO
Your row:
UPDATE Table T1 SET C1 = 1
has wrong because you have specified table keyword.
The correct syntax is:
UPDATE T1 SET C1 = 1
EDIT 1
Rewrite your script as follow, so after GO separator you'll update your field, so you are sure the DDL has taken by DBMS:
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
where table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
END
GO
UPDATE T1 SET C1 = 1
EDIT 2
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.Columns
where table_name = 'T1' AND column_name = 'C1')
BEGIN
ALTER Table T1
ADD C1 BIT NOT NULL CONSTRAINT DF_T1_C1 DEFAULT 0
EXEC('UPDATE T1 SET C1 = 1')
END
GO
if there is no entry in the table update cannot be done
try it after giving asingle entry it works

Drop indexes or alter

I am trying to drop pk constraint and drop index on the target table in informatica, these below statements are working first time successfully.
IF EXISTS (SELECT Name FROM sysindexes WHERE Name = 'xyz')
DROP INDEX [xyz] ON [dbo].[Table_Name];
IF EXISTS (SELECT Name FROM sysindexes WHERE Name = 'xyz')
ALTER TABLE [dbo].[Table_Name] DROP CONSTRAINT [xyz];
But if I run the same query a second time it is giving an error:
Cannot drop the index 'dbo.Table_Name.xyz', because it does not exist or you do not have permission
I need an If ... Else statement syntax like if exists drop else end or success something.
The likely cause for this is that you might have more than one index named xyz on your database. Your IF EXISTS SELECT statement is not taking into consideration which table xyz is on.
You can check for this condition yourself by running the select statement by itself.
Try changing your query to the following to limit the scope:
If Exists
(
Select *
From sys.indexes
Where name = 'xyz'
And Object_Id = Object_Id('dbo.Table_Name')
)
Drop Index xyz On dbo.Table_Name;
One way to get around this issue is to trick the parser:
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE SCHEMA_NAME = 'dbo' AND TABLE_NAME = 'Table_Name' AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND CONSTRAINT_NAME = 'xyz')
BEGIN
EXEC('ALTER TABLE [dbo].[Table_Name] DROP CONSTRAINT [xyz]')
END

How do I add/remove columns using SQL Server 2012 Management Studio

When I execute
exec sp_columns TABLE_NAME
it returns many columns, I need to display specific columns only and add a description column as well.
Is there anyway for me to customize the table to do this?
I am using SQL Server 2012 Management Studio
With SSMS you can use the table designer to add columns fairly easily. In the server browser, find your table, right click, and "Design."
--Check if column does not exists, if yes than add.
IF NOT EXISTS (
SELECT *
FROM sys.columns
WHERE [name] = N'Column_Name'
AND [object_id] = OBJECT_ID(N'Table_Name')
)
BEGIN
ALTER TABLE Table_Name ADD Column_Name Type;
END
-- Similarly for removing column
--Check if column does exists, if yes than add.
IF EXISTS (
SELECT *
FROM sys.columns
WHERE [name] = N'Column_Name'
AND [object_id] = OBJECT_ID(N'Table_Name')
)
BEGIN
ALTER TABLE Table_Name Remove Column_Name;
END
GO
select column_name, table_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME like '%table name%' and column_name
in
(
'column1',
'column2'
)

SQL query for finding all tables ROWS with two columns in them

I have a DataBase with around +100 tables, like half of tables have column A & column B.
My question is, Can I query all tables that have this columns with a specific values e.g.
SELECT * FROM DATABASE
WHERE
EACHTABLE HAS COLUMN A = 21 //only if table has columns and then values
AND
COLUMN B = 13
I am not sure how exact I will do it, nothing is coming up on google either
You can use the undocumented MS stored procedure sp_MSforeachtable, if you fancy living life recklessly:
create table T1 (
ColumnA int not null,
ColumnB int not null
)
go
create table T2 (
ColumnA int not null,
Column2 int not null
)
go
create table T3 (
Column1 int not null,
ColumnB int not null
)
go
create table T4 (
ColumnA int not null,
ColumnB int not null
)
go
insert into T1 values (1,2);
insert into T2 values (3,4);
insert into T3 values (5,6);
insert into T4 values (7,8);
go
create table #Results (TableName sysname,ColumnA int,ColumnB int)
exec sp_MSforeachtable 'insert into #Results select ''?'',ColumnA,ColumnB from ?',
#whereand = ' and syso.object_id in (select object_id from sys.columns where name=''ColumnA'') and syso.object_id in (select object_id from sys.columns where name=''ColumnB'')'
select * from #Results
drop table #Results
Result:
TableName ColumnA ColumnB
------------------------------------- ----------- -----------
[dbo].[T1] 1 2
[dbo].[T4] 7 8
By default, sp_MSforeachtable will, as its name implies, perform the same task for each table in the database. However, one optional parameter to this procedure, called #Whereand, can be used to modify the WHERE clause of the internal query that enumerates the tables in the database. It helps to know that this internal query has already established two aliases to some of the system views. o is an alias for sysobjects (the legacy system view). syso is an alias for sys.all_objects (a more modern system view).
Once sp_MSforeachtable has decided which tables to run against, it will execute the query given to it as its first parameter. But, it will replace ? with the schema and table name (? is the default replacement character. This can be changed as needed)
In this case, I chose to create a temp table, then have each selected table store its results into this temp table, and after sp_MSforeachtable has finished running, to select the combined results out with no further processing.
There is a similar (and similarly undocumented) procedure called sp_MSforeachdb which will access each user database on the server. These can even be combined (although you have to be careful with doubling up ' quote characters twice, at times). However, there's no equivalent sp_MSforeachcolumn.
Try this:
select t.name from sys.objects t inner join sys.columns c
on t.name=OBJECT_NAME(c.object_id)
where t.type='U'
and c.name in('col1','col2')
group by t.name
having COUNT(*) = 2
order by 1
Then you just loop through all the tables and fine the values for these columns.
Like
Declare #out TABLE(tblname varchar(100))
if exists(select * from tbl1 where col1='21' and col2='22')
BEGIN
INSERT INTO #out
select tbl1
END
You can try like this using dynamic query.
select 'select * from '+table_name+ ' where'+column_name+'=21'
from information_schema.columns where column_name = 'A'
I suggest to use two steps:
First, find out all tables in your database that have these two columns and use it for a temporal derived table. For I am not an expert in SQL-Server 2008 I recommend to have a look at the whitepages.
The expression might look like this:
SELECT tablename
FROM information_schema.tables sdbt
WHERE "column a" IN
(SELECT columns
FROM information_schema.columns col
WHERE col.tablename = sdbt.tablename)
Second, use a expresssion to filter the results according to your demanded values.
This command should do the trick in one go, only for column A, amend accordingly to include any other columns you need:
exec sp_MSforeachtable
#command1=N'SELECT * FROM ? WHERE A = 21',
#whereand=' and o.name IN (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME = ''A'') '

How to identify whether the table has identity column

I want to find out whether the table has an identity column or not. Table is unknown to me. I have not done the structure of the table. Using Query?
I am using Sql Server Compact Edition.
IF (OBJECTPROPERTY(OBJECT_ID('TABLE_NAME'), 'TableHasIdentity') = 1)
ObjectProperty is available starting sql server 2008 Reference:
OBJECTPROPERTY
This query returns a table's identity column name:
CREATE PROCEDURE dbo.usp_GetIdentity
#schemaname nvarchar(128) = 'dbo'
,#tablename nvarchar(128)
AS
BEGIN
SELECT OBJECT_NAME(OBJECT_ID) AS TABLENAME,
NAME AS COLUMNNAME,
SEED_VALUE,
INCREMENT_VALUE,
LAST_VALUE,
IS_NOT_FOR_REPLICATION
FROM SYS.IDENTITY_COLUMNS
WHERE OBJECT_NAME(OBJECT_ID) = #tablename
AND OBJECT_SCHEMA_NAME(object_id) = #schemaname
END
Then form the code side.
Call this stored procedure using the datareader role, then check datareader.hasrows(). If the condition value is true (1), then the table has identity column if set. If not then it doesn't have an identity column.
I know it's long time ago but i found this helpful
try this :
IF EXISTS (SELECT * from syscolumns where id = Object_ID(#TABLE_NAME) and colstat & 1 = 1)
BEGIN
-- Do your things
END
Any of the below queries can be used to check if an Identity Column is present in the table
1)
SELECT *
FROM sys.identity_columns
WHERE OBJECT_NAME(object_id) = 'TableName'
2)
SELECT *
FROM sys.identity_columns
WHERE object_id = (
SELECT id
FROM sysobjects
WHERE name = 'TableName'
)
I would just like to add this option as well as I think it is the simplest
SELECT COLUMNPROPERTY(OBJECT_ID('TableName'),'ColumnName','isidentity')
One way to do this would be to make use of the stored procedure sp_help. I.e:
sp_help MyTable
This will return a DataSet that has all the information you would need on the table. There is a specific Table that has information on identities.
I.e:
If it does not contain an identity field, the Identity column will say: "No identity column defined".
#Pranay: he said Compact Edition. Stored procedures aren't supported, and there is no sys.anything.
This is the call:
SELECT Count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE AUTOINC_INCREMENT IS NOT NULL AND TABLE_NAME='this_table'
It will return either 1 (true) or 0 (false).
...
declare #tblhasIdentCol bit = IF (IDENT_CURRENT( #dbName +'.'+ #schemaName +'.'+ #tableName ) IS NOT NULL , 1 , 0 )
You get numeric value if table has identity
Very simple answer would be to run this:
SELECT IDENT_CURRENT('TABLE-NAME')
This would give max value of identity column if exists, if the column doesn't exist, it gives 1 as result.
Based on max value, you can identify which column is having that and determine the identity column.
This the query that get u all the tableNames, columnnames of the table, and is_identity or not in the selected database
SELECT
sys.columns.name
, sys.tables.name
, is_identity
FROM sys.columns
INNER JOIN sys.tables ON sys.tables.object_id = sys.columns.object_id
AND sys.columns.is_identity = 1
CREATE FUNCTION dbo.fnTableHasIdentity(#Tbl sysname)
RETURNS TINYINT
BEGIN
RETURN OBJECTPROPERTY(OBJECT_ID(#Tbl), 'TableHasIdentity')
END
--As simple as that!
select t.name as TableName,c.name as ColumnName
from sys.identity_columns c
inner join sys.tables t on c.object_id = t.object_id
where t.name = 'TableName'
If you like me, needed to be able to do this for tables in an arbitrary database, then I found the following solution:
IF EXISTS (
SELECT 1
FROM [database name].sys.identity_columns AS id_col
INNER JOIN [database name].sys.objects
ON objects.object_id = id_col.object_id
INNER JOIN [database name].sys.schemas
ON schemas.schema_id = objects.schema_id
AND schemas.name = 'schema name'
WHERE OBJECT_NAME(id_col.object_id, DB_ID('database name')) = 'table name'
) SELECT 1 ELSE SELECT 0
you can get the 1 or 0 Boolean Form if the current table has identity Columns by using this
SELECT Count(Column_ID) FROM sys.identity_columns WHERE OBJECT_NAME(object_id) = 'tableName'
One way to list all Tables with their identity column if it exists
to get you desired table add at the end of the filter "and o.name='TableName'"
where Tbale Nam is the table you are looking for
SELECT o.[Name][TableName],i.[name][IdentityColName] FROM
sys.objects o
left outer join sys.identity_columns i on i.object_id=o.object_id
where o.type='U'