I need to add a specific column if it does not exist. I have something like the following, but it always returns false:
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'myTableName'
AND COLUMN_NAME = 'myColumnName')
How can I check if a column exists in a table of the SQL Server database?
SQL Server 2005 onwards:
IF EXISTS(SELECT 1 FROM sys.columns
WHERE Name = N'columnName'
AND Object_ID = Object_ID(N'schemaName.tableName'))
BEGIN
-- Column Exists
END
Martin Smith's version is shorter:
IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL
BEGIN
-- Column Exists
END
A more concise version
IF COL_LENGTH('table_name','column_name') IS NULL
BEGIN
/* Column does not exist or caller does not have permission to view the object */
END
The point about permissions on viewing metadata applies to all answers, not just this one.
Note that the first parameter table name to COL_LENGTH can be in one, two, or three part name format as required.
An example referencing a table in a different database is:
COL_LENGTH('AdventureWorks2012.HumanResources.Department','ModifiedDate')
One difference with this answer, compared to using the metadata views, is that metadata functions, such as COL_LENGTH, always only return data about committed changes, irrespective of the isolation level in effect.
Tweak the below to suit your specific requirements:
if not exists (select
column_name
from
INFORMATION_SCHEMA.columns
where
table_name = 'MyTable'
and column_name = 'MyColumn')
alter table MyTable add MyColumn int
That should work - take a careful look over your code for stupid mistakes; are you querying INFORMATION_SCHEMA on the same database as your insert is being applied to for example? Do you have a typo in your table/column name in either statement?
Try this...
IF NOT EXISTS(
SELECT TOP 1 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
[TABLE_NAME] = 'Employees'
AND [COLUMN_NAME] = 'EmployeeID')
BEGIN
ALTER TABLE [Employees]
ADD [EmployeeID] INT NULL
END
For the people who are checking the column existence before dropping it.
From SQL Server 2016 you can use new DIE (Drop If Exists) statements instead of big IF wrappers
ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name
I'd prefer INFORMATION_SCHEMA.COLUMNS over a system table because Microsoft does not guarantee to preserve the system tables between versions. For example, dbo.syscolumns does still work in SQL Server 2008, but it's deprecated and could be removed at any time in future.
You can use the information schema system views to find out pretty much anything about the tables you're interested in:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yourTableName'
ORDER BY ORDINAL_POSITION
You can also interrogate views, stored procedures and pretty much anything about the database using the Information_schema views.
Try something like:
CREATE FUNCTION ColumnExists(#TableName varchar(100), #ColumnName varchar(100))
RETURNS varchar(1) AS
BEGIN
DECLARE #Result varchar(1);
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = #TableName AND COLUMN_NAME = #ColumnName)
BEGIN
SET #Result = 'T'
END
ELSE
BEGIN
SET #Result = 'F'
END
RETURN #Result;
END
GO
GRANT EXECUTE ON [ColumnExists] TO [whoever]
GO
Then use it like this:
IF ColumnExists('xxx', 'yyyy') = 'F'
BEGIN
ALTER TABLE xxx
ADD yyyyy varChar(10) NOT NULL
END
GO
It should work on both SQL Server 2000 and SQL Server 2005. I am not sure about SQL Server 2008, but I don't see why not.
First check if the table/column(id/name) combination exists in dbo.syscolumns (an internal SQL Server table that contains field definitions), and if not issue the appropriate ALTER TABLE query to add it. For example:
IF NOT EXISTS ( SELECT *
FROM syscolumns
WHERE id = OBJECT_ID('Client')
AND name = 'Name' )
ALTER TABLE Client
ADD Name VARCHAR(64) NULL
A good friend and colleague of mine showed me how you can also use an IF block with SQL functions OBJECT_ID and COLUMNPROPERTY in SQL Server 2005 and later to check for a column. You can use something similar to the following:
You can see for yourself here:
IF (OBJECT_ID(N'[dbo].[myTable]') IS NOT NULL AND
COLUMNPROPERTY( OBJECT_ID(N'[dbo].[myTable]'), 'ThisColumnDoesNotExist', 'ColumnId') IS NULL)
BEGIN
SELECT 'Column does not exist -- You can add TSQL to add the column here'
END
declare #myColumn as nvarchar(128)
set #myColumn = 'myColumn'
if not exists (
select 1
from information_schema.columns columns
where columns.table_catalog = 'myDatabase'
and columns.table_schema = 'mySchema'
and columns.table_name = 'myTable'
and columns.column_name = #myColumn
)
begin
exec('alter table myDatabase.mySchema.myTable add'
+' ['+#myColumn+'] bigint null')
end
This worked for me in SQL Server 2000:
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'table_name'
AND column_name = 'column_name'
)
BEGIN
...
END
Try this
SELECT COLUMNS.*
FROM INFORMATION_SCHEMA.COLUMNS COLUMNS,
INFORMATION_SCHEMA.TABLES TABLES
WHERE COLUMNS.TABLE_NAME = TABLES.TABLE_NAME
AND Upper(COLUMNS.COLUMN_NAME) = Upper('column_name')
I needed something similar for SQL Server 2000 and, as Mitch points out, this only works in SQL Server 2005 or later.
This is what worked for me in the end:
if exists (
select *
from
sysobjects, syscolumns
where
sysobjects.id = syscolumns.id
and sysobjects.name = 'table'
and syscolumns.name = 'column')
IF NOT EXISTS(SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'TableName'
AND table_schema = 'SchemaName'
AND column_name = 'ColumnName') BEGIN
ALTER TABLE [SchemaName].[TableName] ADD [ColumnName] int(1) NOT NULL default '0';
END;
if exists (
select *
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = '<table_name>'
and COLUMN_NAME = '<column_name>'
) begin
print 'Column you have specified exists'
end else begin
print 'Column does not exist'
end
One of the simplest and understandable solutions is:
IF COL_LENGTH('Table_Name','Column_Name') IS NULL
BEGIN
-- Column Not Exists, implement your logic
END
ELSE
BEGIN
-- Column Exists, implement your logic
END
A temporary table version of the accepted answer:
if (exists(select 1
from tempdb.sys.columns
where Name = 'columnName'
and Object_ID = object_id('tempdb..#tableName')))
begin
...
end
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so
where sc.name like '%col_name%' and so.type='U'
There are several ways to check the existence of a column.
I would strongly recommend to use INFORMATION_SCHEMA.COLUMNS as it is created in order to communicate with user.
Consider following tables:
sys.objects
sys.columns
and even some other access methods available to check system catalog.
Also, no need to use SELECT *, simply test it by NULL value
IF EXISTS(
SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'myTableName'
AND COLUMN_NAME = 'myColumnName'
)
Wheat's answer is good, but it assumes you do not have any identical table name / column name pairs in any schema or database. To make it safe for that condition, use this...
select *
from Information_Schema.Columns
where Table_Catalog = 'DatabaseName'
and Table_Schema = 'SchemaName'
and Table_Name = 'TableName'
and Column_Name = 'ColumnName'
Do something if the column does not exist:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NULL)
BEGIN
// Do something
END
END;
Do something if the column does exist:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
BEGIN
// Do something
END
END;
Here is a simple script I use to manage addition of columns in the database:
IF NOT EXISTS (
SELECT *
FROM sys.Columns
WHERE Name = N'QbId'
AND Object_Id = Object_Id(N'Driver')
)
BEGIN
ALTER TABLE Driver ADD QbId NVARCHAR(20) NULL
END
ELSE
BEGIN
PRINT 'QbId is already added on Driver'
END
In this example, the Name is the ColumnName to be added and Object_Id is the TableName
Another contribution is the following sample that adds the column if it does not exist.
USE [Northwind]
GO
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Categories'
AND COLUMN_NAME = 'Note')
BEGIN
ALTER TABLE Categories ADD Note NVARCHAR(800) NULL
END
GO
The below query can be used to check whether searched column exists or not in the table. We can take a decision based on the searched result, also as shown below.
IF EXISTS (SELECT 'Y' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = <YourTableName> AND COLUMN_NAME = <YourColumnName>)
BEGIN
SELECT 'Column Already Exists.'
END
ELSE
BEGIN
ALTER TABLE <YourTableName> ADD <YourColumnName> <DataType>[Size]
END
Yet another variation...
SELECT
Count(*) AS existFlag
FROM
sys.columns
WHERE
[name] = N 'ColumnName'
AND [object_id] = OBJECT_ID(N 'TableName')
You can check multiple columns in SQLDB at once and return a string as status to check if columns exist:
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Table Name'
AND(COLUMN_NAME = 'column 1'
or COLUMN_NAME = 'column 2'
or COLUMN_NAME = 'column 3'
or COLUMN_NAME = 'column 4')
)
SELECT 'Column exists in table' AS[Status];
ELSE
SELECT 'Column does not exist in table' AS[Status];
Execute the below query to check if the column exists in the given table:
IF(SELECT COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName') IS NOT NULL
PRINT 'Column Exists in the given table';
IF EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_CATALOG = 'Database Name'
and TABLE_SCHEMA = 'Schema Name'
and TABLE_NAME = 'Table Name'
and COLUMN_NAME = 'Column Name'
and DATA_TYPE = 'Column Type') -- Where statement lines can be deleted.
BEGIN
-- Column exists in table
END
ELSE BEGIN
-- Column does not exist in table
END
IF EXISTS(SELECT 1 FROM sys.columns
WHERE Name = N'columnName'
AND Object_ID = Object_ID(N'schemaName.tableName'))
This should be the fairly easier way and straightforward solution to this problem. I have used this multiple times for similar scenarios. It works like a charm, no doubts on that.
Related
Currently I am using:
select *
from sys.tables
where name = 'table name'
But it is taking long time since there are many tables and I have to check each one of them one by one.
You can try using IN like
select * from sys.tables where name IN ('tablename1','tablename2',...)
or you can instead try
SELECT 1
FROM systable INNER JOIN sysuserperm ON systable.creator = sysuserperm.user_id
WHERE sysuserperm.user_name = 'yourusername' AND
systable.table_type = 'BASE' AND
systable.table_name IN ('tablename1', 'tablename2')
GROUP BY sysuserperm.user_name, systable.table_type
Once can use this:
USE DbName
SELECT *
FROM information_schema.tables
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME IN ('tb01','tbl02',...)
If you have a list of table names to check, put it into a table variable and use a code similar to the one below:
declare #t table (
SchemaName sysname not null,
ObjectName sysname not null,
primary key (ObjectName, SchemaName)
);
-- Populate this with your data
insert into #t (SchemaName, ObjectName)
values
(N'dbo', N'SomeTable1'),
(N'dbo', N'AnotherTable2'),
(N'abc', N'DEF');
if exists (
select 0 from #t t
left join INFORMATION_SCHEMA.TABLES xt on xt.TABLE_SCHEMA = t.SchemaName
and xt.TABLE_NAME = t.ObjectName
where xt.TABLE_NAME is null
)
select concat(t.SchemaName, N'.', t.ObjectName) as [MissingObject]
from #t t
left join INFORMATION_SCHEMA.TABLES xt on xt.TABLE_SCHEMA = t.SchemaName
and xt.TABLE_NAME = t.ObjectName
where xt.TABLE_NAME is null;
The aforementioned approach can be easily expanded for multiple kinds of objects. You can replace INFORMATION_SCHEMA.TABLES with sys.all_objects and modify the schema name comparison accordingly.
I am trying to check if a table accessed through openquery exists with the following code but it does not work:
IF EXISTS (SELECT * FROM OPENQUERY(SADATABASE, ' select *
from xx_201509_T '
) )
Try something like this:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[xx_201509_T]') AND type in (N'U'))
***DO WHATEVER HERE***
SELECT OBJECT_ID('xx_201509_T', 'U')
if it's NULL, then the table does not exist
EDIT: so in your openquery use it like this:
IF (SELECT objectID FROM OPENQUERY(SADATABASE, 'SELECT OBJECT_ID(''xx_201509_T'', ''U'') as objectID') ) IS NOT NULL
BEGIN
print 'xx_201509_T TABLE EXISTS'
END
I need to add a specific column if it does not exist. I have something like the following, but it always returns false:
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'myTableName'
AND COLUMN_NAME = 'myColumnName')
How can I check if a column exists in a table of the SQL Server database?
SQL Server 2005 onwards:
IF EXISTS(SELECT 1 FROM sys.columns
WHERE Name = N'columnName'
AND Object_ID = Object_ID(N'schemaName.tableName'))
BEGIN
-- Column Exists
END
Martin Smith's version is shorter:
IF COL_LENGTH('schemaName.tableName', 'columnName') IS NOT NULL
BEGIN
-- Column Exists
END
A more concise version
IF COL_LENGTH('table_name','column_name') IS NULL
BEGIN
/* Column does not exist or caller does not have permission to view the object */
END
The point about permissions on viewing metadata applies to all answers, not just this one.
Note that the first parameter table name to COL_LENGTH can be in one, two, or three part name format as required.
An example referencing a table in a different database is:
COL_LENGTH('AdventureWorks2012.HumanResources.Department','ModifiedDate')
One difference with this answer, compared to using the metadata views, is that metadata functions, such as COL_LENGTH, always only return data about committed changes, irrespective of the isolation level in effect.
Tweak the below to suit your specific requirements:
if not exists (select
column_name
from
INFORMATION_SCHEMA.columns
where
table_name = 'MyTable'
and column_name = 'MyColumn')
alter table MyTable add MyColumn int
That should work - take a careful look over your code for stupid mistakes; are you querying INFORMATION_SCHEMA on the same database as your insert is being applied to for example? Do you have a typo in your table/column name in either statement?
Try this...
IF NOT EXISTS(
SELECT TOP 1 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
[TABLE_NAME] = 'Employees'
AND [COLUMN_NAME] = 'EmployeeID')
BEGIN
ALTER TABLE [Employees]
ADD [EmployeeID] INT NULL
END
For the people who are checking the column existence before dropping it.
From SQL Server 2016 you can use new DIE (Drop If Exists) statements instead of big IF wrappers
ALTER TABLE Table_name DROP COLUMN IF EXISTS Column_name
I'd prefer INFORMATION_SCHEMA.COLUMNS over a system table because Microsoft does not guarantee to preserve the system tables between versions. For example, dbo.syscolumns does still work in SQL Server 2008, but it's deprecated and could be removed at any time in future.
You can use the information schema system views to find out pretty much anything about the tables you're interested in:
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'yourTableName'
ORDER BY ORDINAL_POSITION
You can also interrogate views, stored procedures and pretty much anything about the database using the Information_schema views.
Try something like:
CREATE FUNCTION ColumnExists(#TableName varchar(100), #ColumnName varchar(100))
RETURNS varchar(1) AS
BEGIN
DECLARE #Result varchar(1);
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = #TableName AND COLUMN_NAME = #ColumnName)
BEGIN
SET #Result = 'T'
END
ELSE
BEGIN
SET #Result = 'F'
END
RETURN #Result;
END
GO
GRANT EXECUTE ON [ColumnExists] TO [whoever]
GO
Then use it like this:
IF ColumnExists('xxx', 'yyyy') = 'F'
BEGIN
ALTER TABLE xxx
ADD yyyyy varChar(10) NOT NULL
END
GO
It should work on both SQL Server 2000 and SQL Server 2005. I am not sure about SQL Server 2008, but I don't see why not.
First check if the table/column(id/name) combination exists in dbo.syscolumns (an internal SQL Server table that contains field definitions), and if not issue the appropriate ALTER TABLE query to add it. For example:
IF NOT EXISTS ( SELECT *
FROM syscolumns
WHERE id = OBJECT_ID('Client')
AND name = 'Name' )
ALTER TABLE Client
ADD Name VARCHAR(64) NULL
A good friend and colleague of mine showed me how you can also use an IF block with SQL functions OBJECT_ID and COLUMNPROPERTY in SQL Server 2005 and later to check for a column. You can use something similar to the following:
You can see for yourself here:
IF (OBJECT_ID(N'[dbo].[myTable]') IS NOT NULL AND
COLUMNPROPERTY( OBJECT_ID(N'[dbo].[myTable]'), 'ThisColumnDoesNotExist', 'ColumnId') IS NULL)
BEGIN
SELECT 'Column does not exist -- You can add TSQL to add the column here'
END
declare #myColumn as nvarchar(128)
set #myColumn = 'myColumn'
if not exists (
select 1
from information_schema.columns columns
where columns.table_catalog = 'myDatabase'
and columns.table_schema = 'mySchema'
and columns.table_name = 'myTable'
and columns.column_name = #myColumn
)
begin
exec('alter table myDatabase.mySchema.myTable add'
+' ['+#myColumn+'] bigint null')
end
This worked for me in SQL Server 2000:
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'table_name'
AND column_name = 'column_name'
)
BEGIN
...
END
Try this
SELECT COLUMNS.*
FROM INFORMATION_SCHEMA.COLUMNS COLUMNS,
INFORMATION_SCHEMA.TABLES TABLES
WHERE COLUMNS.TABLE_NAME = TABLES.TABLE_NAME
AND Upper(COLUMNS.COLUMN_NAME) = Upper('column_name')
I needed something similar for SQL Server 2000 and, as Mitch points out, this only works in SQL Server 2005 or later.
This is what worked for me in the end:
if exists (
select *
from
sysobjects, syscolumns
where
sysobjects.id = syscolumns.id
and sysobjects.name = 'table'
and syscolumns.name = 'column')
IF NOT EXISTS(SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'TableName'
AND table_schema = 'SchemaName'
AND column_name = 'ColumnName') BEGIN
ALTER TABLE [SchemaName].[TableName] ADD [ColumnName] int(1) NOT NULL default '0';
END;
if exists (
select *
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = '<table_name>'
and COLUMN_NAME = '<column_name>'
) begin
print 'Column you have specified exists'
end else begin
print 'Column does not exist'
end
One of the simplest and understandable solutions is:
IF COL_LENGTH('Table_Name','Column_Name') IS NULL
BEGIN
-- Column Not Exists, implement your logic
END
ELSE
BEGIN
-- Column Exists, implement your logic
END
A temporary table version of the accepted answer:
if (exists(select 1
from tempdb.sys.columns
where Name = 'columnName'
and Object_ID = object_id('tempdb..#tableName')))
begin
...
end
select distinct object_name(sc.id)
from syscolumns sc,sysobjects so
where sc.name like '%col_name%' and so.type='U'
There are several ways to check the existence of a column.
I would strongly recommend to use INFORMATION_SCHEMA.COLUMNS as it is created in order to communicate with user.
Consider following tables:
sys.objects
sys.columns
and even some other access methods available to check system catalog.
Also, no need to use SELECT *, simply test it by NULL value
IF EXISTS(
SELECT NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'myTableName'
AND COLUMN_NAME = 'myColumnName'
)
Wheat's answer is good, but it assumes you do not have any identical table name / column name pairs in any schema or database. To make it safe for that condition, use this...
select *
from Information_Schema.Columns
where Table_Catalog = 'DatabaseName'
and Table_Schema = 'SchemaName'
and Table_Name = 'TableName'
and Column_Name = 'ColumnName'
Do something if the column does not exist:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NULL)
BEGIN
// Do something
END
END;
Do something if the column does exist:
BEGIN
IF (COL_LENGTH('[dbo].[Table]', 'Column ') IS NOT NULL)
BEGIN
// Do something
END
END;
Here is a simple script I use to manage addition of columns in the database:
IF NOT EXISTS (
SELECT *
FROM sys.Columns
WHERE Name = N'QbId'
AND Object_Id = Object_Id(N'Driver')
)
BEGIN
ALTER TABLE Driver ADD QbId NVARCHAR(20) NULL
END
ELSE
BEGIN
PRINT 'QbId is already added on Driver'
END
In this example, the Name is the ColumnName to be added and Object_Id is the TableName
Another contribution is the following sample that adds the column if it does not exist.
USE [Northwind]
GO
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Categories'
AND COLUMN_NAME = 'Note')
BEGIN
ALTER TABLE Categories ADD Note NVARCHAR(800) NULL
END
GO
The below query can be used to check whether searched column exists or not in the table. We can take a decision based on the searched result, also as shown below.
IF EXISTS (SELECT 'Y' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = <YourTableName> AND COLUMN_NAME = <YourColumnName>)
BEGIN
SELECT 'Column Already Exists.'
END
ELSE
BEGIN
ALTER TABLE <YourTableName> ADD <YourColumnName> <DataType>[Size]
END
Yet another variation...
SELECT
Count(*) AS existFlag
FROM
sys.columns
WHERE
[name] = N 'ColumnName'
AND [object_id] = OBJECT_ID(N 'TableName')
You can check multiple columns in SQLDB at once and return a string as status to check if columns exist:
IF EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Table Name'
AND(COLUMN_NAME = 'column 1'
or COLUMN_NAME = 'column 2'
or COLUMN_NAME = 'column 3'
or COLUMN_NAME = 'column 4')
)
SELECT 'Column exists in table' AS[Status];
ELSE
SELECT 'Column does not exist in table' AS[Status];
Execute the below query to check if the column exists in the given table:
IF(SELECT COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName') IS NOT NULL
PRINT 'Column Exists in the given table';
IF EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_CATALOG = 'Database Name'
and TABLE_SCHEMA = 'Schema Name'
and TABLE_NAME = 'Table Name'
and COLUMN_NAME = 'Column Name'
and DATA_TYPE = 'Column Type') -- Where statement lines can be deleted.
BEGIN
-- Column exists in table
END
ELSE BEGIN
-- Column does not exist in table
END
IF EXISTS(SELECT 1 FROM sys.columns
WHERE Name = N'columnName'
AND Object_ID = Object_ID(N'schemaName.tableName'))
This should be the fairly easier way and straightforward solution to this problem. I have used this multiple times for similar scenarios. It works like a charm, no doubts on that.
I have the following query. can someone help rapping this in a cursor.
IF OBJECT_ID('tempdb.[dbo].[#Results]') IS NOT NULL
DROP TABLE [dbo].[#Results]
GO
CREATE TABLE [dbo].[#Results] (
[DatabaseName] VARCHAR(128) NULL,
[DatabaseVersion] VARCHAR(128) NULL,
[DateChangedOn] DATETIME NULL)
EXEC sp_msForEachDb '
IF EXISTS (SELECT * FROM [?].sys.objects WHERE NAME = ''stdVersions'')
BEGIN
INSERT INTO #Results
SELECT
''?'' AS [DatabaseName],
v.[DatabaseVersion],
l.[DateChangedOn]
FROM [?].dbo.stdVersions v
CROSS JOIN [?].dbo.stdChangeLog l
END'
SELECT * FROM #Results ORDER BY DateChangedOn
the query should return list of all database names in the server and within the databases return the databaseversion column and DateChangeOn Column. All the databases in the server contain tables named stdVersions and stdChangeLog of which the stdVersion table have a single row of DatabaseVersion comes and stdChangeLog table have a single row of DateChangedOn.
Below is an example of creating a cursor on the #Results table.
DECLARE #DatabaseName sysname
, #DatabaseVersion sysname
, #DateChangedOn datetime;
DECLARE DatabaseList CURSOR LOCAL FAST_FORWARD
FOR
SELECT DatabaseName
, DatabaseVersion
, DateChangedOn
FROM #Results
ORDER BY DateChangedOn;
OPEN DatabaseList;
WHILE 1 = 1
BEGIN
FETCH NEXT FROM DatabaseList INTO
#DatabaseName
, #DatabaseVersion
, #DateChangedOn;
IF ##FETCH_STATUS = -1 BREAK;
--process row here
END;
CLOSE DatabaseList;
DEALLOCATE DatabaseList;
You mention that the "std" tables exist in all databases. If these tables does not include system databases, change the IF statement in the script below to exclude those:
IF EXISTS (SELECT * FROM [?].sys.objects WHERE NAME = ''stdVersions'')
AND [?] NOT IN(N'master', N'model', N'tempdb', N'msdb', N'SSISDB')
If I've been told a table (or proc) name, but not which connected database the object is located in, is there any simple script to search for it? Maybe search somewhere in the System Databases? (I'm using SQL Server 2005)
There is a schema called INFORMATION_SCHEMA schema which contains a set of views on tables from the SYS schema that you can query to get what you want.
A major upside of the INFORMATION_SCHEMA is that the object names are very query friendly and user readable. The downside of the INFORMATION_SCHEMA is that you have to write one query for each type of object.
The Sys schema may seem a little cryptic initially, but it has all the same information (and more) in a single spot.
You'd start with a table called SysObjects (each database has one) that has the names of all objects and their types.
One could search in a database as follows:
Select [name] as ObjectName, Type as ObjectType
From Sys.Objects
Where 1=1
and [Name] like '%YourObjectName%'
Now, if you wanted to restrict this to only search for tables and stored procs, you would do
Select [name] as ObjectName, Type as ObjectType
From Sys.Objects
Where 1=1
and [Name] like '%YourObjectName%'
and Type in ('U', 'P')
If you look up object types, you will find a whole list for views, triggers, etc.
Now, if you want to search for this in each database, you will have to iterate through the databases. You can do one of the following:
If you want to search through each database without any clauses, then use the sp_MSforeachdb as shown in an answer here.
If you only want to search specific databases, use the "USE DBName" and then search command.
You will benefit greatly from having it parameterized in that case. Note that the name of the database you are searching in will have to be replaced in each query (DatabaseOne, DatabaseTwo...). Check this out:
Declare #ObjectName VarChar (100)
Set #ObjectName = '%Customer%'
Select 'DatabaseOne' as DatabaseName, [name] as ObjectName, Type as ObjectType
From DatabaseOne.Sys.Objects
Where 1=1
and [Name] like #ObjectName
and Type in ('U', 'P')
UNION ALL
Select 'DatabaseTwo' as DatabaseName, [name] as ObjectName, Type as ObjectType
From DatabaseTwo.Sys.Objects
Where 1=1
and [Name] like #ObjectName
and Type in ('U', 'P')
UNION ALL
Select 'DatabaseThree' as DatabaseName, [name] as ObjectName, Type as ObjectType
From DatabaseThree.Sys.Objects
Where 1=1
and [Name] like #ObjectName
and Type in ('U', 'P')
sp_MSforeachdb 'select db_name(), * From ?..sysobjects where xtype in (''U'', ''P'') And name = ''ObjectName'''
Instead of 'ObjectName' insert object you are looking for. First column will display name of database where object is located at.
Easiest way is to hit up the information_schemas...
SELECT *
FROM information_schema.Tables
WHERE [Table_Name]='????'
SELECT *
FROM information_schema.Views
WHERE [Table_Name]='????'
SELECT *
FROM information_schema.Routines
WHERE [Routine_Name]='????'
You can achieve this by using the following query:
EXEC sp_msforeachdb
'IF EXISTS
(
SELECT 1
FROM [?].sys.objects
WHERE name LIKE ''OBJECT_TO_SEARCH''
)
SELECT
''?'' AS DB,
name AS Name,
type_desc AS Type
FROM [?].sys.objects
WHERE name LIKE ''OBJECT_TO_SEARCH'''
Just replace OBJECT_TO_SEARCH with the actual object name you are interested in (or part of it, surrounded with %).
More details here: https://peevsvilen.blog/2019/07/30/search-for-an-object-in-sql-server/
You can use sp_MSforeachdb to search all databases.
declare #RETURN_VALUE int
declare #command1 nvarchar(2000)
set #command1 = "Your command goes here"
exec #RETURN_VALUE = sp_MSforeachdb #command1 = #command1
Raj
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
/**********************************************************************
Naziv procedure : sp_rfv_FIND
Ime i prezime autora: Srdjan Nadrljanski
Datum kreiranja : 13.06.2013.
Namena : Traži sql objekat na celom serveru
Tabele :
Ulazni parametri :
Izlazni parametri :
Datum zadnje izmene :
Opis izmene :
exec sp_rfv_FIND 'TUN',''
**********************************************************************/
CREATE PROCEDURE [dbo].[sp_rfv_FIND] ( #SEARCHSTRING VARCHAR(255),
#notcontain Varchar(255)
)
AS
declare #text varchar(1500),#textinit varchar (1500)
set #textinit=
'USE #sifra
insert into ##temp2
select ''#sifra''as dbName,a.[Object Name],a.[Object Type]
from(
SELECT DISTINCT sysobjects.name AS [Object Name] ,
case
when sysobjects.xtype = ''C'' then ''CHECK constraint''
when sysobjects.xtype = ''D'' then ''Default or DEFAULT constraint''
when sysobjects.xtype = ''F'' then ''Foreign Key''
when sysobjects.xtype = ''FN'' then ''Scalar function''
when sysobjects.xtype = ''P'' then ''Stored Procedure''
when sysobjects.xtype = ''PK'' then ''PRIMARY KEY constraint''
when sysobjects.xtype = ''S'' then ''System table''
when sysobjects.xtype = ''TF'' then ''Function''
when sysobjects.xtype = ''TR'' then ''Trigger''
when sysobjects.xtype = ''U'' then ''User table''
when sysobjects.xtype = ''UQ'' then ''UNIQUE constraint''
when sysobjects.xtype = ''V'' then ''View''
when sysobjects.xtype = ''X'' then ''Extended stored procedure''
end as [Object Type]
FROM sysobjects
WHERE
sysobjects.type in (''C'',''D'',''F'',''FN'',''P'',''K'',''S'',''TF'',''TR'',''U'',''V'',''X'')
AND sysobjects.category = 0
AND CHARINDEX(''#SEARCHSTRING'',sysobjects.name)>0
AND ((CHARINDEX(''#notcontain'',sysobjects.name)=0 or
CHARINDEX(''#notcontain'',sysobjects.name)<>0))
)a'
set #textinit=replace(#textinit,'#SEARCHSTRING',#SEARCHSTRING)
set #textinit=replace(#textinit,'#notcontain',#notcontain)
SELECT name AS dbName,cast(null as varchar(255)) as ObjectName,cast(null as varchar(255)) as ObjectType
into ##temp1
from master.dbo.sysdatabases order by name
SELECT * INTO ##temp2 FROM ##temp1 WHERE 1 = 0
declare #sifra VARCHAR(255),#suma int,#brojac int
set #suma=(select count(dbName) from ##temp1)
DECLARE c_k CURSOR LOCAL FAST_FORWARD FOR
SELECT dbName FROM ##temp1 ORDER BY dbName DESC
OPEN c_k
FETCH NEXT FROM c_K INTO #sifra
SET #brojac = 1
WHILE (##fetch_status = 0 ) AND (#brojac <= #suma)
BEGIN
set #text=replace(#textinit,'#sifra',#sifra)
exec (#text)
SET #brojac = #brojac +1
DELETE FROM ##temp1 WHERE dbName = #sifra
FETCH NEXT FROM c_k INTO #sifra
END
close c_k
DEALLOCATE c_k
select * from ##temp2
order by dbName,ObjectType
drop table ##temp2
drop table ##temp1
SELECT NAME AS ObjectName
,schema_name(o.schema_id) AS SchemaName, OBJECT_NAME(o.parent_object_id) as TableName
,type
,o.type_desc
FROM sys.objects o
WHERE o.is_ms_shipped = 0
AND o.NAME LIKE '%UniqueID%'
ORDER BY o.NAME
mayby one little change from the top answer, because DB_NAME() returns always content db of execution. so, for me better like below:
sp_MSforeachdb 'select DB_name(db_id(''?'')) as DB, * From ?..sysobjects where xtype in (''U'', ''P'') And name like ''[_]x[_]%'''
In my case I was looking for tables their names started with _x_
Cheers,
Ondrej
----Option 2
SELECT DISTINCT
o.name,
o.xtype
FROM
syscomments c
INNER JOIN
sysobjects o
ON
c.id=o.id
WHERE
c.TEXT LIKE '%TableName%'
order by
o.name desc,
o.xtype desc
select db_name(), * From sysobjects where xtype in ('U', 'P') And name = 'OBJECT_name'
First column will display name of database where object is located at.